ASP.NET Core 8 JWT授权提示签名密钥未找到问题求助
ASP.NET Core 8 JWT认证报错:The signature key was not found
问题现象
通过Swagger测试JWT令牌认证时,返回如下错误:
content-length: 0 date: Sun,12 Apr 2026 01:37:08 GMT server: Kestrel www-authenticate: Bearer error="invalid_token",error_description="The signature key was not found"
相关配置代码
JwtOptionsSetup
using EasyPay.Application.DTOs.Auth; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Options; namespace EasyPay.Application.OptionsSetup { public class JwtOptionsSetup : IConfigureOptions<JwtOptions> { private const string SectionName = "Jwt"; private readonly IConfiguration _configuration; public JwtOptionsSetup(IConfiguration configuration) { _configuration = configuration; } public void Configure(JwtOptions options) { _configuration.GetSection(SectionName).Bind(options); } } }
JwtBearerOptionsSetup
using EasyPay.Application.DTOs.Auth; using Microsoft.AspNetCore.Authentication.JwtBearer; using Microsoft.Extensions.Options; using Microsoft.IdentityModel.Tokens; using System.Text; namespace EasyPay.Application.OptionsSetup { public class JwtBearerOptionsSetup : IConfigureOptions<JwtBearerOptions> { private readonly JwtOptions _jwtOptions; public JwtBearerOptionsSetup(IOptions<JwtOptions> jwtOptions) { _jwtOptions = jwtOptions.Value; } public void Configure(JwtBearerOptions options) { options.TokenValidationParameters = new() { ValidateIssuer = true, ValidateAudience = true, ValidateLifetime = true, ValidateIssuerSigningKey = true, ValidIssuer = _jwtOptions.Issuer, ValidAudience = _jwtOptions.Audience, IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_jwtOptions.SecretKey)) }; } } }
JwtProvider
using EasyPay.Application.DTOs.Auth; using EasyPay.Application.Interfaces; using EasyPay.Core.Entities; using Microsoft.Extensions.Options; using Microsoft.IdentityModel.Tokens; using System.IdentityModel.Tokens.Jwt; using System.Security.Claims; using System.Text; namespace EasyPay.Application.Services.Auth { public class JwtProvider : IJwtProvider { private readonly JwtOptions _jwtOptions; public JwtProvider(IOptions<JwtOptions> jwtOptions) { _jwtOptions = jwtOptions.Value; } public string Generate(User user) { var claims = new Claim[] { new Claim("userId", user.UserId.ToString()), new Claim("email", user.Email) }; var signingCredentials = new SigningCredentials(new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_jwtOptions.SecretKey)), SecurityAlgorithms.HmacSha256); var token = new JwtSecurityToken(_jwtOptions.Issuer, _jwtOptions.Audience, claims, null, DateTime.UtcNow.AddHours(1), signingCredentials); string tokenValue = new JwtSecurityTokenHandler().WriteToken(token); return tokenValue; } } }
依赖注入配置(ServiceDI)
using EasyPay.Application.Interfaces; using EasyPay.Application.OptionsSetup; using EasyPay.Application.Services; using EasyPay.Application.Services.Auth; using EasyPay.Infrastructure.Database; using Microsoft.AspNetCore.Authentication.JwtBearer; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.OpenApi.Models; namespace EasyPay.Application.Exceptions; public static class ServiceDI { public static IServiceCollection AddServices(this IServiceCollection services, IConfiguration configuration) { services.AddControllers(); services.AddEndpointsApiExplorer(); services.AddSwaggerGen(option => { option.SwaggerDoc("v1", new OpenApiInfo { Title = "EasyPay API", Version = "v1" }); option.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme { In = ParameterLocation.Header, Description = "Please enter a valid token", Name = "Authorization", Type = SecuritySchemeType.Http, BearerFormat = "JWT", Scheme = "Bearer" }); option.AddSecurityRequirement(new OpenApiSecurityRequirement { { new OpenApiSecurityScheme { Reference = new OpenApiReference { Type = ReferenceType.SecurityScheme, Id = "Bearer" } }, new string[]{} } }); }); services.AddDbContext<EPContext>(options => { options.UseNpgsql(configuration.GetConnectionString("DefaultConnection")); }); services.AddScoped<IUserService, UserService>(); services.AddScoped<IOrderService, OrderService>(); services.AddScoped<IProductService, ProductService>(); services.AddScoped<IGameService, GameService>(); services.AddScoped<IJwtProvider, JwtProvider>(); services.AddScoped<IAuthService, AuthService>(); services.AddRouting(options => { options.LowercaseUrls = true; }); services.ConfigureOptions<JwtOptionsSetup>(); services.ConfigureOptions<JwtBearerOptionsSetup>(); services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme) .AddJwtBearer(); return services; } }
appsettings.json
{ "Logging": { "LogLevel": { "Default": "Information", "Microsoft.AspNetCore": "Warning" } }, "AllowedHosts": "*", "ConnectionStrings": { "DefaultConnection": "Server=localhost;Database=easypay_db;User Id=secret;Password=secret;" }, "Jwt": { "Issuer": "EasyPay", "Audience": "EasyPay", "SecretKey": "[radacted]" } }
排查与解决方案
1. 验证SecretKey的有效性
- 对于HmacSha256算法,
SecretKey长度至少需要32个字符(256位),若实际长度不足会直接导致签名验证失败。 - 确认密钥无特殊字符解析问题,比如多余引号、转义符等。
2. 检查JwtOptions配置绑定是否成功
在JwtOptionsSetup的Configure方法中添加调试输出,确认配置是否正确读取:
public void Configure(JwtOptions options) { _configuration.GetSection(SectionName).Bind(options); Console.WriteLine($"Issuer: {options.Issuer}, Audience: {options.Audience}, SecretKey: {options.SecretKey}"); }
启动项目后查看控制台,确认SecretKey与配置文件一致。
3. 确认中间件注册顺序
在Program.cs中,保证认证中间件在授权中间件之前:
var app = builder.Build(); // 其他中间件... app.UseAuthentication(); app.UseAuthorization(); app.MapControllers(); app.Run();
顺序颠倒会导致令牌未验证就执行授权逻辑,引发错误。
4. 验证生成与验证的密钥一致性
在JwtProvider的Generate方法添加调试输出,对比JwtBearerOptionsSetup中的密钥:
public string Generate(User user) { Console.WriteLine($"Generate Token SecretKey: {_jwtOptions.SecretKey}"); // 剩余代码... }
确保两者完全相同,无大小写或字符差异。
5. 检查Swagger的Token输入格式
在Swagger中输入Token时,必须遵循Bearer {token}格式,注意Bearer后有一个空格,不要遗漏或多输入空格。
内容的提问来源于stack exchange,提问作者Uchqunov Muhammadamin
相关产品推荐
相关产品推荐

