跳到主要内容
ecdsa.com
coreos/go-oidc (Go)Go

错误信息

failed to verify signature: failed to verify id token signature

也可能输出为

  • failed to verify signature: fetching keys oidc: get keys failed

如果 JWKS 请求本身失败,文本为“failed to verify signature: fetching keys oidc: get keys failed …”,后面跟着 HTTP 错误或网络错误。

coreos/go-oidc (Go) — IDTokenVerifier.Verify with a RemoteKeySet

含义

go-oidc 下载了提供商的密钥集(如果 `kid` 未知,会重新获取一次),但没有任何已发布的密钥能验证令牌的签名。go-oidc 不区分“没有这个 kid 的密钥”和“有这个 kid 的密钥,但签名不对”——两者都表示令牌不是由该提供商当前发布的密钥签名的。如果根本无法获取密钥集,消息后面接的则是“fetching keys …”。

原因

修复方法

  1. 1.

    基于发现文档构建验证器

    `provider.Verifier` 使用提供商发现文档中的 `jwks_uri` 和提供商的颁发者,这样就排除了手动配置 URL 这一不匹配来源。

    go
    provider, err := oidc.NewProvider(ctx, "https://accounts.example.com") // discovery gives the right jwks_uri
    if err != nil {
    	return err
    }
    verifier := provider.Verifier(&oidc.Config{ClientID: clientID})
    idToken, err := verifier.Verify(ctx, rawIDToken)
  2. 2.

    将令牌的 kid 与已发布的密钥比对

    如果该 `kid` 没有发布,说明令牌来自别处,或者提供商尚未完成密钥轮换。如果已经发布,说明它对应的密钥并没有签名这个令牌。

    bash
    # kid in the token header vs kids the provider publishes
    python3 -c 'import base64,json,sys; h=sys.argv[1].split(".")[0]; print(json.loads(base64.urlsafe_b64decode(h+"="*(-len(h)%4))))' "$ID_TOKEN"
    curl -s "$(curl -s https://accounts.example.com/.well-known/openid-configuration | jq -r .jwks_uri)" | jq '.keys[] | {kid, alg, kty}'

相关错误

浏览完整的签名错误库