【问题标题】:How do I authorize requests based on the Authorization header value?如何根据 Authorization 标头值授权请求?
【发布时间】:2019-05-04 23:50:35
【问题描述】:

我正在尝试使用 ASP.NET Core 提供一个简单的 API,并且我想根据请求的授权标头限制对某些端点的访问。

在 ASP.NET MVC5 中,我可以通过继承 AuthorizationFilterAttribute 并覆盖检查方法来做到这一点,如下所示:

public class BasicAuthorizationAttribute : AuthorizationFilterAttribute
{
    public override void OnAuthorization(HttpActionContext actionContext)
    {
        try
        {
            if (actionContext.Request.Headers.Authorization == null)
            {
                actionContext.Response = actionContext.Response = actionContext.Request.CreateResponse(HttpStatusCode.Unauthorized);
                return;
            }

            var authorizationToken = Encoding.UTF8.GetString(Convert.FromBase64String(actionContext.Request.Headers.Authorization.Parameter)).Split(':');
            var username = authorizationToken[0];
            var password = authorizationToken[1];
            if (SecurityHelper.Login(username, password))
            {
                Thread.CurrentPrincipal = new GenericPrincipal(new GenericIdentity(username), null);
                actionContext.RequestContext.Principal = Thread.CurrentPrincipal;
            }
            else
            {
                actionContext.Response = actionContext.Request.CreateResponse(HttpStatusCode.Unauthorized);
                return;
            }
        } catch
        {
            actionContext.Response = actionContext.Request.CreateResponse(HttpStatusCode.Unauthorized);
            return;
        }
    }
}

但从表面上看,Core 使用了一个完全不同的授权系统,这似乎需要更多的代码,而且该设置似乎并不适合与标头检查一起使用。对于这种情况,整个策略系统似乎过于复杂。那是我应该在这种情况下使用的吗?还是有一些内置的替代方法来检查基本身份验证?

谢谢!

【问题讨论】:

  • 您是否尝试过实现AuthorizationHandler,您可以在其中通过AuthorizationHandlerContext 访问所有相关信息?
  • 政策似乎相当复杂。如何将 auth 标头转换为声明,以便之后可以在 HandleRequirementAsync 方法中检查它?我需要为此使用声明吗?

标签: c# .net asp.net-core authorization


【解决方案1】:

您无需将标头添加为声明,您可以通过将IHttpContextAccessor 的实例注入您的AuthorizationHandler 来访问授权标头:

public class MinimumAgeHandler : AuthorizationHandler<MinimumAgeRequirement>
{
    IHttpContextAccessor _httpContextAccessor = null;
    public MinimumAgeHandler(IHttpContextAccessor httpContextAccessor)
    {
        _httpContextAccessor = httpContextAccessor;
    }
    protected override Task HandleRequirementAsync(AuthorizationHandlerContext context,
                                                    MinimumAgeRequirement requirement)
    {

        HttpContext httpContext = _httpContextAccessor.HttpContext;

        string authHeader = httpContext.Request.Headers["Authorization"];
        if (authHeader != null && authHeader.StartsWith("Basic "))
        {
            // Get the encoded username and password
            var encodedUsernamePassword = authHeader.Split(' ', 2, StringSplitOptions.RemoveEmptyEntries)[1]?.Trim();
            // Decode from Base64 to string
            var decodedUsernamePassword = Encoding.UTF8.GetString(Convert.FromBase64String(encodedUsernamePassword));
            // Split username and password
            var username = decodedUsernamePassword.Split(':', 2)[0];
            var password = decodedUsernamePassword.Split(':', 2)[1];
            // Check if login is correct

        }

        ........

        if (.....)
        {
            context.Succeed(requirement);
        }

        //TODO: Use the following if targeting a version of
        //.NET Framework older than 4.6:
        //      return Task.FromResult(0);
        return Task.CompletedTask;
    }
}

您可能需要在 DI 设置中进行注册,如下所示:

services.AddHttpContextAccessor();

【讨论】:

    【解决方案2】:

    不需要在构造函数中注入 IHttpContextAccessor。

    您可以通过以下方式访问 HttpContext

    if (context.Resource is HttpContext httpContext)
    {
        ...
    }
    

    或用于 MVC

    // Requires the following import:
    //     using Microsoft.AspNetCore.Mvc.Filters;
    if (context.Resource is AuthorizationFilterContext mvcContext)
    {
        // Examine MVC-specific things like routing data.
    }
    

    来源: https://docs.microsoft.com/en-us/aspnet/core/security/authorization/policies?view=aspnetcore-6.0#access-mvc-request-context-in-handlers

    【讨论】:

      猜你喜欢
      • 2020-02-05
      • 2019-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-04-30
      • 1970-01-01
      • 2015-06-30
      • 1970-01-01
      • 2019-08-07
      相关资源
      最近更新 更多