IDX10501:签名验证失败。无法匹配键
IDX10501: Signature validation failed. Unable to match keys
请帮助我了解来自 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 核心。
相同的源代码(和配置)用于从 Azure AD 获取令牌。
请找到 the gist here。
它被配置为从 https://login.microsoftonline.com/{tenant}/v2.0
提供商获取令牌。两种情况都使用相同的令牌端点、clientid、secret 和范围值。
问题是 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
实施)而控制台主机失败?
谢谢
为了解决这个错误,我必须从 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
下载和提供的密钥,但为什么 AddJwtBearer
中间件不使用 .well-known/openid-configuration
自动加载它?
在我的例子中,同样的错误是因为无意中使用了从一个环境 (https://dev/identity) 接收并在另一个环境 (即 http://local/identity) 中验证的令牌.
请帮助我了解来自 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 核心。
相同的源代码(和配置)用于从 Azure AD 获取令牌。
请找到 the gist here。
它被配置为从 https://login.microsoftonline.com/{tenant}/v2.0
提供商获取令牌。两种情况都使用相同的令牌端点、clientid、secret 和范围值。
问题是 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
实施)而控制台主机失败?
谢谢
为了解决这个错误,我必须从 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
下载和提供的密钥,但为什么 AddJwtBearer
中间件不使用 .well-known/openid-configuration
自动加载它?
在我的例子中,同样的错误是因为无意中使用了从一个环境 (https://dev/identity) 接收并在另一个环境 (即 http://local/identity) 中验证的令牌.