From aa4882b73b13ed230c83efef6cc435b026f75018 Mon Sep 17 00:00:00 2001 From: Yilia Lin Date: Fri, 17 Apr 2026 15:12:21 +0800 Subject: [PATCH 1/8] docs(jwe-decrypt): re-port with Admin API, ADC, and Ingress Controller tabs --- docs/en/latest/plugins/jwe-decrypt.md | 386 ++++++++++++++++++------- docs/zh/latest/plugins/jwe-decrypt.md | 387 +++++++++++++++++++------- 2 files changed, 580 insertions(+), 193 deletions(-) diff --git a/docs/en/latest/plugins/jwe-decrypt.md b/docs/en/latest/plugins/jwe-decrypt.md index 3e55a316fdd9..0ed3bf3eb41e 100644 --- a/docs/en/latest/plugins/jwe-decrypt.md +++ b/docs/en/latest/plugins/jwe-decrypt.md @@ -6,7 +6,7 @@ keywords: - Plugin - JWE Decrypt - jwe-decrypt -description: This document contains information about the Apache APISIX jwe-decrypt Plugin. +description: The jwe-decrypt Plugin decrypts JWE authorization headers in requests directed to Routes or Services, enhancing API security. --- + + + + +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; + ## Description -The `jwe-decrypt` Plugin is used to decrypt [JWE](https://datatracker.ietf.org/doc/html/rfc7516) authorization headers in requests to an APISIX [Service](../terminology/service.md) or [Route](../terminology/route.md). +The `jwe-decrypt` Plugin decrypts [JWE](https://datatracker.ietf.org/doc/html/rfc7516) authorization headers in requests sent to APISIX [Routes](../terminology/route.md) or [Services](../terminology/service.md). This Plugin adds an endpoint `/apisix/plugin/jwe/encrypt` for JWE encryption. For decryption, the key should be configured in [Consumer](../terminology/consumer.md). ## Attributes -For Consumer: - -| Name | Type | Required | Default | Valid values | Description | -|---------------|---------|-------------------------------------------------------|---------|-----------------------------|----------------------------------------------------------------------------------------------------------------------------------------------| -| key | string | True | | | Unique key for a Consumer. | -| secret | string | True | | | The decryption key. Must be 32 characters. The key could be saved in a secret manager using the [Secret](../terminology/secret.md) resource. | -| is_base64_encoded | boolean | False | false | | Set to true if the secret is base64 encoded. | - -:::note - -After enabling `is_base64_encoded`, your `secret` length may exceed 32 chars. You only need to make sure that the length after decoding is still 32 chars. +### Consumer -::: +| Name | Type | Required | Default | Valid values | Description | +| ----------------- | ------- | -------- | ------- | -------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| key | string | True | | | A unique key that identifies the Credential for a Consumer. | +| secret | string | True | | 32 characters | The encryption key. You can also store it in an environment variable and reference it using the `env://` prefix, or in a secret manager such as HashiCorp Vault's KV secrets engine, and reference it using the `secret://` prefix. | +| is_base64_encoded | boolean | False | false | | Set to true if the secret is base64 encoded. Note that after enabling `is_base64_encoded`, the `secret` length may exceed 32 characters. You only need to make sure the decoded length is still 32 characters. | -For Route: +### Route or Service -| Name | Type | Required | Default | Description | -|--------|--------|----------|---------------|---------------------------------------------------------------------| -| header | string | True | Authorization | The header to get the token from. | -| forward_header | string | True | Authorization | Set the header name that passes the plaintext to the Upstream. | -| strict | boolean | False | true | If true, throw a 403 error if JWE token is missing from the request. If false, do not throw an error if JWE token cannot be found. | +| Name | Type | Required | Default | Valid values | Description | +| -------------- | ------- | -------- | ------------- | ------------ | --------------------------------------------------------------------------------------------------------------------------------- | +| header | string | True | Authorization | | The header to get the token from. | +| forward_header | string | True | Authorization | | Name of the header that passes the plaintext to the Upstream. | +| strict | boolean | False | true | | If true, throw a 403 error if JWE token is missing from the request. If false, do not throw an error when JWE token is not found. | -## Example usage +## Examples -First, create a Consumer with `jwe-decrypt` and configure the decryption key: +The examples below demonstrate how you can work with the `jwe-decrypt` Plugin for different scenarios. :::note + You can fetch the `admin_key` from `config.yaml` and save to an environment variable with the following command: ```bash -admin_key=$(yq '.deployment.admin.admin_key[0].key' conf/config.yaml | sed 's/"//g') +admin_key=$(yq '.deployment.admin.admin_key[0].key' /usr/local/apisix/conf/config.yaml | sed 's/"//g') ``` ::: +### Expose JWE Encryption Endpoint and Generate JWE Token + +The following example demonstrates how to expose the JWE encryption endpoint and generate a JWE token. + +The `jwe-decrypt` Plugin creates an internal endpoint at `/apisix/plugin/jwe/encrypt` to encrypt JWE. Expose the endpoint with the [public-api](public-api.md) Plugin: + + + + ```shell -curl http://127.0.0.1:9180/apisix/admin/consumers -H "X-API-KEY: $admin_key" -X PUT -d ' -{ - "username": "jack", +curl "http://127.0.0.1:9180/apisix/admin/routes/jwe-encrypt-api" -X PUT \ + -H "X-API-KEY: ${admin_key}" \ + -d '{ + "uri": "/apisix/plugin/jwe/encrypt", "plugins": { - "jwe-decrypt": { - "key": "user-key", - "secret": "-secret-length-must-be-32-chars-" - } + "public-api": {} } -}' + }' ``` -Next, create a Route with `jwe-decrypt` enabled to decrypt the authorization header: +Create a Consumer with `jwe-decrypt` and configure the decryption key: ```shell -curl http://127.0.0.1:9180/apisix/admin/routes/1 -H "X-API-KEY: $admin_key" -X PUT -d ' -{ - "methods": ["GET"], - "uri": "/anything*", +curl "http://127.0.0.1:9180/apisix/admin/consumers" -X PUT \ + -H "X-API-KEY: ${admin_key}" \ + -d '{ + "username": "jack", "plugins": { - "jwe-decrypt": {} - }, - "upstream": { - "type": "roundrobin", - "nodes": { - "httpbin.org:80": 1 - } + "jwe-decrypt": { + "key": "jack-key", + "secret": "key-length-should-be-32-chars123" + } } -}' + }' ``` -### Encrypt Data with JWE + + + + +Expose the JWE encryption endpoint and create a Consumer with `jwe-decrypt` Credential: + +```yaml title="adc.yaml" +consumers: + - username: jack + plugins: + jwe-decrypt: + key: jack-key + secret: key-length-should-be-32-chars123 +services: + - name: jwe-encrypt-api-service + routes: + - name: jwe-encrypt-api-route + uris: + - /apisix/plugin/jwe/encrypt + plugins: + public-api: {} + upstream: + type: roundrobin + nodes: + - host: httpbin.org + port: 80 + weight: 1 +``` -The Plugin creates an internal endpoint `/apisix/plugin/jwe/encrypt` to encrypt data with JWE. To expose it publicly, create a Route with the [public-api](public-api.md) Plugin: +Synchronize the configuration to the gateway: ```shell -curl http://127.0.0.1:9180/apisix/admin/routes/jwenew -H "X-API-KEY: $admin_key" -X PUT -d ' -{ - "uri": "/apisix/plugin/jwe/encrypt", - "plugins": { - "public-api": {} - } -}' +adc sync -f adc.yaml +``` + + + + + +Create a Consumer with `jwe-decrypt` and expose the JWE encryption endpoint with the `public-api` Plugin: + + + + +```yaml title="jwe-encrypt-api-ic.yaml" +apiVersion: apisix.apache.org/v1alpha1 +kind: Consumer +metadata: + namespace: aic + name: jack +spec: + gatewayRef: + name: apisix + plugins: + - name: jwe-decrypt + config: + key: jack-key + secret: key-length-should-be-32-chars123 +--- +apiVersion: apisix.apache.org/v1alpha1 +kind: PluginConfig +metadata: + namespace: aic + name: jwe-encrypt-api-plugin-config +spec: + plugins: + - name: public-api + config: + _meta: + disable: false +--- +apiVersion: gateway.networking.k8s.io/v1 +kind: HTTPRoute +metadata: + namespace: aic + name: jwe-encrypt-api-route +spec: + parentRefs: + - name: apisix + rules: + - matches: + - path: + type: Exact + value: /apisix/plugin/jwe/encrypt + filters: + - type: ExtensionRef + extensionRef: + group: apisix.apache.org + kind: PluginConfig + name: jwe-encrypt-api-plugin-config ``` -Send a request to the endpoint passing the key configured in Consumer to the URI parameter to encrypt some sample data in the payload: +Apply the configuration to your cluster: ```shell -curl -G --data-urlencode 'payload={"uid":10000,"uname":"test"}' 'http://127.0.0.1:9080/apisix/plugin/jwe/encrypt?key=user-key' -i +kubectl apply -f jwe-encrypt-api-ic.yaml ``` -You should see a response similar to the following, with the JWE encrypted data in the response body: + + + +`ApisixConsumer` only supports authentication plugins via the `authParameter` field, and `jwe-decrypt` is not among the supported types. This example cannot be completed using the APISIX Ingress Controller. + + + + + + + +Send a request to the encryption endpoint with Consumer key to encrypt some sample data in the payload: + +```shell +curl "http://127.0.0.1:9080/apisix/plugin/jwe/encrypt?key=jack-key" \ + -d 'payload={"uid":10000,"uname":"test"}' -G ``` -HTTP/1.1 200 OK -Date: Mon, 25 Sep 2023 02:38:16 GMT -Content-Type: text/plain; charset=utf-8 -Transfer-Encoding: chunked -Connection: keep-alive -Server: APISIX/3.5.0 -Apisix-Plugins: public-api -eyJhbGciOiJkaXIiLCJraWQiOiJ1c2VyLWtleSIsImVuYyI6IkEyNTZHQ00ifQ..MTIzNDU2Nzg5MDEy.hfzMJ0YfmbMcJ0ojgv4PYAHxPjlgMivmv35MiA.7nilnBt2dxLR_O6kf-HQUA +You should see a response similar to the following, with the JWE encrypted data in the response body: + +```text +eyJraWQiOiJqYWNrLWtleSIsImFsZyI6ImRpciIsImVuYyI6IkEyNTZHQ00ifQ..MTIzNDU2Nzg5MDEy.IUFW_q4igO_wvf63i-3VwV0MEetPL9C20tlgcQ.fveViMUi0ijJlQ19D7kDrg ``` ### Decrypt Data with JWE -Send a request to the route with the JWE encrypted data in the `Authorization` header: +The following example demonstrates how to decrypt the previously generated JWE token. + +Create a Route with `jwe-decrypt` to decrypt the authorization header: + + + ```shell -curl http://127.0.0.1:9080/anything/hello -H 'Authorization: eyJhbGciOiJkaXIiLCJraWQiOiJ1c2VyLWtleSIsImVuYyI6IkEyNTZHQ00ifQ..MTIzNDU2Nzg5MDEy.hfzMJ0YfmbMcJ0ojgv4PYAHxPjlgMivmv35MiA.7nilnBt2dxLR_O6kf-HQUA' -i +curl "http://127.0.0.1:9180/apisix/admin/routes" -X PUT \ + -H "X-API-KEY: ${admin_key}" \ + -d '{ + "id": "jwe-decrypt-route", + "uri": "/anything/jwe", + "plugins": { + "jwe-decrypt": { + "header": "Authorization", + "forward_header": "Authorization" + } + }, + "upstream": { + "type": "roundrobin", + "nodes": { + "httpbin.org:80": 1 + } + } + }' ``` -You should see a response similar to the following, where the `Authorization` header shows the plaintext of the payload: + + + + +```yaml title="adc.yaml" +services: + - name: jwe-decrypt-service + routes: + - name: jwe-decrypt-route + uris: + - /anything/jwe + plugins: + jwe-decrypt: + header: Authorization + forward_header: Authorization + upstream: + type: roundrobin + nodes: + - host: httpbin.org + port: 80 + weight: 1 +``` + +Synchronize the configuration to the gateway: + +```shell +adc sync -f adc.yaml +``` + + + + + + + + +```yaml title="jwe-decrypt-ic.yaml" +apiVersion: v1 +kind: Service +metadata: + namespace: aic + name: httpbin-external-domain +spec: + type: ExternalName + externalName: httpbin.org +--- +apiVersion: apisix.apache.org/v1alpha1 +kind: PluginConfig +metadata: + namespace: aic + name: jwe-decrypt-plugin-config +spec: + plugins: + - name: jwe-decrypt + config: + header: Authorization + forward_header: Authorization +--- +apiVersion: gateway.networking.k8s.io/v1 +kind: HTTPRoute +metadata: + namespace: aic + name: jwe-decrypt-route +spec: + parentRefs: + - name: apisix + rules: + - matches: + - path: + type: Exact + value: /anything/jwe + filters: + - type: ExtensionRef + extensionRef: + group: apisix.apache.org + kind: PluginConfig + name: jwe-decrypt-plugin-config + backendRefs: + - name: httpbin-external-domain + port: 80 +``` + +Apply the configuration to your cluster: + +```shell +kubectl apply -f jwe-decrypt-ic.yaml +``` + + + + + +`ApisixConsumer` only supports authentication plugins via the `authParameter` field, and `jwe-decrypt` is not among the supported types. This example cannot be completed using the APISIX Ingress Controller. + + + + + + +Send a request to the Route with the JWE encrypted data in the `Authorization` header: + +```shell +curl "http://127.0.0.1:9080/anything/jwe" -H 'Authorization: eyJraWQiOiJqYWNrLWtleSIsImFsZyI6ImRpciIsImVuYyI6IkEyNTZHQ00ifQ..MTIzNDU2Nzg5MDEy.IUFW_q4igO_wvf63i-3VwV0MEetPL9C20tlgcQ.fveViMUi0ijJlQ19D7kDrg' ``` -HTTP/1.1 200 OK -Content-Type: application/json -Content-Length: 452 -Connection: keep-alive -Date: Mon, 25 Sep 2023 02:38:59 GMT -Access-Control-Allow-Origin: * -Access-Control-Allow-Credentials: true -Server: APISIX/3.5.0 -Apisix-Plugins: jwe-decrypt +You should see a response similar to the following, where the `Authorization` header shows the plaintext of the payload: + +```json { "args": {}, "data": "", @@ -174,25 +387,6 @@ Apisix-Plugins: jwe-decrypt "json": null, "method": "GET", "origin": "127.0.0.1, 119.143.79.94", - "url": "http://127.0.0.1/anything/hello" + "url": "http://127.0.0.1/anything/jwe" } ``` - -## Delete Plugin - -To remove the `jwe-decrypt` Plugin, you can delete the corresponding JSON configuration from the Plugin configuration. APISIX will automatically reload and you do not have to restart for this to take effect. - -```shell -curl http://127.0.0.1:9180/apisix/admin/routes/1 -H "X-API-KEY: $admin_key" -X PUT -d ' -{ - "methods": ["GET"], - "uri": "/anything*", - "plugins": {}, - "upstream": { - "type": "roundrobin", - "nodes": { - "httpbin.org:80": 1 - } - } -}' -``` diff --git a/docs/zh/latest/plugins/jwe-decrypt.md b/docs/zh/latest/plugins/jwe-decrypt.md index b3bc92fb5432..dbcc65e7c1e9 100644 --- a/docs/zh/latest/plugins/jwe-decrypt.md +++ b/docs/zh/latest/plugins/jwe-decrypt.md @@ -6,7 +6,7 @@ keywords: - APISIX 插件 - JWE Decrypt - jwe-decrypt -description: 本文档包含了关于 APISIX jwe-decrypt 插件的相关信息。 +description: jwe-decrypt 插件解密发送到路由或服务的请求中的 JWE 授权请求头,增强 API 安全性。 --- -## 描述 - -`jwe-decrypt` 插件,用于解密 APISIX [Service](../terminology/service.md) 或者 [Route](../terminology/route.md) 请求中的 [JWE](https://datatracker.ietf.org/doc/html/rfc7516) 授权请求头。 + + + -插件增加了一个 `/apisix/plugin/jwe/encrypt` 的内部 API,提供给 JWE 加密使用。解密时,秘钥应该配置在 [Consumer](../terminology/consumer.md)内。 +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; -## 属性 +## 描述 -Consumer 配置: +`jwe-decrypt` 插件解密发送到 APISIX [路由](../terminology/route.md)或[服务](../terminology/service.md)的请求中的 [JWE](https://datatracker.ietf.org/doc/html/rfc7516) 授权请求头。 -| 名称 | 类型 | 必选项 | 默认值 | 有效值 | 描述 | -|---------------|---------|-------|-------|-----|-------------------------------------------------------------| -| key | string | True | | | Consumer 的唯一 key | -| secret | string | True | | | 解密密钥,必须为 32 位。秘钥可以使用 [Secret](../terminology/secret.md) 资源保存在密钥管理服务中 | -| is_base64_encoded | boolean | False | false | | 如果密钥是 Base64 编码,则需要配置为 `true` | +该插件添加了一个 `/apisix/plugin/jwe/encrypt` 内部端点用于 JWE 加密。解密时,密钥应配置在[消费者](../terminology/consumer.md)中。 -:::note +## 属性 -注意,在启用 `is_base64_encoded` 后,你的 `secret` 长度可能会超过 32 位,你只需要保证在 Decode 后的长度仍然是 32 位即可。 +### 消费者 -::: +| 名称 | 类型 | 必选项 | 默认值 | 有效值 | 描述 | +| ----------------- | ------- | ------ | ------ | --------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| key | string | 是 | | | 用于标识消费者凭证的唯一密钥。 | +| secret | string | 是 | | 32 个字符 | 加密密钥。也可以将其存储在环境变量中并使用 `env://` 前缀引用,或存储在 HashiCorp Vault 的 KV 密钥引擎等密钥管理器中并使用 `secret://` 前缀引用。启用 `is_base64_encoded` 后,`secret` 长度可能超过 32 个字符,只需确保解码后长度仍为 32 个字符即可。 | +| is_base64_encoded | boolean | 否 | false | | 如果密钥为 Base64 编码,则设置为 true。 | -Route 配置: +### 路由或服务 -| 名称 | 类型 | 必选项 | 默认值 | 描述 | -|----------------|---------|-------|---------------|----------------------------------------------------------------------------| -| header | string | True | Authorization | 指定请求头,用于获取加密令牌 | -| forward_header | string | True | Authorization | 传递给 Upstream 的请求头名称 | -| strict | boolean | False | true | 如果为配置为 true,请求中缺失 JWE token 则抛出 `403` 异常。如果为 `false`, 在缺失 JWE token 的情况下不会抛出异常 | +| 名称 | 类型 | 必选项 | 默认值 | 有效值 | 描述 | +| -------------- | ------- | ------ | ------------- | ------ | ---------------------------------------------------------------------------------------------- | +| header | string | 是 | Authorization | | 用于获取令牌的请求头。 | +| forward_header | string | 是 | Authorization | | 传递明文给上游的请求头名称。 | +| strict | boolean | 否 | true | | 如果为 true,当请求中缺少 JWE 令牌时抛出 403 错误。如果为 false,当找不到 JWE 令牌时不抛出错误。 | -## 启用插件 +## 使用示例 -首先,基于 `jwe-decrypt` 插件创建一个 Consumer,并且配置解密密钥: +以下示例演示了如何针对不同场景使用 `jwe-decrypt` 插件。 :::note 您可以这样从 `config.yaml` 中获取 `admin_key` 并存入环境变量: ```bash -admin_key=$(yq '.deployment.admin.admin_key[0].key' conf/config.yaml | sed 's/"//g') +admin_key=$(yq '.deployment.admin.admin_key[0].key' /usr/local/apisix/conf/config.yaml | sed 's/"//g') ``` ::: +### 暴露 JWE 加密端点并生成 JWE 令牌 + +以下示例演示如何暴露 JWE 加密端点并生成 JWE 令牌。 + +`jwe-decrypt` 插件在 `/apisix/plugin/jwe/encrypt` 创建一个内部端点用于 JWE 加密。使用 [public-api](public-api.md) 插件暴露该端点: + + + + ```shell -curl http://127.0.0.1:9180/apisix/admin/consumers -H "X-API-KEY: $admin_key" -X PUT -d ' -{ - "username": "jack", +curl "http://127.0.0.1:9180/apisix/admin/routes/jwe-encrypt-api" -X PUT \ + -H "X-API-KEY: ${admin_key}" \ + -d '{ + "uri": "/apisix/plugin/jwe/encrypt", "plugins": { - "jwe-decrypt": { - "key": "user-key", - "secret": "-secret-length-must-be-32-chars-" - } + "public-api": {} } -}' + }' ``` -下一步,基于 `jwe-decrypt` 插件创建一个路由,用于解密 authorization 请求头: +创建带有 `jwe-decrypt` 的消费者并配置解密密钥: ```shell -curl http://127.0.0.1:9180/apisix/admin/routes/1 -H "X-API-KEY: $admin_key" -X PUT -d ' -{ - "methods": ["GET"], - "uri": "/anything*", +curl "http://127.0.0.1:9180/apisix/admin/consumers" -X PUT \ + -H "X-API-KEY: ${admin_key}" \ + -d '{ + "username": "jack", "plugins": { - "jwe-decrypt": {} - }, - "upstream": { - "type": "roundrobin", - "nodes": { - "httpbin.org:80": 1 - } + "jwe-decrypt": { + "key": "jack-key", + "secret": "key-length-should-be-32-chars123" + } } -}' + }' ``` -### 使用 JWE 加密数据 + + + + +暴露 JWE 加密端点并创建带有 `jwe-decrypt` 凭证的消费者: + +```yaml title="adc.yaml" +consumers: + - username: jack + plugins: + jwe-decrypt: + key: jack-key + secret: key-length-should-be-32-chars123 +services: + - name: jwe-encrypt-api-service + routes: + - name: jwe-encrypt-api-route + uris: + - /apisix/plugin/jwe/encrypt + plugins: + public-api: {} + upstream: + type: roundrobin + nodes: + - host: httpbin.org + port: 80 + weight: 1 +``` -该插件创建了一个内部的 API `/apisix/plugin/jwe/encrypt` 以使用 JWE 进行加密。要公开它,需要创建一个对应的路由,并启用 [public-api](public-api.md) 插件: +将配置同步到网关: ```shell -curl http://127.0.0.1:9180/apisix/admin/routes/jwenew -H "X-API-KEY: $admin_key" -X PUT -d ' -{ - "uri": "/apisix/plugin/jwe/encrypt", - "plugins": { - "public-api": {} - } -}' +adc sync -f adc.yaml +``` + + + + + +创建带有 `jwe-decrypt` 的消费者并使用 `public-api` 插件暴露 JWE 加密端点: + + + + +```yaml title="jwe-encrypt-api-ic.yaml" +apiVersion: apisix.apache.org/v1alpha1 +kind: Consumer +metadata: + namespace: aic + name: jack +spec: + gatewayRef: + name: apisix + plugins: + - name: jwe-decrypt + config: + key: jack-key + secret: key-length-should-be-32-chars123 +--- +apiVersion: apisix.apache.org/v1alpha1 +kind: PluginConfig +metadata: + namespace: aic + name: jwe-encrypt-api-plugin-config +spec: + plugins: + - name: public-api + config: + _meta: + disable: false +--- +apiVersion: gateway.networking.k8s.io/v1 +kind: HTTPRoute +metadata: + namespace: aic + name: jwe-encrypt-api-route +spec: + parentRefs: + - name: apisix + rules: + - matches: + - path: + type: Exact + value: /apisix/plugin/jwe/encrypt + filters: + - type: ExtensionRef + extensionRef: + group: apisix.apache.org + kind: PluginConfig + name: jwe-encrypt-api-plugin-config ``` -向 API 发送一个请求,将 Consumer 中配置的密钥,以参数的方式传递给 URI,用于加密 payload 中的一些数据。 +将配置应用到集群: ```shell -curl -G --data-urlencode 'payload={"uid":10000,"uname":"test"}' 'http://127.0.0.1:9080/apisix/plugin/jwe/encrypt?key=user-key' -i +kubectl apply -f jwe-encrypt-api-ic.yaml ``` -您应该看到类似于如下内容的响应结果,其中 JWE 加密的数据位于响应体中: + + + +`ApisixConsumer` 仅通过 `authParameter` 字段支持认证插件,而 `jwe-decrypt` 不在支持的类型中。此示例无法使用 APISIX Ingress Controller 完成。 + + + + + + + +向加密端点发送请求,使用消费者密钥加密 payload 中的示例数据: + +```shell +curl "http://127.0.0.1:9080/apisix/plugin/jwe/encrypt?key=jack-key" \ + -d 'payload={"uid":10000,"uname":"test"}' -G ``` -HTTP/1.1 200 OK -Date: Mon, 25 Sep 2023 02:38:16 GMT -Content-Type: text/plain; charset=utf-8 -Transfer-Encoding: chunked -Connection: keep-alive -Server: APISIX/3.5.0 -Apisix-Plugins: public-api -eyJhbGciOiJkaXIiLCJraWQiOiJ1c2VyLWtleSIsImVuYyI6IkEyNTZHQ00ifQ..MTIzNDU2Nzg5MDEy.hfzMJ0YfmbMcJ0ojgv4PYAHxPjlgMivmv35MiA.7nilnBt2dxLR_O6kf-HQUA +您应该看到类似以下的响应,响应体中包含 JWE 加密数据: + +```text +eyJraWQiOiJqYWNrLWtleSIsImFsZyI6ImRpciIsImVuYyI6IkEyNTZHQ00ifQ..MTIzNDU2Nzg5MDEy.IUFW_q4igO_wvf63i-3VwV0MEetPL9C20tlgcQ.fveViMUi0ijJlQ19D7kDrg ``` ### 使用 JWE 解密数据 -将加密数据放在 `Authorization` 请求头中,向 API 发起请求: +以下示例演示如何解密上述生成的 JWE 令牌。 + +创建带有 `jwe-decrypt` 的路由以解密授权请求头: + + + ```shell -curl http://127.0.0.1:9080/anything/hello -H 'Authorization: eyJhbGciOiJkaXIiLCJraWQiOiJ1c2VyLWtleSIsImVuYyI6IkEyNTZHQ00ifQ..MTIzNDU2Nzg5MDEy.hfzMJ0YfmbMcJ0ojgv4PYAHxPjlgMivmv35MiA.7nilnBt2dxLR_O6kf-HQUA' -i +curl "http://127.0.0.1:9180/apisix/admin/routes" -X PUT \ + -H "X-API-KEY: ${admin_key}" \ + -d '{ + "id": "jwe-decrypt-route", + "uri": "/anything/jwe", + "plugins": { + "jwe-decrypt": { + "header": "Authorization", + "forward_header": "Authorization" + } + }, + "upstream": { + "type": "roundrobin", + "nodes": { + "httpbin.org:80": 1 + } + } + }' +``` + + + + + +```yaml title="adc.yaml" +services: + - name: jwe-decrypt-service + routes: + - name: jwe-decrypt-route + uris: + - /anything/jwe + plugins: + jwe-decrypt: + header: Authorization + forward_header: Authorization + upstream: + type: roundrobin + nodes: + - host: httpbin.org + port: 80 + weight: 1 +``` + +将配置同步到网关: + +```shell +adc sync -f adc.yaml +``` + + + + + + + + +```yaml title="jwe-decrypt-ic.yaml" +apiVersion: v1 +kind: Service +metadata: + namespace: aic + name: httpbin-external-domain +spec: + type: ExternalName + externalName: httpbin.org +--- +apiVersion: apisix.apache.org/v1alpha1 +kind: PluginConfig +metadata: + namespace: aic + name: jwe-decrypt-plugin-config +spec: + plugins: + - name: jwe-decrypt + config: + header: Authorization + forward_header: Authorization +--- +apiVersion: gateway.networking.k8s.io/v1 +kind: HTTPRoute +metadata: + namespace: aic + name: jwe-decrypt-route +spec: + parentRefs: + - name: apisix + rules: + - matches: + - path: + type: Exact + value: /anything/jwe + filters: + - type: ExtensionRef + extensionRef: + group: apisix.apache.org + kind: PluginConfig + name: jwe-decrypt-plugin-config + backendRefs: + - name: httpbin-external-domain + port: 80 +``` + +将配置应用到集群: + +```shell +kubectl apply -f jwe-decrypt-ic.yaml ``` -您应该可以看到类似于如下的响应内容,其中 `Authorization` 响应头显示了有效的解密内容: + + + + +`ApisixConsumer` 仅通过 `authParameter` 字段支持认证插件,而 `jwe-decrypt` 不在支持的类型中。此示例无法使用 APISIX Ingress Controller 完成。 + + + + + + +在 `Authorization` 请求头中携带 JWE 加密数据向路由发送请求: + +```shell +curl "http://127.0.0.1:9080/anything/jwe" -H 'Authorization: eyJraWQiOiJqYWNrLWtleSIsImFsZyI6ImRpciIsImVuYyI6IkEyNTZHQ00ifQ..MTIzNDU2Nzg5MDEy.IUFW_q4igO_wvf63i-3VwV0MEetPL9C20tlgcQ.fveViMUi0ijJlQ19D7kDrg' ``` -HTTP/1.1 200 OK -Content-Type: application/json -Content-Length: 452 -Connection: keep-alive -Date: Mon, 25 Sep 2023 02:38:59 GMT -Access-Control-Allow-Origin: * -Access-Control-Allow-Credentials: true -Server: APISIX/3.5.0 -Apisix-Plugins: jwe-decrypt +您应该看到类似以下的响应,其中 `Authorization` 请求头显示了 payload 的明文: + +```json { "args": {}, "data": "", @@ -175,25 +387,6 @@ Apisix-Plugins: jwe-decrypt "json": null, "method": "GET", "origin": "127.0.0.1, 119.143.79.94", - "url": "http://127.0.0.1/anything/hello" + "url": "http://127.0.0.1/anything/jwe" } ``` - -## 删除插件 - -要删除 `jwe-decrypt` 插件,您可以从插件配置中删除插件对应的 JSON 配置,APISIX 会自动加载,您不需要重新启动即可生效。 - -```shell -curl http://127.0.0.1:9180/apisix/admin/routes/1 -H "X-API-KEY: $admin_key" -X PUT -d ' -{ - "methods": ["GET"], - "uri": "/anything*", - "plugins": {}, - "upstream": { - "type": "roundrobin", - "nodes": { - "httpbin.org:80": 1 - } - } -}' -``` From 63ceee3f5c1231295d186b410c0b9758281434b2 Mon Sep 17 00:00:00 2001 From: Yilia Lin <114121331+Yilialinn@users.noreply.github.com> Date: Fri, 17 Apr 2026 18:28:39 +0800 Subject: [PATCH 2/8] Update docs/zh/latest/plugins/jwe-decrypt.md Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- docs/zh/latest/plugins/jwe-decrypt.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/zh/latest/plugins/jwe-decrypt.md b/docs/zh/latest/plugins/jwe-decrypt.md index dbcc65e7c1e9..7faa1659b798 100644 --- a/docs/zh/latest/plugins/jwe-decrypt.md +++ b/docs/zh/latest/plugins/jwe-decrypt.md @@ -223,7 +223,7 @@ kubectl apply -f jwe-encrypt-api-ic.yaml ```shell curl "http://127.0.0.1:9080/apisix/plugin/jwe/encrypt?key=jack-key" \ - -d 'payload={"uid":10000,"uname":"test"}' -G + --data-urlencode 'payload={"uid":10000,"uname":"test"}' -G ``` 您应该看到类似以下的响应,响应体中包含 JWE 加密数据: From 701946b10e2f35ebba746d8f5742477bebea4847 Mon Sep 17 00:00:00 2001 From: Yilia Lin <114121331+Yilialinn@users.noreply.github.com> Date: Fri, 17 Apr 2026 18:28:49 +0800 Subject: [PATCH 3/8] Update docs/en/latest/plugins/jwe-decrypt.md Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- docs/en/latest/plugins/jwe-decrypt.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/en/latest/plugins/jwe-decrypt.md b/docs/en/latest/plugins/jwe-decrypt.md index 0ed3bf3eb41e..c2777e467239 100644 --- a/docs/en/latest/plugins/jwe-decrypt.md +++ b/docs/en/latest/plugins/jwe-decrypt.md @@ -68,7 +68,7 @@ The examples below demonstrate how you can work with the `jwe-decrypt` Plugin fo You can fetch the `admin_key` from `config.yaml` and save to an environment variable with the following command: ```bash -admin_key=$(yq '.deployment.admin.admin_key[0].key' /usr/local/apisix/conf/config.yaml | sed 's/"//g') +admin_key=$(yq '.deployment.admin.admin_key[0].key' conf/config.yaml | sed 's/"//g') ``` ::: From d4c68ea0ae068fa634256c1ffae9f246765caf0e Mon Sep 17 00:00:00 2001 From: Yilia Lin <114121331+Yilialinn@users.noreply.github.com> Date: Fri, 17 Apr 2026 18:29:05 +0800 Subject: [PATCH 4/8] Update docs/en/latest/plugins/jwe-decrypt.md Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- docs/en/latest/plugins/jwe-decrypt.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/en/latest/plugins/jwe-decrypt.md b/docs/en/latest/plugins/jwe-decrypt.md index c2777e467239..aadd30d6cd4a 100644 --- a/docs/en/latest/plugins/jwe-decrypt.md +++ b/docs/en/latest/plugins/jwe-decrypt.md @@ -223,7 +223,7 @@ Send a request to the encryption endpoint with Consumer key to encrypt some samp ```shell curl "http://127.0.0.1:9080/apisix/plugin/jwe/encrypt?key=jack-key" \ - -d 'payload={"uid":10000,"uname":"test"}' -G + --data-urlencode 'payload={"uid":10000,"uname":"test"}' -G ``` You should see a response similar to the following, with the JWE encrypted data in the response body: From fb991cbfb682ab0288634a72b620cc512d6b3be9 Mon Sep 17 00:00:00 2001 From: Yilia Lin <114121331+Yilialinn@users.noreply.github.com> Date: Fri, 17 Apr 2026 18:29:34 +0800 Subject: [PATCH 5/8] Update docs/zh/latest/plugins/jwe-decrypt.md Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- docs/zh/latest/plugins/jwe-decrypt.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/zh/latest/plugins/jwe-decrypt.md b/docs/zh/latest/plugins/jwe-decrypt.md index 7faa1659b798..f03d29a44909 100644 --- a/docs/zh/latest/plugins/jwe-decrypt.md +++ b/docs/zh/latest/plugins/jwe-decrypt.md @@ -68,7 +68,7 @@ import TabItem from '@theme/TabItem'; 您可以这样从 `config.yaml` 中获取 `admin_key` 并存入环境变量: ```bash -admin_key=$(yq '.deployment.admin.admin_key[0].key' /usr/local/apisix/conf/config.yaml | sed 's/"//g') +admin_key=$(yq '.deployment.admin.admin_key[0].key' conf/config.yaml | sed 's/"//g') ``` ::: From 4cd4fc1e71a27e402f70a1194794a5b6b2fb7729 Mon Sep 17 00:00:00 2001 From: Yilia Lin <114121331+Yilialinn@users.noreply.github.com> Date: Fri, 17 Apr 2026 18:30:08 +0800 Subject: [PATCH 6/8] Update docs/zh/latest/plugins/jwe-decrypt.md Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- docs/zh/latest/plugins/jwe-decrypt.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/zh/latest/plugins/jwe-decrypt.md b/docs/zh/latest/plugins/jwe-decrypt.md index f03d29a44909..3dafb629fab6 100644 --- a/docs/zh/latest/plugins/jwe-decrypt.md +++ b/docs/zh/latest/plugins/jwe-decrypt.md @@ -45,11 +45,11 @@ import TabItem from '@theme/TabItem'; ### 消费者 -| 名称 | 类型 | 必选项 | 默认值 | 有效值 | 描述 | -| ----------------- | ------- | ------ | ------ | --------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| key | string | 是 | | | 用于标识消费者凭证的唯一密钥。 | -| secret | string | 是 | | 32 个字符 | 加密密钥。也可以将其存储在环境变量中并使用 `env://` 前缀引用,或存储在 HashiCorp Vault 的 KV 密钥引擎等密钥管理器中并使用 `secret://` 前缀引用。启用 `is_base64_encoded` 后,`secret` 长度可能超过 32 个字符,只需确保解码后长度仍为 32 个字符即可。 | -| is_base64_encoded | boolean | 否 | false | | 如果密钥为 Base64 编码,则设置为 true。 | +| 名称 | 类型 | 必选项 | 默认值 | 有效值 | 描述 | +| ----------------- | ------- | ------ | ------ | --------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| key | string | 是 | | | 用于标识消费者凭证的唯一密钥。 | +| secret | string | 是 | | 32 个字符 | 加/解密共用的对称密钥。也可以将其存储在环境变量中并使用 `env://` 前缀引用,或存储在 HashiCorp Vault 的 KV 密钥引擎等密钥管理器中并使用 `secret://` 前缀引用。启用 `is_base64_encoded` 后,`secret` 长度可能超过 32 个字符,只需确保解码后长度仍为 32 个字符即可。 | +| is_base64_encoded | boolean | 否 | false | | 如果密钥为 Base64 编码,则设置为 true。 | ### 路由或服务 From 778da0768b9b3121efcb3ead2e22a6d6e8b8ed17 Mon Sep 17 00:00:00 2001 From: Yilia Lin <114121331+Yilialinn@users.noreply.github.com> Date: Fri, 17 Apr 2026 18:30:18 +0800 Subject: [PATCH 7/8] Update docs/en/latest/plugins/jwe-decrypt.md Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- docs/en/latest/plugins/jwe-decrypt.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/en/latest/plugins/jwe-decrypt.md b/docs/en/latest/plugins/jwe-decrypt.md index aadd30d6cd4a..709cf8e8d200 100644 --- a/docs/en/latest/plugins/jwe-decrypt.md +++ b/docs/en/latest/plugins/jwe-decrypt.md @@ -45,11 +45,11 @@ This Plugin adds an endpoint `/apisix/plugin/jwe/encrypt` for JWE encryption. Fo ### Consumer -| Name | Type | Required | Default | Valid values | Description | -| ----------------- | ------- | -------- | ------- | -------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -| key | string | True | | | A unique key that identifies the Credential for a Consumer. | -| secret | string | True | | 32 characters | The encryption key. You can also store it in an environment variable and reference it using the `env://` prefix, or in a secret manager such as HashiCorp Vault's KV secrets engine, and reference it using the `secret://` prefix. | -| is_base64_encoded | boolean | False | false | | Set to true if the secret is base64 encoded. Note that after enabling `is_base64_encoded`, the `secret` length may exceed 32 characters. You only need to make sure the decoded length is still 32 characters. | +| Name | Type | Required | Default | Valid values | Description | +| ----------------- | ------- | -------- | ------- | -------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| key | string | True | | | A unique key that identifies the Credential for a Consumer. | +| secret | string | True | | 32 characters | The shared symmetric encryption/decryption key. You can also store it in an environment variable and reference it using the `env://` prefix, or in a secret manager such as HashiCorp Vault's KV secrets engine, and reference it using the `secret://` prefix. | +| is_base64_encoded | boolean | False | false | | Set to true if the secret is base64 encoded. Note that after enabling `is_base64_encoded`, the `secret` length may exceed 32 characters. You only need to make sure the decoded length is still 32 characters. | ### Route or Service From 4580a91b482a90b48f39369ebbadf7d2c5bad9d3 Mon Sep 17 00:00:00 2001 From: Yilia Lin Date: Fri, 17 Apr 2026 18:32:12 +0800 Subject: [PATCH 8/8] fix typo --- docs/zh/latest/plugins/jwe-decrypt.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/zh/latest/plugins/jwe-decrypt.md b/docs/zh/latest/plugins/jwe-decrypt.md index 3dafb629fab6..ba5f412e09dc 100644 --- a/docs/zh/latest/plugins/jwe-decrypt.md +++ b/docs/zh/latest/plugins/jwe-decrypt.md @@ -65,7 +65,7 @@ import TabItem from '@theme/TabItem'; :::note -您可以这样从 `config.yaml` 中获取 `admin_key` 并存入环境变量: +你可以这样从 `config.yaml` 中获取 `admin_key` 并存入环境变量: ```bash admin_key=$(yq '.deployment.admin.admin_key[0].key' conf/config.yaml | sed 's/"//g') @@ -226,7 +226,7 @@ curl "http://127.0.0.1:9080/apisix/plugin/jwe/encrypt?key=jack-key" \ --data-urlencode 'payload={"uid":10000,"uname":"test"}' -G ``` -您应该看到类似以下的响应,响应体中包含 JWE 加密数据: +你应该看到类似以下的响应,响应体中包含 JWE 加密数据: ```text eyJraWQiOiJqYWNrLWtleSIsImFsZyI6ImRpciIsImVuYyI6IkEyNTZHQ00ifQ..MTIzNDU2Nzg5MDEy.IUFW_q4igO_wvf63i-3VwV0MEetPL9C20tlgcQ.fveViMUi0ijJlQ19D7kDrg @@ -368,7 +368,7 @@ kubectl apply -f jwe-decrypt-ic.yaml curl "http://127.0.0.1:9080/anything/jwe" -H 'Authorization: eyJraWQiOiJqYWNrLWtleSIsImFsZyI6ImRpciIsImVuYyI6IkEyNTZHQ00ifQ..MTIzNDU2Nzg5MDEy.IUFW_q4igO_wvf63i-3VwV0MEetPL9C20tlgcQ.fveViMUi0ijJlQ19D7kDrg' ``` -您应该看到类似以下的响应,其中 `Authorization` 请求头显示了 payload 的明文: +你应该看到类似以下的响应,其中 `Authorization` 请求头显示了 payload 的明文: ```json {