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

Golang中验证无kid字段的JWT令牌问题咨询

验证无kid字段的JWT令牌(golang-jwt/jwt/v4)

你遇到的错误是因为使用的jwks.Keyfunc默认依赖JWT Header中的kid字段去JWKS集合匹配公钥,但你的JWT Header没有该字段,导致匹配失败。

核心解决思路是自定义jwt.Keyfunc函数,根据实际场景处理无kid的情况:

场景1:第三方JWKS仅包含一个RS256公钥

如果确定JWKS里只有一个用于RS256签名的公钥,直接用该公钥验证即可:

import (
    "fmt"
    "github.com/golang-jwt/jwt/v4"
    "crypto/rsa"
)

// 假设已通过JWKS端点或其他方式获取到公钥pubKey(*rsa.PublicKey类型)
tokenParsed, err := jwt.Parse(token, func(token *jwt.Token) (interface{}, error) {
    // 先校验签名算法是否符合预期
    if _, ok := token.Method.(*jwt.SigningMethodRSA); !ok {
        return nil, fmt.Errorf("unexpected signing method: %v", token.Header["alg"])
    }
    // 返回预获取的公钥
    return pubKey, nil
})
if err != nil {
    ch.Log(alog.FATAL, "Failed to parse the JWT.\nError: %s", err.Error())
}

场景2:JWKS包含多个密钥,无kid时使用默认密钥

如果JWKS有多个密钥,且第三方约定无kid时使用默认密钥(比如第一个RS256密钥),可以在Keyfunc中添加无kid的处理逻辑:

import (
    "fmt"
    "github.com/golang-jwt/jwt/v4"
    "github.com/lestrrat-go/jwx/jwks"
)

// 假设已加载JWKS密钥集jwksSet
tokenParsed, err := jwt.Parse(token, func(token *jwt.Token) (interface{}, error) {
    // 校验签名算法
    if _, ok := token.Method.(*jwt.SigningMethodRSA); !ok {
        return nil, fmt.Errorf("unexpected signing method: %v", token.Header["alg"])
    }

    // 尝试获取kid字段
    kid, ok := token.Header["kid"].(string)
    if !ok {
        // 无kid时,查找JWKS中第一个RS256类型的密钥
        for _, key := range jwksSet.Keys() {
            if key.Algorithm() == "RS256" {
                pubKey, err := key.PublicKey()
                if err != nil {
                    return nil, err
                }
                return pubKey, nil
            }
        }
        return nil, fmt.Errorf("no default RS256 key found in JWKS")
    }

    // 有kid时按原逻辑查找密钥
    key, ok := jwksSet.LookupKeyID(kid)
    if !ok {
        return nil, fmt.Errorf("key with kid %s not found", kid)
    }
    pubKey, err := key.PublicKey()
    if err != nil {
        return nil, err
    }
    return pubKey, nil
})
if err != nil {
    ch.Log(alog.FATAL, "Failed to parse the JWT.\nError: %s", err.Error())
}

关键要点

  • 不要直接使用jwks.Keyfunc,而是自己实现jwt.Keyfunc,灵活处理无kid的场景
  • 必须先校验签名算法,避免算法绕过攻击

内容的提问来源于stack exchange,提问作者Shihabudheen K M

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.31 23:39:08