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

ASP.NET Core 6 Web API中AuthorizationHandler未触发问题求助

解决ASP.NET Core 6中AuthorizationHandler未触发的问题

你的代码存在几个关键问题,导致ScreenAuthorizationHandler未被触发:

  • 自定义的ScreenAuthorizationAttribute只是普通Attribute,ASP.NET Core授权系统不会自动识别它作为授权规则的一部分。
  • 控制器方法上的[Authorize]未指定你定义的ScreenAuthorizationPolicy,授权系统不会执行对应的Requirement和Handler。
  • ScreenAuthorizationRequirement未携带ScreenID和PermissionLevel参数,Handler无法获取授权检查所需的业务信息。

以下是分步解决方案:

1. 修改自定义授权属性,关联到策略

将ScreenAuthorizationAttribute改为继承AuthorizeAttribute,并指定要使用的策略名称,让ASP.NET Core将其视为授权属性:

[AttributeUsage(AttributeTargets.Method | AttributeTargets.Class, AllowMultiple = false)]
public class ScreenAuthorizationAttribute : AuthorizeAttribute
{
    public Screens ScreenID { get; }
    public PermissionLevel PermissionLevel { get; }

    public ScreenAuthorizationAttribute(Screens screenID, PermissionLevel permissionLevel)
    {
        Policy = "ScreenAuthorizationPolicy";
        ScreenID = screenID;
        PermissionLevel = permissionLevel;
    }
}

2. 更新Requirement,添加业务参数

修改ScreenAuthorizationRequirement,添加用于接收属性参数的字段:

public class ScreenAuthorizationRequirement : IAuthorizationRequirement
{
    public Screens ScreenID { get; }
    public PermissionLevel PermissionLevel { get; }

    public ScreenAuthorizationRequirement(Screens screenID, PermissionLevel permissionLevel)
    {
        ScreenID = screenID;
        PermissionLevel = permissionLevel;
    }
}

3. 注册自定义策略提供程序

添加一个IAuthorizationPolicyProvider实现,动态根据属性参数生成授权策略:

public class ScreenAuthorizationPolicyProvider : DefaultAuthorizationPolicyProvider
{
    private readonly IOptions<AuthorizationOptions> _options;

    public ScreenAuthorizationPolicyProvider(IOptions<AuthorizationOptions> options) : base(options)
    {
        _options = options;
    }

    public override async Task<AuthorizationPolicy?> GetPolicyAsync(string policyName)
    {
        var policy = await base.GetPolicyAsync(policyName);
        if (policy != null)
            return policy;

        if (policyName == "ScreenAuthorizationPolicy")
        {
            var policyBuilder = new AuthorizationPolicyBuilder();
            policyBuilder.Requirements.Add(new ScreenAuthorizationRequirement(default, default));
            return policyBuilder.Build();
        }

        return null;
    }
}

在Program.cs中注册该提供程序:

builder.Services.AddSingleton<IAuthorizationPolicyProvider, ScreenAuthorizationPolicyProvider>();

4. 修改AuthorizationHandler,获取属性参数并执行逻辑

更新ScreenAuthorizationHandler,从请求端点元数据中获取自定义属性的参数,执行授权检查:

public class ScreenAuthorizationHandler : AuthorizationHandler<ScreenAuthorizationRequirement>
{
    private readonly IHttpContextAccessor _httpContextAccessor;

    public ScreenAuthorizationHandler(IHttpContextAccessor httpContextAccessor)
    {
        _httpContextAccessor = httpContextAccessor;
    }

    protected override Task HandleRequirementAsync(
        AuthorizationHandlerContext context,
        ScreenAuthorizationRequirement requirement)
    {
        var endpoint = _httpContextAccessor.HttpContext?.GetEndpoint();
        var screenAuthAttribute = endpoint?.Metadata.GetMetadata<ScreenAuthorizationAttribute>();

        if (screenAuthAttribute != null)
        {
            // 此处替换为你的自定义授权逻辑
            var targetScreen = screenAuthAttribute.ScreenID;
            var requiredPermission = screenAuthAttribute.PermissionLevel;
            
            context.Succeed(requirement);
        }
        else
        {
            context.Fail();
        }

        return Task.CompletedTask;
    }
}

在Program.cs中注册IHttpContextAccessor:

builder.Services.AddHttpContextAccessor();

5. 更新控制器方法

直接使用自定义的[ScreenAuthorization]属性,它已继承AuthorizeAttribute,会同时触发AWS Cognito认证和自定义授权:

[Route("api/[controller]/Endpoint")]
[ScreenAuthorization(Screens.screen1, PermissionLevel.Read)]
public async Task<IActionResult> GetSomething()
{
    // 业务逻辑代码
}

最后确认Program.cs的中间件顺序正确(已有代码符合要求):

app.UseAuthentication();
app.UseAuthorization();

app.MapControllers();
app.UseCors("*");
app.Run();

完成以上修改后,ScreenAuthorizationHandler会被正确触发,且能获取到指定的ScreenID和PermissionLevel参数执行自定义授权逻辑。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 17:02:17