You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.01 13:08:12