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

ASP.NET Core授权中如何为同一控制器操作同时校验应用与用户访问令牌权限

微软身份平台同时支持委托权限与应用权限的授权方案

核心前提:多个[Authorize]特性默认执行与逻辑,要实现「scope校验通过 或 role校验通过即可访问」的需求,需要将二选一的判断逻辑合并到同一个授权规则中,以下是两种常用的最佳实践方案:

方案1:断言式组合策略(轻量场景首选)

直接在策略定义中使用RequireAssertion编写自定义判断逻辑,满足任意条件即可通过授权:

builder.Services.AddAuthorization(options =>
{
    options.AddPolicy("AllowScopeOrAppRole", policy => 
        policy.RequireAssertion(context =>
            // 校验是否持有目标委托权限,兼容多scope空格分隔的场景
            context.User.HasClaim(c => 
                c.Type == "scp" && c.Value.Split(' ').Contains("TheScope"))
            // 或校验是否持有目标应用权限
            || context.User.IsInRole("TheRole")
        ));
});

在控制器操作上只需要应用单个授权特性即可:

[Authorize(Policy = "AllowScopeOrAppRole")]
public IActionResult YourTargetAction()
{
    // 业务逻辑
}

方案2:自定义授权需求(复杂复用场景首选)

如果多个接口需要匹配不同的scope和role组合,可以实现通用的自定义授权规则,避免重复编码:

  1. 首先定义授权需求类和对应的处理器:
// 自定义授权需求:可传入任意需要校验的scope和role
public class ScopeOrRoleRequirement : IAuthorizationRequirement
{
    public string RequiredScope { get; }
    public string RequiredRole { get; }

    public ScopeOrRoleRequirement(string requiredScope, string requiredRole)
    {
        RequiredScope = requiredScope;
        RequiredRole = requiredRole;
    }
}

// 授权处理器:实现二选一校验逻辑
public class ScopeOrRoleHandler : AuthorizationHandler<ScopeOrRoleRequirement>
{
    protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, ScopeOrRoleRequirement requirement)
    {
        bool hasValidScope = context.User.Claims
            .Any(c => c.Type == "scp" && c.Value.Split(' ').Contains(requirement.RequiredScope));
        bool hasValidRole = context.User.IsInRole(requirement.RequiredRole);

        if (hasValidScope || hasValidRole)
        {
            context.Succeed(requirement);
        }
        return Task.CompletedTask;
    }
}
  1. 注册服务和策略:
// 注册自定义授权处理器
builder.Services.AddSingleton<IAuthorizationHandler, ScopeOrRoleHandler>();

// 按需创建不同的组合授权策略
builder.Services.AddAuthorization(options =>
{
    // 针对当前场景的策略
    options.AddPolicy("AllowTheScopeOrRole", policy =>
        policy.AddRequirements(new ScopeOrRoleRequirement("TheScope", "TheRole")));
    // 其他场景可以直接新增策略,传入不同的scope和role即可
    // options.AddPolicy("AllowOtherScopeOrRole", policy =>
    //     policy.AddRequirements(new ScopeOrRoleRequirement("OtherScope", "OtherRole")));
});
  1. 控制器上的使用方式和方案1一致,应用对应策略的[Authorize]特性即可。

两种方案均可以同时兼容客户端凭据流生成的应用权限令牌、授权码流生成的用户委托权限令牌的访问需求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.14 01:18:02