跳到正文
Træfɪk

<span class="nav-link-with-icon">JWT <img src="https://doc.traefik.io/traefik-hub/img/ps-traefik-hub-logo-light.svg" class="menu-icon" alt="Traefik Hub API Gateway"></span>

Traefik Hub 功能

此中间件仅在 Traefik Hub 中提供。了解更多 Traefik Hub 高级功能。

JWT 中间件验证 Authorization 头中是否提供有效的 JWT 令牌(Authorization: Bearer <JWT>)。 如果不能通过 Authorization 头传递令牌,也可以通过表单数据或查询参数提供。 更多信息参阅 tokenKey 选项。

没有特定配置时,JWT 中间件仅验证 JWT 的签名,并检查 nbf、exp 和 iat 标准声明(如果存在)。 可以通过自定义声明验证配置自定义声明的验证规则。


配置示例

apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
  name: test-jwt
spec:
  plugin:
    jwt:
      signingSecret: my-secret
      forwardHeaders:
        Group: grp
        Expires-At: exp
      claims: Equals(`grp`, `admin`)

配置选项

字段 说明 默认值 必填
signingSecret 定义用于签署 JWT 证书的密钥。
中间件随后使用它验证传入请求。
必须至少设置 signingSecret、publicKey、jwksFile 或 jwksUrl 中的一个选项。(更多信息见此处)
"" 否
signingSecretBase64Encoded 定义 signingSecret 是否经过 base64 编码。
设为 true 时,先对 signingSecret 进行 base64 解码,再使用。
false 否
publicKey 定义用于验证传入请求中密钥签名的公钥。
此时,用户应使用与配置公钥对应的私钥签署令牌。
必须至少设置 signingSecret、publicKey、jwksFile 或 jwksUrl 中的一个选项。
"" 否
jwksFile 定义用于验证 JWT 签名的 JWK 集合。
此选项可以是挂载到 API 网关上的文件路径,也可以直接是 JWK 集合文件的内容。
必须至少设置 signingSecret、publicKey、jwksFile 或 jwksUrl 中的一个选项。(更多信息见此处)
"" 否
jwksUrl 定义提供 JWK 集合的主机 URL。
如果 HTTP Cache Control 允许缓存,则会缓存这些密钥。
必须至少设置 signingSecret、publicKey、jwksFile 或 jwksUrl 中的一个选项。
(更多信息见此处)
"" 否
forwardAuthorization 定义请求通过中间件批准后,是转发还是移除其中的认证头。 false 否
tokenKey 定义用于传递 JWT 的查询参数和表单数据参数名称,适用于无法通过 Authorization 头传递 JWT 的应用。
即使启用了此选项,中间件仍会优先查找 Authorization 头。
只有无法通过 Authorization 头传递 JWT 时才应启用此选项,因为 RFC 不建议此做法。
"" 否
claims 定义为授权请求而需要验证的声明。
claims 选项仅可用于 JWT 格式的令牌。(更多信息见此处)
"" 否
usernameClaim 定义需要求值的声明,以填充访问日志中的 clientusername。
usernameClaim 选项仅可用于 JWT 格式的令牌。
"" 否
forwardHeaders 定义要添加到请求中的 HTTP 头,并使用从授权服务器返回的访问令牌声明中提取的值填充。
如果 JWT 中找不到要转发的声明,相应头的值为空。
forwardHeaders 选项仅可用于 JWT 格式的令牌。
{} 否
clientConfig.tls.ca PEM 编码的证书包,或引用包含此证书包的 Secret 的 URN;该证书包用于与授权服务器建立 TLS 连接。(更多信息见此处) "" 否
clientConfig.tls.cert PEM 编码的证书,或引用包含此证书的 Secret 的 URN;该证书用于与 Vault 服务器建立 TLS 连接。(更多信息见此处) "" 否
clientConfig.tls.key PEM 编码的密钥,或引用包含此密钥的 Secret 的 URN;该密钥用于与 Vault 服务器建立 TLS 连接。(更多信息见此处) "" 否
clientConfig.tls.insecureSkipVerify 与授权服务器通信时禁用 TLS 证书验证。
可用于测试,但强烈不建议在生产环境使用。(更多信息见此处)
false 否
clientConfig.timeoutSeconds 定义向授权服务器发出请求后,放弃等待之前的时长。 5 否
clientConfig.maxRetries 定义向授权服务器发送请求失败时的重试次数。 3 否

claims 声明

语法

claims 支持以下函数:

函数 说明 示例
Equals 验证 key 中的值是否等于 value。 Equals(`grp`, `admin`)
Prefix 验证 key 中的值是否以 value 为前缀。 Prefix(`referrer`, `http://example.com`)
Contains(字符串) 验证 key 中的值是否包含 value。 Contains(`referrer`, `/foo/`)
Contains(数组) 验证 key 数组是否包含 value。 Contains(`areas`, `home`)
SplitContains 验证 key 中的值按分隔符拆分后是否包含 value。 SplitContains(`scope`, ` `, `writer`)
OneOf 验证 key 数组是否包含 values 中的任意一个值。 OneOf(`areas`, `office`, `lab`)

所有函数都可以通过布尔运算符连接。支持以下运算符:

运算符 说明 示例
&& 比较两个函数,仅当二者都求值为 true 时返回 true。 Equals(`grp`, `admin`) && Equals(`active`, `true`)
|| 比较两个函数,只要任意一个求值为 true 就返回 true。 Equals(`grp`, `admin`) || Equals(`active`, `true`)
! 函数为 true 时返回 false,否则返回 true。 !Equals(`grp`, `testers`)

对于以下数据结构,所有示例都会返回 true:

{
  "active": true,
  "grp": "admin",
  "scope": "reader writer deploy",
  "referrer": "http://example.com/foo/bar",
  "areas": [
    "office",
    "home"
  ]
}

嵌套声明

在键之间使用 . 可以支持嵌套声明。例如:

user.name
{
  "active": true,
  "grp": "admin",
  "scope": "reader writer deploy",
  "referrer": "http://example.com/foo/bar",
  "areas": [
    "office",
    "home"
  ],
  "user": {
    "name": "John Snow",
    "status": "undead"
  }
}
John Snow

处理包含 '.' 的键

如果 key 包含点号,可以使用 \. 转义。

处理包含 '\' 的键

如果 key 包含 \,则需要写成两个:\\。

clientConfig 客户端配置

定义 API 网关连接身份提供商等第三方软件时使用的配置。

clientConfig.tls TLS 配置

在 Kubernetes Secret 中存储机密值

配置 tls.ca、tls.cert、tls.key 时,可以引用与 Middleware 位于同一命名空间中的 Kubernetes Secret。
Kubernetes Secret 的引用采用 URN 格式:

urn:k8s:secret:[name]:[valueKey]
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
  name: test-jwt
spec:
  plugin:
    jwt:
      clientConfig:
        tls:
          ca: "urn:k8s:secret:tls:ca"
          cert: "urn:k8s:secret:tls:cert"
          key: "urn:k8s:secret:tls:key"
          insecureSkipVerify: true
apiVersion: v1
kind: Secret
metadata:
  name: tls
stringData:
  ca: |-
    -----BEGIN CERTIFICATE-----
    MIIB9TCCAWACAQAwgbgxGTAXBgNVBAoMEFF1b1ZhZGlzIExpbWl0ZWQxHDAaBgNV
    BAsME0RvY3VtZW50IERlcGFydG1lbnQxOTA3BgNVBAMMMFdoeSBhcmUgeW91IGRl
    Y29kaW5nIG1lPyAgVGhpcyBpcyBvbmx5IGEgdGVzdCEhITERMA8GA1UEBwwISGFt
    aWx0b24xETAPBgNVBAgMCFBlbWJyb2tlMQswCQYDVQQGEwJCTTEPMA0GCSqGSIb3
    DQEJARYAMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCJ9WRanG/fUvcfKiGl
    EL4aRLjGt537mZ28UU9/3eiJeJznNSOuNLnF+hmabAu7H0LT4K7EdqfF+XUZW/2j
    RKRYcvOUDGF9A7OjW7UfKk1In3+6QDCi7X34RE161jqoaJjrm/T18TOKcgkkhRzE
    apQnIDm0Ea/HVzX/PiSOGuertwIDAQABMAsGCSqGSIb3DQEBBQOBgQBzMJdAV4QP
    Awel8LzGx5uMOshezF/KfP67wJ93UW+N7zXY6AwPgoLj4Kjw+WtU684JL8Dtr9FX
    ozakE+8p06BpxegR4BR3FMHf6p+0jQxUEAkAyb/mVgm66TyghDGC6/YkiKoZptXQ
    98TwDIK/39WEB/V607As+KoYazQG8drorw==
    -----END CERTIFICATE-----
  cert: |-
    -----BEGIN CERTIFICATE-----
    MIIB9TCCAWACAQAwgbgxGTAXBgNVBAoMEFF1b1ZhZGlzIExpbWl0ZWQxHDAaBgNV
    BAsME0RvY3VtZW50IERlcGFydG1lbnQxOTA3BgNVBAMMMFdoeSBhcmUgeW91IGRl
    Y29kaW5nIG1lPyAgVGhpcyBpcyBvbmx5IGEgdGVzdCEhITERMA8GA1UEBwwISGFt
    aWx0b24xETAPBgNVBAgMCFBlbWJyb2tlMQswCQYDVQQGEwJCTTEPMA0GCSqGSIb3
    DQEJARYAMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCJ9WRanG/fUvcfKiGl
    EL4aRLjGt537mZ28UU9/3eiJeJznNSOuNLnF+hmabAu7H0LT4K7EdqfF+XUZW/2j
    RKRYcvOUDGF9A7OjW7UfKk1In3+6QDCi7X34RE161jqoaJjrm/T18TOKcgkkhRzE
    apQnIDm0Ea/HVzX/PiSOGuertwIDAQABMAsGCSqGSIb3DQEBBQOBgQBzMJdAV4QP
    Awel8LzGx5uMOshezF/KfP67wJ93UW+N7zXY6AwPgoLj4Kjw+WtU684JL8Dtr9FX
    ozakE+8p06BpxegR4BR3FMHf6p+0jQxUEAkAyb/mVgm66TyghDGC6/YkiKoZptXQ
    98TwDIK/39WEB/V607As+KoYazQG8drorw==
    -----END CERTIFICATE-----
  key: |-
    -----BEGIN EC PRIVATE KEY-----
    MHcCAQEEIC8CsJ/B115S+JtR1/l3ZQwKA3XdXt9zLqusF1VXc/KloAoGCCqGSM49
    AwEHoUQDQgAEpwUmRIZHFt8CdDHYm1ikScCScd2q6QVYXxJu+G3fQZ78ScGtN7fu
    KXMnQqVjXVRAr8qUY8yipVKuMCepnPXScQ==
    -----END EC PRIVATE KEY-----

jwksFile JWK 集合文件

JWT 头中的密钥 ID

如果 JWT 头包含 kid 头,中间件预期能找到对应 JWK。 如果找不到 JWK,则返回 401 Unauthorized 错误。

jwksUrl JWK 集合 URL

JWT 头中的密钥 ID

如果 JWT 头包含 kid 头,中间件预期能找到对应 JWK。 如果找不到 JWK,则返回 401 Unauthorized 错误。

JWT 签发者声明

如果 jwksUrl 设置为一个路径,而待验证 JWT 缺少 iss 属性,中间件将返回 401 Unauthorized 错误。

signingSecret 签名密钥

在 Kubernetes Secret 中存储机密值

配置 signingSecret 时,可以引用与 Middleware 位于同一命名空间中的 Kubernetes Secret。 Kubernetes Secret 的引用采用 URN 格式:

urn:k8s:secret:[name]:[valueKey]

在生产环境使用 Traefik OSS?

如果你在工作中使用 Traefik,可以考虑为 Traefik OSS 增加企业级 API 网关能力或商业支持。

为 Traefik OSS 增加 API 网关能力快捷且平滑,无需推倒重来,现有配置也会完整保留。请通过这个简短视频了解实际效果。


版权所有 © 头文件软件工作室

文档由 HeadFile Studio 翻译。

Traefik v3.7 中文快照 · 原文版权归 Traefik Labs 及贡献者所有 · MIT 许可证