You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多
文档控制台
免费开始使用

ASP.NET Core Identity中AddBearerToken的密钥位置及令牌生成算法疑问

ASP.NET Core Identity中AddBearerToken的密钥位置及令牌生成算法疑问

你遇到的这个问题其实挺典型的,我来帮你理清这两个关键点,顺便解释下为什么jwt.io解析不了你的令牌~

一、为什么你的令牌在jwt.io上解析失败?

首先要明确:ASP.NET Core 8及以后版本中,AddBearerToken()默认生成的是参考令牌(Reference Token),而不是标准的JWT格式。参考令牌只是一个随机生成的字符串,服务器会把令牌对应的用户信息存储在后端(比如内存、分布式缓存),所以它没有JWT那种三段式的结构,自然在jwt.io上会报错。

如果想要生成能在jwt.io上解析的自包含JWT,你需要手动配置AddBearerToken的令牌格式,示例代码如下:

builder.Services.AddAuthentication(options =>
{
    options.DefaultScheme = IdentityConstants.BearerScheme;
    options.DefaultAuthenticateScheme = IdentityConstants.BearerScheme;
    options.DefaultChallengeScheme = IdentityConstants.BearerScheme;
}).AddBearerToken(IdentityConstants.BearerScheme, options =>
{
    // 指定使用JWT格式的令牌
    options.TokenFormat = new JwtBearerTokenFormat(JwtBearerTokenFormat.DefaultSecurityAlgorithm);
});

二、密钥的位置

1. 默认情况(开发环境)

当你没有手动指定密钥时,ASP.NET Core会在应用启动时自动生成一个临时的内存密钥,用来签名令牌。但这种密钥只存在于当前应用进程中,一旦应用重启或者部署到新实例,密钥就会丢失,之前生成的所有令牌都会失效,所以只适合开发测试用。

2. 生产环境配置

生产环境必须使用持久化的密钥,常见的配置方式有两种:

  • 通过配置文件指定:在appsettings.json中添加密钥配置,然后在代码中读取:
    "BearerTokenSettings": {
      "SecretKey": "你的长字符串密钥,建议至少32位以上"
    }
    
    然后代码中配置:
    var secretKey = builder.Configuration["BearerTokenSettings:SecretKey"];
    builder.Services.AddAuthentication(options =>
    {
        // ... 其他配置
    }).AddBearerToken(IdentityConstants.BearerScheme, options =>
    {
        options.TokenFormat = new JwtBearerTokenFormat(
            SecurityAlgorithms.HmacSha256,
            new SymmetricSecurityKey(Encoding.UTF8.GetBytes(secretKey))
        );
    });
    
  • 使用DataProtection共享密钥:如果你的应用是多实例部署,可以用ASP.NET Core的DataProtection系统来共享密钥,确保所有实例使用同一个密钥:
    builder.Services.AddDataProtection()
        .PersistKeysToFileSystem(new DirectoryInfo(@"C:\Keys")) // 或者存储到Azure Blob、Redis等
        .SetApplicationName("你的应用名称");
    
    这样AddBearerToken会自动使用DataProtection的密钥来签名令牌。

三、令牌生成的算法

  • 默认参考令牌:不需要签名算法,因为令牌只是一个指向服务器存储数据的引用,服务器会直接验证令牌的存在性和有效性。
  • 自包含JWT模式:默认使用**HS256(HMAC-SHA256)**对称加密算法。如果你需要更安全的非对称算法(比如RS256),可以配置使用RSA密钥对:
    // 生成或加载RSA密钥对(生产环境建议从安全存储加载)
    var rsa = RSA.Create();
    // 假设你已经加载了公钥和私钥
    builder.Services.AddAuthentication(options =>
    {
        // ... 其他配置
    }).AddBearerToken(IdentityConstants.BearerScheme, options =>
    {
        options.TokenFormat = new JwtBearerTokenFormat(
            SecurityAlgorithms.RsaSha256,
            new RsaSecurityKey(rsa)
        );
    });
    

内容来源于stack exchange

火山引擎 最新活动