跳到主要内容
ecdsa.com
Envoy / IstioJWKS 与密钥发现

错误信息

Jwks doesn't have key to match kid or alg from Jwt

也可能输出为

  • Jwt verification fails
  • Jwks remote fetch is failed

这是 401 的响应体;`WWW-Authenticate` 响应头携带 `error="invalid_token"`。如果某个提供方的 `remote_jwks` 无法获取,响应则是“Jwks remote fetch is failed”。

Envoy / Istio — envoy.filters.http.jwt_authn (401 response body; Istio RequestAuthentication)

含义

Envoy 的 `jwt_authn` 过滤器(Istio 的 `RequestAuthentication` 也使用它)在提供方的 JWKS 中查找 `kid` 与令牌相同、类型与其 `alg` 相符的密钥,但没有找到,于是返回 401,并以这段文本作为响应体。签名根本没有被检查。如果存在匹配的密钥但签名验证失败,响应体则是“Jwt verification fails”。

原因

修复方法

  1. 1.

    从颁发者获取 JWKS

    使用 `remote_jwks`,配合合理的 `cache_duration` 和异步获取,使密钥在令牌用到之前就已就绪。

    yaml
    providers:
      issuer_example:
        issuer: https://issuer.example.com
        audiences: ["api://orders"]
        remote_jwks:
          http_uri:
            uri: https://issuer.example.com/.well-known/jwks.json
            cluster: issuer_jwks          # a cluster with TLS to the issuer
            timeout: 5s
          cache_duration: 600s
          async_fetch: { fast_listener: false }   # prefetch, and refetch in the background
  2. 2.

    在 Istio 中指向 jwksUri

    Istiod 会获取并推送密钥;内联的 `jwks` 值则必须在每次轮换时手动更新。

    yaml
    apiVersion: security.istio.io/v1
    kind: RequestAuthentication
    metadata:
      name: orders-jwt
    spec:
      selector:
        matchLabels: { app: orders }
      jwtRules:
      - issuer: https://issuer.example.com
        jwksUri: https://issuer.example.com/.well-known/jwks.json   # not an inline "jwks:" copy

相关错误

浏览完整的签名错误库