You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ASP.NET Core无要求项创建IAuthorization策略的方法及问题咨询

问题解答

核心结论

直接在if(result)分支中标记所有待处理要求为成功不可行,会完全破坏ApiScope策略的验证逻辑,导致该策略的RequireClaim("scope", "customScope")要求被绕过,失去作用。

问题原因

ASP.NET Core的授权机制中,当你同时应用多个策略(如这里的ApiScope和ValidateGroups)时,所有策略的所有要求(Requirement)会被汇总到context.PendingRequirements中。你的GroupsValidationHandler实现了通用的IAuthorizationHandler接口,没有指定处理特定要求,因此会拦截所有待处理要求。一旦你的组验证通过,就会把包括ApiScope策略中scope声明验证在内的所有要求都标记为成功,这意味着哪怕用户没有customScope声明,只要组验证通过,ApiScope策略也会被判定为有效,完全违背了该策略的设计初衷。

正确解决方案

要避免干扰其他策略的验证逻辑,你需要让GroupsValidationHandler只处理属于自己的自定义要求,而非所有要求。具体步骤如下:

1. 创建自定义授权要求

定义一个专属的Requirement,用于标识组验证的逻辑边界:

public class GroupsValidationRequirement : IAuthorizationRequirement
{
    // 可根据需求添加属性,比如指定必须存在的组列表等
}

2. 修改授权处理器,仅处理自定义要求

继承AuthorizationHandler<TRequirement>而非直接实现IAuthorizationHandler,这样处理器只会响应GroupsValidationRequirement:

public class GroupsValidationHandler : AuthorizationHandler<GroupsValidationRequirement>
{
    private readonly IServiceScopeFactory _serviceScopeFactory;

    public GroupsValidationHandler(IServiceScopeFactory serviceScopeFactory)
    {
        _serviceScopeFactory = serviceScopeFactory;
    }

    protected override async Task HandleRequirementAsync(AuthorizationHandlerContext context, GroupsValidationRequirement requirement)
    {
        using (var scope = _serviceScopeFactory.CreateScope())
        {
            var authService = scope.ServiceProvider.GetRequiredService<IAuthenticationService>();
            var userGroups = context.User.FindAll("groups").Select(x => x.Value).ToList();
            var result = await authService.AllGroupsExist(userGroups);

            if (result)
            {
                // 仅标记当前自定义要求为成功
                context.Succeed(requirement);
            }
            else
            {
                // 组验证失败时终止授权流程
                context.Fail();
                if (context.Resource is DefaultHttpContext httpContext)
                {
                    httpContext.Response.OnStarting(() =>
                    {
                        httpContext.Response.StatusCode = StatusCodes.Status401Unauthorized;
                        return Task.CompletedTask;
                    });
                }
            }
        }
    }
}

3. 更新策略配置,绑定自定义要求

修改ValidateGroups策略,明确添加自定义要求,确保处理器只作用于该策略:

builder.Services.AddScoped<IAuthorizationHandler, GroupsValidationHandler>();

builder.Services.AddAuthorization(options =>
{
    options.AddPolicy("ApiScope", policy =>
    {
        policy.RequireAuthenticatedUser();
        policy.RequireClaim("scope", "customScope");
    });
    options.AddPolicy("ValidateGroups", policy =>
    {
        policy.RequireAuthenticatedUser();
        // 将自定义要求绑定到该策略
        policy.AddRequirements(new GroupsValidationRequirement());
    });
    options.InvokeHandlersAfterFailure = false;
});

app.MapControllers().RequireAuthorization("ApiScope", "ValidateGroups");

效果说明

修改后,两个策略的验证逻辑完全独立:

  • ApiScope策略由ASP.NET Core默认的处理器验证用户是否认证、是否持有customScope声明;
  • ValidateGroups策略由你的自定义处理器验证用户组是否全部存在;
  • 只有两个策略的所有要求都通过时,授权才会成功,任何一个策略失败都会直接返回401(因InvokeHandlersAfterFailure = false,失败后不会继续调用其他处理器)。

内容的提问来源于stack exchange,提问作者nnchvxx

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.04 05:25:16