如何根据授权标头值授权请求?

时间:2019-05-04 23:50:35

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

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

在ASP.NET MVC5中,我可以通过从AuthorizationFilterAttribute继承并覆盖check方法来做到这一点,就像这样:

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使用了完全不同的授权系统,该系统似乎需要更多的代码,并且该设置似乎不打算与标头检查一起使用。在这种情况下,整个政策体系似乎过于复杂。那是我应该在这种情况下使用的吗?还是有一些内置的替代方法来检查基本身份验证?

谢谢!

1 个答案:

答案 0 :(得分:0)

您无需添加标头作为声明,可以通过将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();