.NET 7中如何使用RSA安全密钥验证Bearer令牌?
问题分析与修正方案
报错The signature key was not found的核心原因是.NET 7认证中间件未正确加载与.NET Framework生成令牌匹配的RSA验证密钥,或配置未兼容旧版令牌的签名逻辑。以下是修正后的代码及关键说明:
修正后的自定义认证扩展方法
using Microsoft.AspNetCore.Authentication.JwtBearer; using Microsoft.IdentityModel.Tokens; using System.Security.Cryptography; public static class AuthenticationExtensions { public static IServiceCollection AddCustomJwtAuthentication(this IServiceCollection services, string rsaPublicKeyXml) { // 加载.NET Framework兼容的XML格式RSA公钥 var rsa = RSA.Create(); rsa.FromXmlString(rsaPublicKeyXml); var signingKey = new RsaSecurityKey(rsa); services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme) .AddJwtBearer(options => { options.TokenValidationParameters = new TokenValidationParameters { ValidateIssuer = true, ValidateAudience = true, ValidateLifetime = true, ValidateIssuerSigningKey = true, // 必须与.NET Framework生成令牌时的Issuer、Audience完全一致 ValidIssuer = "你的旧应用Issuer", ValidAudience = "你的旧应用Audience", IssuerSigningKey = signingKey, // 消除服务器时间差导致的验证失败 ClockSkew = TimeSpan.Zero, // 显式匹配RSA签名算法,兼容旧版令牌 SignatureValidator = (token, parameters) => { var handler = new JwtSecurityTokenHandler(); var jwtToken = handler.ReadJwtToken(token); // 若旧应用使用其他RSA签名算法,替换为对应枚举值(如RsaSha384) if (jwtToken.Header.Alg == SecurityAlgorithms.RsaSha256) { parameters.IssuerSigningKey = signingKey; } return handler.ValidateToken(token, parameters, out _) as JwtSecurityToken; } }; }); return services; } }
Program.cs调用示例
var builder = WebApplication.CreateBuilder(args); // 从配置读取RSA公钥(正式环境建议存入配置文件而非硬编码) var rsaPublicKey = builder.Configuration["JwtSettings:RsaPublicKey"]; // 注册自定义认证服务 builder.Services.AddCustomJwtAuthentication(rsaPublicKey); builder.Services.AddControllers(); var app = builder.Build(); // 中间件顺序必须是先认证后授权 app.UseAuthentication(); app.UseAuthorization(); app.MapControllers(); app.Run();
关键注意事项
- 公钥正确性:确保使用的XML格式公钥与.NET Framework生成令牌的私钥完全配对,公钥需包含完整的
<RSAKeyValue>标签。 - Issuer/Audience匹配:必须与旧应用生成令牌时设置的参数完全一致,大小写、字符都不能错。
- 签名算法匹配:用JWT解码工具(如jwt.io)查看令牌Header的
alg字段,若为RS384或RS512,需同步修改代码中的SecurityAlgorithms枚举值。 - 中间件顺序:
UseAuthentication必须在UseAuthorization之前调用,否则认证逻辑不会触发。 - 控制器授权标记:确保需要验证的接口或控制器添加了
[Authorize]属性。
内容的提问来源于stack exchange,提问作者Daan
相关产品推荐
相关产品推荐

