如何在授权失败(403)时修改响应正文?

时间:2019-05-09 08:59:44

标签: asp.net-core-webapi

我要修改“授权失败”的响应正文(“ 403禁止”)。 我目前收到403错误,但是找不到拦截中间件/过滤器以修改响应正文的正确位置。

我在路线上使用的是AuthorizeAttribute

[Authorize(Roles = Constants.Roles.MyRole)]
public IActionResult GetResources() { /* ... */ }

并设置身份验证。

services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
    .AddJwtBearer(options => 
    {
        options.TokenValidationParameters = services.BuildServiceProvider().GetService<TokenValidationParameters>();
        options.Events = new JwtBearerEvents(){
            OnChallenge = context => { /* handle authentication errors (401) */ }
            OnAuthenticationFailed  = context => { /* This never seems to get hit */ }
            OnMessageRecieved = context => { /* always hit but authorization not hit yet */ }
            OnTokenValidated = context => { /* always hit but authorization not hit yet */ }
        };
    });

我尝试将要求添加到我的AuthorizeFilter并添加ExceptionFilter。

services.AddMvc(options =>
{
    options.Filters.Add(new AuthorizeFilter(new AuthorizationPolicyBuilder()
        .RequireAuthenticatedUser()
        .AddRequirements(new ReturnErrorRequirement())
        .Build()));
    options.Filters.Add(new MyExceptionFilter());
});

但是,我的ReturnErrorHandler在[AuthorizeAttribute]的处理程序之前被调用,并且异常过滤器根本没有被命中。

无奈之下,我为角色创建了自己的自定义属性和授权处理程序。

[System.AttributeUsage(AttributeTargets.All, Inherited = false, AllowMultiple = true)]
sealed class AllowedRoleAttribute : Attribute
{
    public AllowedRoleAttribute(string role)
    {
        Role = role;
    }

    public string Role
    {
        get;
    }
}


public class RouteAccessHandler : AuthorizationHandler<RouteAccessRequirement>
{
    protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, RouteAccessRequirement requirement)
    {
        //get roles from claims
        var roles = context.User.Claims.Where(claim => claim.Type == ClaimTypes.Role).ToList();

        //get allowed roles from route method
        var authorizationFilterContext = (AuthorizationFilterContext) context.Resource;
        var descriptor = (ControllerActionDescriptor) authorizationFilterContext.ActionDescriptor;
        var allowedRoles = Attribute.GetCustomAttributes(descriptor.MethodInfo, typeof(AllowedRoleAttribute)).Cast<AllowedRoleAttribute>().ToList();

        //determine if we have a match
        if (!allowedRoles.Any() || roles.Any(role =>
            allowedRoles.Any(allowedRole =>
                role.Value == allowedRole.Role)))
        {
            context.Succeed(requirement);
        }
        else 
        {
            // Modify response
        }

        return Task.CompletedTask;
    }
}

但是,这感觉像是黑客。

documentation没有任何示例,我的google-fu让我失望了。

如何在授权失败时修改响应正文?

0 个答案:

没有答案