.NET 6多认证方案内部工作机制及高负载性能疑问
.NET 6 多JWT认证的内部机制与性能疑问
已实现的配置代码
认证服务注册
.AddJwtBearer(options => { // 配置Authority等参数 options.Events = new JwtBearerEvents { OnAuthenticationFailed = ctx => { // 可添加日志或断点 }, OnChallenge = ctx => { // 可添加日志或断点 return Task.CompletedTask; }, OnMessageReceived = ctx => { return Task.CompletedTask; }, OnTokenValidated = ctx => { return Task.CompletedTask; } }; }).AddJwtBearer("PrepIdentityServer", options => { // 配置专属参数 options.Events = new JwtBearerEvents { OnAuthenticationFailed = ctx => { // 可添加日志或断点 }, OnChallenge = ctx => { // 可添加日志或断点 return Task.CompletedTask; }, OnMessageReceived = ctx => { return Task.CompletedTask; }, OnTokenValidated = ctx => { return Task.CompletedTask; } }; });
控制器授权配置
[Authorize(AuthenticationSchemes = "Bearer,PrepIdentityServer")] public class PortfolioSeriesController
观察到的执行行为
- 使用第一个授权机构(如Azure AD)的令牌发起请求时,两种认证方案都会被调用
- 第一个方案认证成功,第二个方案因令牌不匹配认证失败
- 最终接口返回200状态码,符合预期
核心疑问
当前认证逻辑会执行两种方案的异步任务,看起来需要等两个任务全部完成才会判定结果。如果其中一个认证方案耗时较长,会不会在高负载场景下引发性能问题?或者JWT认证本身足够轻量且带有缓存,无需担心?
解答
内部执行逻辑
当通过[Authorize(AuthenticationSchemes)]指定多个认证方案时,ASP.NET Core的认证中间件会遍历所有指定的方案,依次执行每个方案的完整认证流程——即使前一个方案已经认证成功,后续方案的逻辑依然会全部执行。
不过JWT认证的核心耗时操作默认带有缓存机制:
- 公钥与元数据缓存:
JwtBearerOptions中的ConfigurationManager会自动缓存从授权机构获取的OpenID元数据和公钥,默认缓存有效期由授权机构的配置决定,不会每次请求都发起远程调用 - 本地验证操作:令牌过期检查、受众/颁发者校验等步骤都是本地轻量计算,耗时可以忽略
性能影响分析
- 常规场景无需担忧:只要授权机构的元数据稳定,缓存命中率会极高,大部分认证请求都是本地操作,性能开销非常小,高负载下也不会成为瓶颈。
- 极端情况的性能风险:如果某个认证方案的缓存过期,恰好需要重新拉取远程元数据/公钥,此时该方案的认证会产生网络请求耗时。如果高负载下大量请求同时触发缓存刷新,可能会短暂出现性能波动。
- 优化方向:
- 提前筛选认证方案:在
OnMessageReceived事件中解析令牌的iss(颁发者)字段,动态指定只执行匹配的认证方案,避免无用的认证流程。例如:OnMessageReceived = ctx => { var authHeader = ctx.Request.Headers["Authorization"].ToString(); var token = authHeader.Replace("Bearer ", ""); if (!string.IsNullOrEmpty(token)) { var handler = new JwtSecurityTokenHandler(); if (handler.CanReadToken(token)) { var jwtToken = handler.ReadJwtToken(token); var schemeProvider = ctx.HttpContext.RequestServices.GetRequiredService<IAuthenticationSchemeProvider>(); if (jwtToken.Issuer == "https://login.microsoftonline.com/xxx/v2.0") { ctx.Scheme = schemeProvider.GetSchemeAsync("Bearer").Result; } else if (jwtToken.Issuer == "https://your-identity-server.com") { ctx.Scheme = schemeProvider.GetSchemeAsync("PrepIdentityServer").Result; } } } return Task.CompletedTask; } - 调整缓存策略:通过
options.ConfigurationManager.RefreshInterval设置元数据缓存的刷新间隔,减少远程请求频率;也可以自定义缓存实现,提升缓存稳定性。 - 监控认证耗时:在
OnTokenValidated和OnAuthenticationFailed事件中记录每个方案的认证耗时,定位性能瓶颈。
- 提前筛选认证方案:在
总结
默认的多JWT认证方案在大部分场景下性能足够可靠,缓存机制能有效降低远程调用开销。如果高负载下确实遇到性能问题,通过提前筛选认证方案、优化缓存配置等手段,可以进一步降低性能损耗。
内容的提问来源于stack exchange,提问作者daxu
相关产品推荐
相关产品推荐

