Asp 使用 Active Directory 的网络核心 MVC 授权

Asp net core MVC Authorization with Active Directory

在 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(){}

使用 link 具有授权角色的 AD 组,或者如果可能的话直接检查 AD 组的授权,但我不知道如何做这样的事情。

注意:我没有任何 login/logout 页,它只是自动的。

编辑

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

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

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

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")]

你可以写一个ErrorHandlingMiddleware,如下所示。您需要在启动文件中注册它

app.UseMiddleware(typeof(ErrorHandlingMiddleware));

以下是相同的示例。 public class 错误处理中间件 { 私人只读 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);
        }
    }
}