.NET Core 7 Minimal API JWT认证报错:签名密钥未找到
1. 配置注册顺序错误
你把ConfigureOptions注册放在了AddAuthentication之后,这可能导致JWT验证配置没被正确应用到JwtBearerOptions上。ASP.NET Core中建议先注册配置选项,再添加认证服务。
修复:
调整Program.cs代码顺序,先注册配置选项,再添加认证授权:
// 先注册配置选项 builder.Services.ConfigureOptions<JWTOptionsSetup>(); // 注意检查这个类是否正确实现 builder.Services.ConfigureOptions<JWTBearerOptionsSetup>(); // 再添加认证和授权 builder.Services.AddAuthentication(options => { options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme; options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme; options.DefaultSignInScheme = JwtBearerDefaults.AuthenticationScheme; }).AddJwtBearer(); builder.Services.AddAuthorization(auth => { auth.AddPolicy("Bearer", new AuthorizationPolicyBuilder() .AddAuthenticationSchemes(JwtBearerDefaults.AuthenticationScheme) .RequireAuthenticatedUser() .Build()); });
2. JWTOptionsSetup可能存在拼写错误或未正确配置JwtOptions
你在Program.cs里注册了JWTOptionsSetup,但没提供这个类的代码。如果它是用来配置JwtOptions的,必须确保它正确绑定了配置文件中的JWT参数(SecretKey、Issuer、Audience),否则_jwtOptions.SecretKey会为空,直接导致验证时找不到签名密钥。
修复:
如果没有专门的JWTOptionsSetup类,直接用以下方式绑定配置:
// 替换原来的ConfigureOptions<JWTOptionsSetup>() builder.Services.Configure<JwtOptions>(builder.Configuration.GetSection("Jwt"));
同时确保appsettings.json中有对应配置节点:
{ "Jwt": { "SecretKey": "你的强密钥(建议至少32位)", "Issuer": "你的服务发行者名称", "Audience": "你的目标受众名称" } }
3. RequireSignedTokens配置冲突
你在JWTBearerOptionsSetup里设置了RequireSignedTokens = false,但同时开启了ValidateIssuerSigningKey = true,这两个配置互相矛盾。既然你生成的是带签名的JWT,就必须要求验证签名。
修复:
将RequireSignedTokens改为true(或者直接移除该配置,默认值就是true):
options.TokenValidationParameters = new() { ValidateAudience = true, ValidAudience = _jwtOptions.Audience, ValidateIssuer = true, ValidIssuer = _jwtOptions.Issuer, ValidateLifetime = true, ValidateIssuerSigningKey = true, RequireSignedTokens = true, IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_jwtOptions.SecretKey)), };
4. OnMessageReceived事件的ValidateToken方法可能有问题
你绑定了OnMessageReceived = ValidateToken但没提供方法实现,如果这个方法没有正确提取请求中的Token,或者修改了Token内容,会直接导致签名验证失败。
修复:
如果不需要自定义Token提取逻辑,直接移除这个事件绑定;如果需要自定义,确保方法正确提取Token:
// 不需要自定义的话,直接删除这段事件绑定代码 // options.Events = new JwtBearerEvents() // { // OnMessageReceived = ValidateToken // }; // 如需自定义提取逻辑,示例实现: private Task ValidateToken(MessageReceivedContext context) { var token = context.Request.Headers.Authorization.FirstOrDefault()?.Split(" ").Last(); if (!string.IsNullOrEmpty(token)) { context.Token = token; } return Task.CompletedTask; }
5. 确认SecretKey完全一致
生成Token和验证Token时使用的SecretKey必须完全相同,包括大小写、空格、特殊字符等。可以在生成和验证的代码中分别输出密钥值,确认两者完全一致。
内容的提问来源于stack exchange,提问作者Jack M

