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

IdentityServer3能否将资源范围纳入访问令牌受众数组以兼容AddJwtBearer?

适配IdentityServer3与IdentityServer4的JWT验证平滑方案

针对你的需求——让ASP.NET Core Web API的JWT验证逻辑既能兼容IdentityServer3(IDS3)生成的令牌,又能在升级到IdentityServer4(IDS4)后无需大幅修改,我整理了两个贴合你思路的可行方案:

方案1:修改IDS3令牌的受众(Audience)为数组并包含资源Scope

IDS3默认生成的JWT令牌中,aud(受众)字段通常是单个值(比如客户端ID或API资源名称),原生不支持直接将Scope加入受众数组,但你可以通过自定义令牌生成逻辑实现这一点:

  1. 实现ICustomTokenService接口,重写令牌生成逻辑:
public class CustomTokenService : DefaultTokenService
{
    public CustomTokenService(IServiceLocator serviceLocator) : base(serviceLocator)
    {
    }

    public override async Task<Token> CreateAccessTokenAsync(TokenCreationRequest request)
    {
        var token = await base.CreateAccessTokenAsync(request);
        
        // 将需要验证的业务Scope添加到受众列表中
        var targetScopes = request.Scopes.Where(s => s.StartsWith("api_")).ToList();
        token.Audiences.AddRange(targetScopes);
        
        return token;
    }
}
  1. 在IDS3的Startup配置中注册自定义TokenService:
var factory = new IdentityServerServiceFactory();
factory.TokenService.RegisterType<CustomTokenService>();

这样生成的IDS3令牌aud字段就会是包含API资源名称和目标Scope的数组。之后在ASP.NET Core的AddJwtBearer配置中,只需指定ValidAudiences为对应的数组值,验证逻辑就能同时适配IDS3和IDS4(IDS4默认会将API资源名称作为受众,若你保持Scope命名一致,升级后仅需切换Authority地址即可)。

方案2:在AddJwtBearer中添加Scope声明验证

如果修改IDS3的令牌生成逻辑成本较高,更直接的方式是在API端的JWT验证流程中手动检查Scope声明,这种方式在IDS3和IDS4中完全通用:

方式A:通过JWT事件验证Scope

services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
    .AddJwtBearer(options =>
    {
        options.Authority = "https://your-ids3-server.com";
        options.Audience = "your-api-resource-name";
        
        options.Events = new JwtBearerEvents
        {
            OnTokenValidated = context =>
            {
                // 从令牌声明中提取Scope列表
                var scopeClaim = context.Principal.FindFirst("scope");
                if (scopeClaim == null || !scopeClaim.Value.Split(' ').Contains("api_access"))
                {
                    context.Fail("Missing or invalid required scope");
                }
                return Task.CompletedTask;
            }
        };
    });

方式B:使用基于策略的授权(更推荐)

这种方式更符合ASP.NET Core的授权规范,也更灵活易维护:

  1. 定义验证Scope的授权策略:
services.AddAuthorization(options =>
{
    options.AddPolicy("ApiRequiredScope", policy =>
    {
        policy.RequireAuthenticatedUser();
        policy.RequireClaim("scope", "api_access");
    });
});
  1. 在API控制器或Action上应用策略:
[Authorize(Policy = "ApiRequiredScope")]
[ApiController]
[Route("api/[controller]")]
public class ValuesController : ControllerBase
{
    // 你的API逻辑
}

这种方式在IDS3和IDS4中都能正常工作,因为两者生成的令牌都会包含scope声明字段,升级到IDS4后无需修改授权逻辑。

平滑过渡的最佳实践

  • 如果你倾向于通过Audience完成验证,优先选择方案1,确保IDS3和IDS4的令牌aud字段保持一致(比如都包含API资源名称),升级后仅需切换Authority地址即可。
  • 若修改IDS3的令牌生成逻辑有障碍,方案2是更轻量的选择,授权逻辑在两个版本的IdentityServer中完全通用,迁移成本极低。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 04:12:26