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

.NET Core 6 JWT令牌签名验证失败:无kid字段问题求助

.NET Core 6 JWT认证:Signature validation failed. Token does not have a kid 问题排查

我在.NET Core 6环境下实现JWT认证功能,调用User()接口发起GET请求时抛出异常:Signature validation failed. Token does not have a kid。按照建议在Generate方法中添加了header.Add("kid", "unique_key_id"),但问题仍未解决,需要协助排查。

相关代码如下:

JwtService 代码

public class JwtService
{
    private string secureKey = "KFJSDKLŞGJSkldfsggdgsaagrdrgfdjfklsajk1234567890!@#$%^&*()1234567890!@#$%^&*()";
    public string Generate(int id)
    {
        var symmetricSecurityKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(secureKey));
        var credentials = new SigningCredentials(symmetricSecurityKey, SecurityAlgorithms.HmacSha256Signature);
        var header = new JwtHeader(credentials);
        header.Add("kid", "unique_key_id");
        var payload = new JwtPayload(id.ToString(), null, null, null, DateTime.Today.AddDays(1));
        var token = new JwtSecurityToken(header, payload);
        return new JwtSecurityTokenHandler().WriteToken(token);
    }
    public JwtSecurityToken Verify(string jwt)
    {
        var tokenHandler = new JwtSecurityTokenHandler();
        var key = Encoding.ASCII.GetBytes(secureKey);
        tokenHandler.ValidateToken(jwt, new TokenValidationParameters
        {
            IssuerSigningKey = new SymmetricSecurityKey(key),
            ValidateIssuerSigningKey = true,
            ValidateIssuer = false,
            ValidateAudience = false
        }, out SecurityToken validatedToken);
        return (JwtSecurityToken)validatedToken;
    }
}

User接口代码

public IActionResult User()
{
    try
    {
        var jwt = Request.Cookies["jwt"];
        var token = _jwtService.Verify(jwt);
        int userId = int.Parse(token.Issuer);
        var user = _repository.GetById(userId);
        return Ok(user);
    }
    catch (Exception)
    {
        return Unauthorized();
    }
}

问题根源与修复方案

1. 密钥编码不一致导致签名验证失败

Generate方法使用Encoding.UTF8处理密钥,但Verify方法用了Encoding.ASCII。密钥中包含非ASCII字符(比如Ş),ASCII编码会丢失这些字符,导致验证时使用的密钥和生成Token时的密钥不一致,直接触发签名验证失败。

修复:将Verify方法中的编码统一为UTF8:

var key = Encoding.UTF8.GetBytes(secureKey);

2. 未配置Kid与密钥的映射关系

当Token的Header中包含kid字段时,验证逻辑需要明确知道该kid对应的签名密钥。当前的TokenValidationParameters仅设置了单个IssuerSigningKey,没有关联kid,导致验证器无法匹配,抛出"Token does not have a kid"异常。

修复:修改Verify方法的TokenValidationParameters,添加带kid的密钥集合:

tokenHandler.ValidateToken(jwt, new TokenValidationParameters
{
    ValidIssuerSigningKeys = new List<SecurityKey>
    {
        new SymmetricSecurityKey(Encoding.UTF8.GetBytes(secureKey))
        {
            KeyId = "unique_key_id" // 与生成Token时的kid保持一致
        }
    },
    ValidateIssuerSigningKey = true,
    ValidateIssuer = false,
    ValidateAudience = false,
    ValidateLifetime = true // 建议开启,避免过期Token被使用
}, out SecurityToken validatedToken);

3. 生成Token时设置Kid的方式不规范

手动调用header.Add("kid", "unique_key_id")虽然能添加字段,但更规范的方式是直接给SecurityKey设置KeyId,JWT处理程序会自动将其写入Header,避免手动操作可能出现的格式问题。

修复:修改Generate方法,直接给密钥设置KeyId:

public string Generate(int id)
{
    var symmetricSecurityKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(secureKey))
    {
        KeyId = "unique_key_id"
    };
    var credentials = new SigningCredentials(symmetricSecurityKey, SecurityAlgorithms.HmacSha256Signature);
    
    var payload = new JwtPayload(
        issuer: id.ToString(), 
        audience: null, 
        claims: null, 
        notBefore: null, 
        expires: DateTime.UtcNow.AddDays(1)); // 改用UtcNow避免时区问题
    
    var token = new JwtSecurityToken(
        issuer: id.ToString(),
        expires: DateTime.UtcNow.AddDays(1),
        signingCredentials: credentials);
    
    return new JwtSecurityTokenHandler().WriteToken(token);
}

额外检查

  • 提取Cookie中的JWT,到JWT解析工具中查看Header是否包含正确的kid字段,确认Token没有被截断或篡改。
  • 检查Token过期时间:DateTime.Today.AddDays(1)会在当天零点生成有效期到次日零点的Token,若当前时间接近零点,可能导致Token刚生成就过期,建议改用DateTime.UtcNow.AddDays(1)。

内容的提问来源于stack exchange,提问作者Enes Tanis

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 12:32:33