IDX10501:签名验证失败。无法匹配键

Posted

技术标签:

【中文标题】IDX10501:签名验证失败。无法匹配键【英文标题】:IDX10501: Signature validation failed. Unable to match keys 【发布时间】:2020-03-10 09:49:16 【问题描述】:

请帮助我了解来自 ASP netcore 应用程序和 netcore Kestrel 托管应用程序的 JWT 令牌验证之间的区别。

有两个应用程序使用如下源代码验证令牌:

public static IServiceCollection AddJwtToken(this IServiceCollection services, OAuthConfig config)

    services.AddMvc();
    services.AddAuthorization();

    Logger.DebugFormat("AddJwtBearer authority:0 audience:1", config.GetAuthority(), config.Resource);

    services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
        .AddJwtBearer(options => new JwtBearerOptions
        
            Authority = config.GetAuthority(),
            Audience = config.Resource,
    );

    return services;

这很简单,如果从 asp net core 2.2 应用程序验证令牌,它会很好地工作

// in the asp.net core
var builder = WebHost.CreateDefaultBuilder(args);
builder
        .UseStartup<Startup>()
        .ConfigureKestrel(_ => _.ConfigureEndpoints())
        .UseSerilog();

还有另一个应用程序(控制台)使用UseKestrel启动相同的休息服务主机

//in the console app
var builder = WebHost.CreateDefaultBuilder()
    .UseNLog()
    .UseKestrel(_ => _.ConfigureEndpoints())
    .UseStartup<Startup>();

唯一一个显着的区别是控制台中有UseKestrel,通过ConfigureKestrel 用于asp.net core。

相同的源代码(和配置)用于从 Azure AD 获取令牌。 请查找the gist here。 它被配置为从https://login.microsoftonline.com/tenant/v2.0 提供程序获取令牌。两种情况都使用相同的令牌端点、clientid、secret 和 scope 值。

问题是AddJwtBearer 在 asp.net 核心中验证令牌,而不是在控制台应用程序中。 错误是

Microsoft.IdentityModel.Tokens.SecurityTokenSignatureKeyNotFoundException: IDX10501: Signature validation failed. Unable to match keys:
kid: 'BB8CeFVqyaGrGNuehJIiL4dfjzw',
token: '"typ":"JWT","alg":"RS256","kid":"BB8CeFVqyaGrGNuehJIiL4dfjzw"."aud":"2c163c99-935b-4362-ae0d-657f589f5565","iss":"https://login.microsoftonline.com/tenantidhere/v2.0

为什么 asp.net 核心主机验证令牌(对于第一个 AddJwtBearer 实现)而控制台主机失败?

谢谢

【问题讨论】:

【参考方案1】:

要解决此错误,我必须从 openid 提供程序加载密钥,如下所示:

Logger.DebugFormat("AddJwtBearer authority:0 audience:1", config.GetAuthority(), config.Resource);

IList<string> validissuers = new List<string>()

    config.GetAuthority(),
;

var configManager = new ConfigurationManager<OpenIdConnectConfiguration>($"validissuers.Last()/.well-known/openid-configuration", new OpenIdConnectConfigurationRetriever());

var openidconfig = configManager.GetConfigurationAsync().Result;

services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
    .AddJwtBearer(JwtBearerDefaults.AuthenticationScheme, _ =>
    
        _.TokenValidationParameters = new Microsoft.IdentityModel.Tokens.TokenValidationParameters()
        
            ValidateAudience = true,
            ValidAudience = config.Resource,

            ValidateIssuer = true,
            ValidIssuers = new[]  config.GetAuthority() ,

            ValidateIssuerSigningKey = true,
            IssuerSigningKeys = openidconfig.SigningKeys,

            RequireExpirationTime = true,
            ValidateLifetime = true,
            RequireSignedTokens = true,
        ;

        _.RequireHttpsMetadata = false;

    );

它开始适用于这两种情况。但是旧的AddJwtBearer 实现和新的(与密钥验证有关)有什么区别?使用IssuerSigningKeys = openidconfig.SigningKeys 下载和提供的密钥,但为什么没有使用.well-known/openid-configurationAddJwtBearer 中间件自动加载?

【讨论】:

感谢您的回答,我解决了我的问题。至于您为什么没有自动加载签名密钥的问题,我只能假设 id 服务器没有正确配置。就我而言,发行者 uri 是 http 而不是 https,这很奇怪。 @RosdiKasim 我正在从https://login.microsoftonline.com 加载令牌,你认为他们在后台有http:// 吗? 没有。在我对此发表评论后,我通过像这样显式设置 MetaDataAddress 完全解决了这个问题:options.MetadataAddress = Config.OidcAuthority + "/.well-known/openid-configuration"。然后验证会自动进行。 我使用了罗斯迪的评论。 ***.com/questions/49694383/… 与我正在尝试设置的内容有关,这两个 Q 和 A 都是工作解决方案的关键。 FWIW YMMV。应在撰写本文之日发表评论。感谢未来的读者。 OAuthConfig 类型中的“config.Resource”在您的代码中代表什么?这是“ValidAudience”,它为用户的客户端浏览器、运行代码的机器、OpenID Connect 服务器或其他东西提供了水合物?【参考方案2】:

在我的情况下,同样的错误是由于无意使用了从一个环境 (https://dev/identity) 接收并在另一个环境 (即 http://local/identity) 中验证的令牌。

【讨论】:

我也是!即使问题出在椅子和键盘之间,也感谢您添加此答案!哈哈!你为我节省了一些时间:) 天哪,谢谢你,我只是忘记在 appsetting 中更改我的 url environmnet。

以上是关于IDX10501:签名验证失败。无法匹配键的主要内容,如果未能解决你的问题,请参考以下文章

Azure b2c 错误:IDX10501:签名验证失败。无法匹配键:孩子:'gLv****************'

IDX10501:签名验证失败。无法匹配密钥

收到 IDX10501 的错误信息:签名验证失败。使用 Azure AD 时无法匹配密钥

IDX10501:签名验证失败。尝试的密钥:'System.IdentityModel.Tokens.X509AsymmetricSecurityKey'

签名验证失败。无法匹配“孩子”

Azure AD B2C 错误 - IDX10501:签名验证失败