代码之家  ›  专栏  ›  技术社区  ›  Flo

.net core-如何在AuthorizationHandler上返回403?

  •  2
  • Flo  · 技术社区  · 8 年前

    我实现了自定义授权处理程序。 在这一点上,我检查我的用户可以解决和活动。

    如果用户未处于活动状态,则我希望返回403状态。

    protected override async Task HandleRequirementAsync(AuthorizationHandlerContext context, ValidUserRequirement requirement)
    {
        var userId = context.User.FindFirstValue( ClaimTypes.NameIdentifier );
    
        if (userId != null)
        {
            var user = await _userManager.GetUserAsync(userId);
    
            if (user != null)
            {
                _httpContextAccessor.HttpContext.AddCurrentUser(user);
    
                if (user.Active)
                {
                    context.Succeed(requirement);
                    return;
                }
                else
                {
                    _log.LogWarning(string.Format("User ´{1}´ with id: ´{0} isn't active", userId, user.UserName), null);
                }
            }
            else
            {
                _log.LogWarning(string.Format("Can't find user with id: ´{0}´", userId), null);
            }
        } else
        {
            _log.LogWarning(string.Format("Can't get user id from token"), null);
        }
    
        context.Fail();
    
        var response = _httpContextAccessor.HttpContext.Response;
        response.StatusCode = 403;
    
    }
    

    但我得到了401。你能帮帮我吗?

    2 回复  |  直到 8 年前
        1
  •  4
  •   Jaume    8 年前

    你能在函数结束时检查一下吗?我在我的自定义中间件中使用它,在某些情况下将状态代码重写为401,但在您的场景中也应该可以使用

    var filterContext = context.Resource as AuthorizationFilterContext;
    var response = filterContext?.HttpContext.Response;
    response?.OnStarting(async () =>
    {
        filterContext.HttpContext.Response.StatusCode = 403;
    //await response.Body.WriteAsync(message, 0, message.Length); only when you want to pass a message
    });
    
        2
  •  1
  •   itminus    8 年前

    根据单一责任原则,我们不应该使用 HandleRequirementAsync() 方法要重定向响应,我们应该使用中间件或控制器来代替。如果将重定向逻辑放入 HandleRequirementAsync() ,如果要在“视图”页中使用,如何?

    您可以将与重定向相关的代码移除到其他地方(外部),现在您可以插入 IAuthorizationService 要授权任何内容,甚至是基于资源的授权:

    public class YourController : Controller{
    
        private readonly IAuthorizationService _authorizationService;
        public YourController(IAuthorizationService authorizationService)
        {
            this._authorizationService = authorizationService;
        }
    
        [Authorize("YYY")]
        public async Task<IActionResult> Index()
        {
            var resource  /* = ... */ ;
            var x = await this._authorizationService.AuthorizeAsync(User,resource , "UserNameActiveCheck");
    
            if (x.Succeeded)
            {
                return View();
            }
            else {
                return new StatusCodeResult(403);
            }
        }
    
    }