使用 System.IdentityModel.Tokens.Jwt 验证外部创建的没有密钥 ID 的 JWT

Hau*_*and 6 c# jwt

鉴于 JWT 是在外部创建的,因此无法影响它,当令牌不包含kid.

这是相关代码:

private bool ValidateToken(string authToken)
{
    var tokenHandler = new JwtSecurityTokenHandler();
    var hmac = new HMACSHA256(Encoding.UTF8.GetBytes(_secretKey));
    var validationParameters = new TokenValidationParameters()
    {
        ValidAudience = "clientid",
        ValidIssuer = _issuer,
        ValidateAudience = false,
        ValidateIssuer = false,
        IssuerSigningKey = new SymmetricSecurityKey(hmac.Key),
    };

    try
    {
        tokenHandler.ValidateToken(authToken, validationParameters, out SecurityToken validatedToken);
    }
    catch (Exception ex)
    {
        //handle exception
    }
    return true;
}
Run Code Online (Sandbox Code Playgroud)

然而这会引发异常:

{
"IDX10503: Signature validation failed. 
    Token does not have a kid. 
    Keys tried: '[PII of type 'System.Text.StringBuilder' is hidden. 
        For more details, see https://aka.ms/IdentityModel/PII.]'.
    Number of keys in TokenValidationParameters: '1'. 
    Number of keys in Configuration: '0'. 
    Exceptions caught:
        '[PII of type 'System.Text.StringBuilder' is hidden. 
            For more details, see https://aka.ms/IdentityModel/PII.]'.
        token: '[PII of type 'System.IdentityModel.Tokens.Jwt.JwtSecurityToken' is hidden. 
            For more details, see https://aka.ms/IdentityModel/PII.]'."
}
Run Code Online (Sandbox Code Playgroud)

为什么微软坚持在令牌中包含密钥 ID?有没有办法忽略失踪的人kid

示例令牌(编辑以删除数据):

标头:

{
  "alg": "HS256",
  "typ": "JWT",
  "ver": 1,
  "typ_2": "ref"
}
Run Code Online (Sandbox Code Playgroud)

有效负载:

{
  "jti": "<token_id>",
  "client_id": "<client_id>",
  "client_name": "<client>",
  "ref_token": "<ref_token>",
  "ref_token_type": "Full",
  "zone": "<zone>",
  "endusertype": "system",
  "nbf": 1643639617,
  "exp": 1643643217,
  "iat": 1643639617,
  "iss": "<issuer>"
}
Run Code Online (Sandbox Code Playgroud)

编辑:删除了 IssuerSigningKeys 以避免混淆。

Hau*_*and 2

在验证编码并摸索了相当长一段时间后,我设法联系了外部方,他们确认密钥确实是错误的 - “密钥”仅用于 api 调用,其中消费者请求一个令牌,以“验证”消费者的身份。他们没有kid在 jwt 中包含 a,因为他们不打算让消费者验证令牌。

但这并不能回答问题。