ASP.NET Core配置JWT+Azure AD双认证后自定义JWT可跨方案访问接口问题
问题原因
- 你配置的默认授权策略同时注册了
TestBearer和AzureAd两个认证方案,该策略默认只要任意一个方案认证通过,就判定用户身份合法,完全覆盖了你在控制器接口上单独指定的AuthenticationSchemes属性的限制。 - 你的
TestBearer方案的Token验证参数配置过于宽松:ValidateIssuer、ValidateAudience、ValidateLifetime全部设为false,导致只要签名正确的自定义JWT都能通过该方案的认证,自然就能绕开接口的方案限制。
修复方案
步骤1:调整授权策略配置,替换默认多方案策略
移除原来的自定义DefaultPolicy配置,改为给两个认证方案分别创建独立的授权策略:
services.AddAuthorization(options => { // 为自定义JWT创建独立策略 options.AddPolicy("TestBearerPolicy", policy => { policy.AddAuthenticationSchemes("TestBearer"); policy.RequireAuthenticatedUser(); }); // 为Azure AD创建独立策略 options.AddPolicy("AzureAdPolicy", policy => { policy.AddAuthenticationSchemes("AzureAd"); policy.RequireAuthenticatedUser(); }); });
步骤2:修改控制器接口的Authorize标注
把原来直接指定AuthenticationSchemes的方式,改为绑定对应独立策略:
[HttpGet] [Authorize(Policy = "TestBearerPolicy")] [Route("Test1")] public async Task Test() { } [HttpGet] [Authorize(Policy = "AzureAdPolicy")] [Route("Test2")] public async Task Test2() { }
步骤3:收紧TestBearer方案的Token验证规则(生产环境必改)
开启必要的校验项避免安全风险:
.AddJwtBearer("TestBearer", x => { x.RequireHttpsMetadata = false; // 生产环境建议设为true x.TokenValidationParameters = new Microsoft.IdentityModel.Tokens.TokenValidationParameters { ValidateIssuer = true, ValidIssuer = jwtConfig.Issuer, // 和生成Token时的Issuer保持一致 ValidateAudience = true, ValidAudience = jwtConfig.Audience, // 和生成Token时的Audience保持一致 ValidateLifetime = true, ClockSkew = TimeSpan.FromMinutes(5), // 允许的时间误差 ValidateIssuerSigningKey = true, IssuerSigningKey = new SymmetricSecurityKey(Guid.Parse(jwtConfig.SecretKey).ToByteArray()) }; })
步骤4:移除不必要的默认认证方案配置(可选)
如果没有全局默认认证的需求,可以删除AddAuthentication的DefaultScheme配置避免干扰:
services.AddAuthentication() // 不需要指定DefaultScheme .AddJwtBearer("TestBearer", x => { /* 原有配置 */ }) .AddMicrosoftIdentityWebApi(/* 原有配置 */, "AzureAd");
修改完成后,Test1接口只会放行通过自定义JWT认证的请求,Test2接口只会放行通过Azure AD认证的请求,不会再出现跨方案访问的问题。
内容的提问来源于stack exchange,提问作者Stuart Lexington
相关产品推荐
相关产品推荐

