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组合,可以实现通用的自定义授权规则,避免重复编码:
- 首先定义授权需求类和对应的处理器:
// 自定义授权需求:可传入任意需要校验的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; } }
- 注册服务和策略:
// 注册自定义授权处理器 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一致,应用对应策略的
[Authorize]特性即可。
两种方案均可以同时兼容客户端凭据流生成的应用权限令牌、授权码流生成的用户委托权限令牌的访问需求。
内容的提问来源于stack exchange,提问作者user4252634
相关产品推荐
相关产品推荐

