【问题标题】:Custom Policy for Authorization自定义授权策略
【发布时间】:2019-04-26 11:12:48
【问题描述】:

我正在处理要求,其中我检查了我们的请求标头是否包含授权标头,并基于该标头调用另一个服务器并返回 403。目前我通过创建自定义 ActionAttribute 来完成它,如下所示:

 public class ValidateAuthHeaderAttribute: ActionFilterAttribute
{
    private readonly ILogger<ValidateAuthHeaderAttribute> _logger;
    public ValidateAuthHeaderAttribute(ILogger<ValidateAuthHeaderAttribute> logger)
    {
        _logger = logger;
    }
    public override void OnActionExecuting(ActionExecutingContext context)
    {
        var httpContext = context.HttpContext;

        if (httpContext.Request.Headers.ContainsKey("Authorization"))
        {
            return;
        }
        var failureResponse = new FailureResponseModel
        {
            Result = false,
            ResultDetails = "Authorization header not present in request",
            Uri = httpContext.Request.Path.ToUriComponent(),
            Timestamp = DateTime.Now.ToString("s", CultureInfo.InvariantCulture),
            Error = new Error
            {
                Code = 108,
                Description = "Authorization header not present in request",
                Resolve = "Send Request with authorization header to avoid this error."
            }
        };

        var responseString = JsonConvert.SerializeObject(failureResponse);

        context.Result = new ContentResult
        {
            Content = responseString,
            ContentType = "application/json",
            StatusCode = 403
        };
    }
}

我正在像这样在我的控制器/方法中使用这个自定义属性。

[TypeFilter(typeof(ValidateAuthHeaderAttribute))]

现在一切正常,但我正在阅读 .Net Core doc 中的基于策略的授权。因此,现在建议使用策略。我在想可以将我的代码移植到自定义策略。

【问题讨论】:

  • 这看起来像是我之前回答的question 的扩展。由于您的场景非常简单,并且您没有任何身份验证/授权集成,因此 ActionFilter 就足够了。
  • 我会尝试更新我之前上传到 GitHub 的代码以方便解决。
  • 在我继续更新代码之前,在我看来,自定义授权策略的实施对于您的场景来说是多余的。事实是,当您进行授权时,[Authorize] 过滤器将自动检查您的 AuthHeader。您可以执行类似 [Authorize(Policy = "MyPolicy")] 的操作,但它仍会检查 AuthHeader 是否存在。如果是 Bearer 令牌,它携带的所有声明都将添加到 HttpContext.User.Claims 的 Claims 属性中。然后您可以使用该策略来验证用户是否有特定的声明或用户是否经过身份验证等
  • 由于您需要使用 Authorization 标头来使用HttpClient 进行后续课程,我认为在这种情况下使用授权策略不会对您有所帮助。添加了授权策略以允许更多自定义类型的授权,而不仅仅是基于角色的授权

标签: c# asp.net-core


【解决方案1】:

IMO,我建议您继续使用ValidateAuthHeaderAttribute,这样更容易。

如果您坚持政策,请按照以下步骤操作:

  1. 要求

    public class AuthorizationHeaderRequirement: IAuthorizationRequirement
    {
    }
    public class AuthorizationHeaderHandler : AuthorizationHandler<AuthorizationHeaderRequirement>
    {
        protected override async Task HandleRequirementAsync(AuthorizationHandlerContext context, AuthorizationHeaderRequirement requirement)
        {
            // Requires the following import:
            //     using Microsoft.AspNetCore.Mvc.Filters;
            if (context.Resource is AuthorizationFilterContext mvcContext)
            {
                // Examine MVC-specific things like routing data.
                var httpContext = mvcContext.HttpContext;
    
                if (httpContext.Request.Headers.ContainsKey("Authorization"))
                {
                    context.Succeed(requirement);
                    return;
                }
                var failureResponse = new FailureResponseModel
                {
                    Result = false,
                    ResultDetails = "Authorization header not present in request",
                    Uri = httpContext.Request.Path.ToUriComponent(),
                    Timestamp = DateTime.Now.ToString("s", CultureInfo.InvariantCulture),
                    Error = new Error
                    {
                        Code = 108,
                        Description = "Authorization header not present in request",
                        Resolve = "Send Request with authorization header to avoid this error."
                    }
                };
    
                var responseString = JsonConvert.SerializeObject(failureResponse);
                mvcContext.Result = new ContentResult
                {
                    Content = responseString,
                    ContentType = "application/json",
                    StatusCode = 403
                };
    
                await mvcContext.Result.ExecuteResultAsync(mvcContext);
            }
            return;
        }
    }
    
  2. Startup.cs中配置

    services.AddAuthorization(options =>
    {
        options.AddPolicy("AuthorizationHeaderRequirement", policy =>
            policy.Requirements.Add(new AuthorizationHeaderRequirement()));
    });
    
    services.AddSingleton<IAuthorizationHandler, AuthorizationHeaderHandler>();
    
  3. 控制器

    [Authorize(Policy = "AuthorizationHeaderRequirement")]
    public IActionResult Privacy()
    {
        return View();
    }
    

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-10-21
    • 2014-03-14
    • 1970-01-01
    • 2021-06-07
    • 1970-01-01
    • 2021-03-26
    相关资源
    最近更新 更多