IDX10501:签名验证失败.无法匹配密钥 [英] IDX10501: Signature validation failed. Unable to match keys

查看:1609
本文介绍了IDX10501:签名验证失败.无法匹配密钥的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

Please help me to understand the difference between JWT token validation from the ASP netcore application and the netcore Kestrel hosted application.

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

There are two applications that verifies token using the source code like below:

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应用程序验证令牌,它会很好地工作

it is pretty simple and it works well if token is being validated from the asp net core 2.2 application

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

还有另一个应用程序(控制台),该应用程序使用UseKestrel

And there is another application (console) that starts the same rest service host using the UseKestrel

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

唯一的显着区别是,在控制台中,通过ConfigureKestrel的asp.net核心中有UseKestrel.

the only one significant difference is that there is UseKestrel in the console via ConfigureKestrel for asp.net core.

使用相同的源代码(和配置)从Azure AD获取令牌. 请在要点此处找到. 它被配置为从https://login.microsoftonline.com/{tenant}/v2.0提供程序获取令牌.两种情况都使用相同的令牌终结点,clientid,secret和scope值.

The same source code (and configuration) is used to get token from the Azure AD. Please find it as the gist here. It is configured to get token from the https://login.microsoftonline.com/{tenant}/v2.0 provider. The same token endpoint, clientid, secret and scope values are used for both cases.

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

The problem is that AddJwtBearer validates the token in the asp.net core and does not in the console app. the error is

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实现)而控制台主机失败?

Why asp.net core host validates the token (for the first AddJwtBearer implementation) and console host fails?

谢谢

推荐答案

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

to solve this error I've to load keys from the openid provider as below:

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下载和提供的键,但是为什么AddJwtBearer中间件不使用.well-known/openid-configuration自动加载键?

And it started to work for both cases. But what is the difference with the old AddJwtBearer implementation and the new one (related to the keys validation)? Keys where downloaded and supplied using the IssuerSigningKeys = openidconfig.SigningKeys but why it is not loaded automatically using the .well-known/openid-configuration by the AddJwtBearer middleware ?

这篇关于IDX10501:签名验证失败.无法匹配密钥的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆