This is an automated email from the ASF dual-hosted git repository.

juzhiyuan pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/apisix.git


The following commit(s) were added to refs/heads/master by this push:
     new 381595e9e feat(jwt-auth): store JWT in the request context (#11675)
381595e9e is described below

commit 381595e9e21482cdd1dab6ef73a2b5644c21375c
Author: Michele Righi <righi.mi...@gmail.com>
AuthorDate: Wed Mar 5 08:02:28 2025 +0100

    feat(jwt-auth): store JWT in the request context (#11675)
---
 apisix/plugins/jwt-auth.lua        |   8 +++
 docs/en/latest/plugins/jwt-auth.md |  15 ++---
 docs/zh/latest/plugins/jwt-auth.md |   1 +
 t/plugin/jwt-auth4.t               | 120 +++++++++++++++++++++++++++++++++++++
 4 files changed, 137 insertions(+), 7 deletions(-)

diff --git a/apisix/plugins/jwt-auth.lua b/apisix/plugins/jwt-auth.lua
index 2c00b6bf7..b61d82df3 100644
--- a/apisix/plugins/jwt-auth.lua
+++ b/apisix/plugins/jwt-auth.lua
@@ -56,6 +56,10 @@ local schema = {
             default = "key",
             minLength = 1,
         },
+        store_in_ctx = {
+            type = "boolean",
+            default = false
+        },
         anonymous_consumer = schema_def.anonymous_consumer_schema,
     },
 }
@@ -295,6 +299,10 @@ local function find_consumer(conf, ctx)
         return nil, nil, "failed to verify jwt"
     end
 
+    if conf.store_in_ctx then
+        ctx.jwt_auth_payload = jwt_obj.payload
+    end
+
     return consumer, consumer_conf
 end
 
diff --git a/docs/en/latest/plugins/jwt-auth.md 
b/docs/en/latest/plugins/jwt-auth.md
index 38fab4e87..f52d3cec5 100644
--- a/docs/en/latest/plugins/jwt-auth.md
+++ b/docs/en/latest/plugins/jwt-auth.md
@@ -52,13 +52,14 @@ NOTE: `encrypt_fields = {"secret"}` is also defined in the 
schema, which means t
 
 For Route:
 
-| Name             | Type    | Required | Default       | Description          
                                                                           |
-|------------------|---------|----------|---------------|-------------------------------------------------------------------------------------------------|
-| header           | string  | False    | authorization | The header to get 
the token from.                                                               |
-| query            | string  | False    | jwt           | The query string to 
get the token from. Lower priority than header.                             |
-| cookie           | string  | False    | jwt           | The cookie to get 
the token from. Lower priority than query.                                    |
-| hide_credentials | boolean | False    | false         | Set to true will not 
pass the authorization request of header\query\cookie to the Upstream.     |
-| key_claim_name   | string  | False    | key           | The name of the JWT 
claim that contains the user key (corresponds to Consumer's key attribute). |
+| Name             | Type    | Required | Default       | Description          
                                                                                
                                                                |
+|------------------|---------|----------|---------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------|
+| header           | string  | False    | authorization | The header to get 
the token from.                                                                 
                                                                   |
+| query            | string  | False    | jwt           | The query string to 
get the token from. Lower priority than header.                                 
                                                                 |
+| cookie           | string  | False    | jwt           | The cookie to get 
the token from. Lower priority than query.                                      
                                                                   |
+| hide_credentials | boolean | False    | false         | Set to true will not 
pass the authorization request of header\query\cookie to the Upstream.          
                                                                |
+| key_claim_name   | string  | False    | key           | The name of the JWT 
claim that contains the user key (corresponds to Consumer's key attribute).     
                                                                 |
+| store_in_ctx     | boolean | False    | false         | Set to true will 
store the JWT payload in the request context (`ctx.jwt_auth_payload`). This 
allows lower-priority plugins that run afterwards on the same request to 
retrieve and use the JWT token. |
 
 You can implement `jwt-auth` with [HashiCorp 
Vault](https://www.vaultproject.io/) to store and fetch secrets and RSA keys 
pairs from its [encrypted KV 
engine](https://developer.hashicorp.com/vault/docs/secrets/kv) using the 
[APISIX Secret](../terminology/secret.md) resource.
 
diff --git a/docs/zh/latest/plugins/jwt-auth.md 
b/docs/zh/latest/plugins/jwt-auth.md
index 6c848aa3d..0111e9e03 100644
--- a/docs/zh/latest/plugins/jwt-auth.md
+++ b/docs/zh/latest/plugins/jwt-auth.md
@@ -59,6 +59,7 @@ Route 端:
 | cookie | string | 否     | jwt           | 设置我们从哪个 cookie 获取 token,优先级低于 
query。        |
 | hide_credentials | boolean | 否     | false  | 该参数设置为 `true` 时,则不会将含有认证信息的 
header\query\cookie 传递给 Upstream。|
 | key_claim_name | string  | 否     | key           | 包含用户密钥(对应消费者的密钥属性)的 JWT 
声明的名称。|
+| store_in_ctx | boolean | 否     | false  | 设置为 `true` 将会将 JWT 负载存储在请求上下文 
(`ctx.jwt_auth_payload`) 中。这允许在同一请求上随后运行的低优先级插件检索和使用 JWT 令牌。 |
 
 您可以使用 [HashiCorp Vault](https://www.vaultproject.io/) 实施 `jwt-auth`,以从其[加密的 KV 
引擎](https://developer.hashicorp.com/vault/docs/secrets/kv) 使用 [APISIX 
Secret](../terminology/secret.md) 资源。
 
diff --git a/t/plugin/jwt-auth4.t b/t/plugin/jwt-auth4.t
index 48fbc5de1..333b26166 100644
--- a/t/plugin/jwt-auth4.t
+++ b/t/plugin/jwt-auth4.t
@@ -230,3 +230,123 @@ qr/\\"secret\\" validation failed: string too short, 
expected at least 1, got 0/
 --- error_code: 400
 --- response_body eval
 qr/\\"key\\" validation failed: string too short, expected at least 1, got 0/
+
+
+
+=== TEST 6: store_in_ctx disabled
+--- config
+    location /t {
+        content_by_lua_block {
+            local t = require("lib.test_admin").test
+            local code, body = t('/apisix/admin/routes/1',
+                ngx.HTTP_PUT,
+                [[{
+                    "plugins": {
+                        "jwt-auth": {},
+                        "serverless-post-function": {
+                            "phase": "rewrite",
+                            "functions": [
+                                "return function(conf, ctx)
+                                if ctx.jwt_auth_payload then
+                                    ngx.status = 200
+                                    ngx.say(\"JWT found in ctx. Payload key: 
\" .. ctx.jwt_auth_payload.key)
+                                    return ngx.exit(200)
+                                else
+                                    ngx.status = 401
+                                    ngx.say(\"JWT not found in ctx.\")
+                                    return ngx.exit(401)
+                                end
+                                end"
+                            ]
+                        }
+                    },
+                    "upstream": {
+                        "nodes": {
+                            "127.0.0.1:1980": 1
+                        },
+                        "type": "roundrobin"
+                    },
+                    "uri": "/jwt-auth-no-ctx"
+                }]]
+                )
+
+            if code >= 300 then
+                ngx.status = code
+            end
+            ngx.say(body)
+        }
+    }
+--- response_body
+passed
+
+
+
+=== TEST 7: verify store_in_ctx disabled (header with bearer)
+--- request
+GET /jwt-auth-no-ctx
+--- more_headers
+Authorization: bearer 
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJrZXkiOiJ1c2VyLWtleSIsIm5iZiI6MTcyNzI3NDk4M30.N6ebc4U5ms976pwKZ_iQ88w_uJKqUVNtTYZ_nXhRpWo
+--- error_code: 401
+--- response_body
+JWT not found in ctx.
+
+
+
+=== TEST 8: store_in_ctx enabled
+--- config
+    location /t {
+        content_by_lua_block {
+            local t = require("lib.test_admin").test
+            local code, body = t('/apisix/admin/routes/2',
+                ngx.HTTP_PUT,
+                [[{
+                    "plugins": {
+                        "jwt-auth": {
+                            "store_in_ctx": true
+                        },
+                        "serverless-post-function": {
+                            "phase": "rewrite",
+                            "functions": [
+                                "return function(conf, ctx)
+                                if ctx.jwt_auth_payload then
+                                    ngx.status = 200
+                                    ngx.say(\"JWT found in ctx. Payload key: 
\" .. ctx.jwt_auth_payload.key)
+                                    return ngx.exit(200)
+                                else
+                                    ngx.status = 401
+                                    ngx.say(\"JWT not found in ctx.\")
+                                    return ngx.exit(401)
+                                end
+                                end"
+                            ]
+                        }
+                    },
+                    "upstream": {
+                        "nodes": {
+                            "127.0.0.1:1980": 1
+                        },
+                        "type": "roundrobin"
+                    },
+                    "uri": "/jwt-auth-ctx"
+                }]]
+                )
+
+            if code >= 300 then
+                ngx.status = code
+            end
+            ngx.say(body)
+        }
+    }
+--- response_body
+passed
+
+
+
+=== TEST 9: verify store_in_ctx enabled (header with bearer)
+--- request
+GET /jwt-auth-ctx
+--- more_headers
+Authorization: bearer 
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJrZXkiOiJ1c2VyLWtleSIsIm5iZiI6MTcyNzI3NDk4M30.N6ebc4U5ms976pwKZ_iQ88w_uJKqUVNtTYZ_nXhRpWo
+--- error_code: 200
+--- response_body
+JWT found in ctx. Payload key: user-key

Reply via email to