【问题标题】:Asp net core MVC Authorization with Active Directory使用 Active Directory 的 Asp net core MVC 授权
【发布时间】:2018-04-16 13:37:46
【问题描述】:

在一个 Asp net core MVC 应用程序中,我使用 Active Directory 进行自动登录,如下所示:

this.user = UserPrincipal.FindByIdentity(this.context, Environment.UserName);

我得到了用户组:

public List<String> GetUserGroups()
{
   List<String> groups = new List<String>();
   foreach(GroupPrincipal gr in user.GetGroups())
   {
      groups.Add(gr.Name);
   }
   return groups;
}

我想对这些组实施 Autorisation,类似这样:

[Authorize(Roles ="Admin")]
public IActionResult OnlyAdmin(){}

使用将 AD 组与授权角色联系起来的东西,或者如果可能的话直接检查 AD 组的授权,但我不知道如何做这样的事情。

注意:我没有任何登录/注销页面,它只是自动的。

编辑

不知道确切的原因或方式,但它最终可以在没有任何代码的情况下工作,并且只有用户登录 PC 而不是this.user 中指定的用户,但这样就可以了。

但是现在当我尝试访问被拒绝的页面时出现 404 错误,为什么不是 401 或 403 错误?如何将拒绝访问重定向到自定义错误页面?

【问题讨论】:

    标签: active-directory asp.net-core-mvc roles active-directory-group asp.net-authorization


    【解决方案1】:

    您需要在 ClaimsPrincipal 类中添加组,即

    var claims = new List<Claim>();
    claims.Add(new Claim(ClaimTypes.Name, username));
    foreach (string userGroup in authResponse)
    {
        claims.Add(new Claim(ClaimTypes.Role, userGroup, ClaimValueTypes.String,"system","system"));
    }
    
    var principal = new ClaimsPrincipal(new ClaimsIdentity(claims, "authenticationScheme"));
    

    现在在控制器或动作上使用授权属性:

    [Authorize(Roles = "guest,home")]
    

    【讨论】:

    • 谢谢,它工作得很好。但是当我尝试在没有所需访问权限的情况下访问页面时,我收到一个错误,知道如何将此错误重定向到正确的“您无权访问此”页面吗?
    • 如果您不需要任何访问权限,只需将控制器/操作标记为匿名即可。
    【解决方案2】:

    您可以按如下方式编写 ErrorHandlingMiddleware。您需要在启动文件中注册它

    app.UseMiddleware(typeof(ErrorHandlingMiddleware));
    

    以下是相同的示例。 公共类 ErrorHandlingMiddleware { 私有只读 RequestDelegate _next; 私有只读 ILogger _logger;

        public ErrorHandlingMiddleware(RequestDelegate next, ILogger<ErrorHandlingMiddleware> createLogger)
        {
            this._next = next;
            this._logger = createLogger;
        }
    
        public async Task Invoke(HttpContext context)
        {
            var statusCode = HttpStatusCode.OK;
    
            try
            {
                await _next.Invoke(context);
            }
            catch (Exception ex)
            {
                this._logger.LogError(ex, ex.Message);
                switch (context.Response.StatusCode)
                {
                    case (int)HttpStatusCode.NotFound:
                        statusCode = HttpStatusCode.NotFound;
                        break;
                    case (int)HttpStatusCode.Forbidden:
                        statusCode = HttpStatusCode.Forbidden;
                        break;
                    case (int)HttpStatusCode.BadRequest:
                        statusCode = HttpStatusCode.BadRequest;
                        break;
                    default:
                        statusCode = HttpStatusCode.InternalServerError;
                        break;
                }
    
                context.Response.StatusCode = (int)statusCode;
            }
    
            if (!context.Response.HasStarted)
            {
                context.Response.ContentType = "application/json";
    
                var response = new { code = statusCode };
    
                var json = JsonConvert.SerializeObject(response);
    
                await context.Response.WriteAsync(json);
            }
        }
    }
    

    【讨论】:

    • 在尝试之后,我最终只使用此代码app.UseStatusCodePagesWithReExecute("/Home/Error", "?statusCode={0}"); 在我的控制器中进行简单的异常处理:public IActionResult Error(int? statusCode = null) { if (statusCode.HasValue) { if (statusCode == 404 || statusCode == 500) { var viewName = statusCode.ToString(); return View(viewName); } } return View( } 但是我得到一个 404 错误而不是 403 或 401 错误知道吗?
    • 最后我记得这是 .net 核心中的一个已知问题,即无法使用 UseStatusCodePagesWithReExecute() 处理 401。建议是使用自定义中间件。
    猜你喜欢
    • 2011-05-19
    • 1970-01-01
    • 2017-10-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-08-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多