.NET Core中AAD access_token签名验证失败(IDX10511)求助
解决AAD Access Token签名验证失败的问题
我来帮你搞定这个access_token验证失败的问题!你遇到的IDX10511错误,核心原因是你用了common租户的OpenID配置端点来验证特定租户签发的access_token,这两者的签名密钥不匹配导致的。
为什么会这样?
AAD的common端点是用于多租户场景下的id_token验证的,但access_token是由特定租户(就是你ValidIssuers里的tenantid对应的租户)签发的,它的签名密钥只存在于该租户专属的OpenID配置文档中,而不是公共的common端点里。所以用common端点拿到的密钥自然验证不了特定租户的access_token。
解决方案步骤
替换配置端点为租户专属的
把你的stsDiscoveryEndpoint从公共的common端点,改成你目标租户的专属端点:string tenantId = "你的租户ID"; string stsDiscoveryEndpoint = $"https://login.microsoftonline.com/{tenantId}/v2.0/.well-known/openid-configuration";先确认access_token是JWT格式
有些场景下(比如调用Microsoft Graph等第一方API),AAD返回的access_token是不透明令牌(不是JWT),这种令牌是无法用JwtSecurityTokenHandler验证的。可以先加个检查:if (!JwtSecurityTokenHandler.CanReadToken(token.AccessToken)) { // 不是JWT格式的令牌,无法验证,直接返回false或做对应处理 return false; }修改后的完整验证代码
整合上面的修改,你的验证代码应该改成这样:string tenantId = "你的租户ID"; string stsDiscoveryEndpoint = $"https://login.microsoftonline.com/{tenantId}/v2.0/.well-known/openid-configuration"; var handler = new JwtSecurityTokenHandler(); ConfigurationManager<OpenIdConnectConfiguration> configManager = new ConfigurationManager<OpenIdConnectConfiguration>(stsDiscoveryEndpoint, new OpenIdConnectConfigurationRetriever()); OpenIdConnectConfiguration config = configManager.GetConfigurationAsync().Result; try { // 先检查是否是可读取的JWT if (!JwtSecurityTokenHandler.CanReadToken(token.AccessToken)) { return false; } TokenValidationParameters validationParameters = new TokenValidationParameters { ValidIssuers = new [] { $"https://login.microsoftonline.com/{tenantId}/v2.0" }, ValidAudiences = new [] { "你的API的Client-ID" }, // 注意这里要和access_token的aud字段一致 ValidateAudience = true, ValidateIssuer = true, IssuerSigningKeys = config.SigningKeys, ValidateLifetime = true }; var tokenHandler = new JwtSecurityTokenHandler(); SecurityToken validatedToken = null; tokenHandler.ValidateToken(token.AccessToken, validationParameters, out validatedToken); return validatedToken != null; } catch (SecurityTokenInvalidSignatureException ex) { return false; } catch(SecurityTokenValidationException) { return false; }
额外注意事项
- 确认
ValidAudiences的值和access_token的aud(受众)字段完全一致:如果是你自己的API,这个值就是API的Client-ID;如果是调用第三方API(比如Graph),那就是该API的资源ID(比如https://graph.microsoft.com)。 - 尽量避免用
.Result同步调用异步方法,在ASP.NET Core中建议用await configManager.GetConfigurationAsync(),避免阻塞线程。
内容的提问来源于stack exchange,提问作者anonuser1
相关产品推荐
相关产品推荐

