c# - IDX10501:签名验证失败。无法匹配键
问题描述
请帮助我了解来自 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 核心的 via。
相同的源代码(和配置)用于从 Azure AD 获取令牌。请在此处找到它作为要点。它被配置为从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
实现)而控制台主机失败?
谢谢
解决方案
要解决此错误,我必须从 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-configuration
加载AddJwtBearer
?
推荐阅读
- python - 在字符串中查找单词,然后在 excel 中写入字符串,找到不同字体的单词
- android - @Override "Method..." 从另一个项目复制方法后
- javascript - 如何在 vue JavaScript 中将数据从一个组件恢复到另一个组件
- python - Python:如何在 Pandas 的循环中正确使用滚动平均值?
- r - 使用 tufte-book 在 bookdown 中设置 PDF 输出的纸张大小
- css - 对话框、快餐栏、...entryComponents 上的 Angular Material 自定义主题
- r - 在 R 中生成特殊矩阵的更有效函数
- sql - SQL罗斯文数据库查询重复行
- google-apps-script - 如何创建一个接受多个输入的谷歌脚本提示
- r - R 包在 Windows 上构建,但无法运行示例 - 使 R 会话崩溃