You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@apisix.apache.org by sp...@apache.org on 2022/03/24 01:53:44 UTC

[apisix] branch master updated: feat: add optional request method for forward-auth plugin (#6682)

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

spacewander 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 2149ab1  feat: add optional request method for forward-auth plugin (#6682)
2149ab1 is described below

commit 2149ab12bcb279574f4a68154c13087baa5477cf
Author: LetsGO <97...@qq.com>
AuthorDate: Thu Mar 24 09:53:36 2022 +0800

    feat: add optional request method for forward-auth plugin (#6682)
---
 apisix/plugins/forward-auth.lua        | 13 ++++++-
 docs/en/latest/plugins/forward-auth.md |  1 +
 docs/zh/latest/plugins/forward-auth.md |  1 +
 t/plugin/forward-auth.t                | 67 +++++++++++++++++++++++++++++++++-
 4 files changed, 79 insertions(+), 3 deletions(-)

diff --git a/apisix/plugins/forward-auth.lua b/apisix/plugins/forward-auth.lua
index 6aafb3a..3bc8a0e 100644
--- a/apisix/plugins/forward-auth.lua
+++ b/apisix/plugins/forward-auth.lua
@@ -27,6 +27,12 @@ local schema = {
             type = "boolean",
             default = true,
         },
+        request_method = {
+            type = "string",
+            default = "GET",
+            enum = {"GET", "POST"},
+            description = "the method for client to request the authorization service"
+        },
         request_headers = {
             type = "array",
             default = {},
@@ -95,9 +101,14 @@ function _M.access(conf, ctx)
     local params = {
         headers = auth_headers,
         keepalive = conf.keepalive,
-        ssl_verify = conf.ssl_verify
+        ssl_verify = conf.ssl_verify,
+        method = conf.request_method
     }
 
+    if params.method == "POST" then
+        params.body = core.request.get_body()
+    end
+
     if conf.keepalive then
         params.keepalive_timeout = conf.keepalive_timeout
         params.keepalive_pool = conf.keepalive_pool
diff --git a/docs/en/latest/plugins/forward-auth.md b/docs/en/latest/plugins/forward-auth.md
index ed3cced..f742664 100644
--- a/docs/en/latest/plugins/forward-auth.md
+++ b/docs/en/latest/plugins/forward-auth.md
@@ -33,6 +33,7 @@ Forward Auth cleverly moves the authentication and authorization logic to a dedi
 | -- | -- | -- | -- | -- | -- |
 | uri | string | required |  |  | Authorization service uri (eg. https://localhost/auth) |
 | ssl_verify | boolean | optional | true |   | Whether to verify the certificate |
+| request_method | string | optional | GET | ["GET","POST"] | The method for `client` to request the `authorization` service. When it is `POST`, the request body will be send to the `authorization` service. |
 | request_headers | array[string] | optional |  |  | `client` request header that will be sent to the `authorization` service. When it is not set, no `client` request headers are sent to the `authorization` service, except for those provided by APISIX (X-Forwarded-XXX). |
 | upstream_headers | array[string] | optional |  |  | `authorization` service response header that will be sent to the `upstream`. When it is not set, will not forward the `authorization` service response header to the `upstream`. |
 | client_headers | array[string] | optional |  |  | `authorization` response header that will be sent to the `client` when authorize failure. When it is not set, will not forward the `authorization` service response header to the `client`. |
diff --git a/docs/zh/latest/plugins/forward-auth.md b/docs/zh/latest/plugins/forward-auth.md
index bf97912..ed95048 100644
--- a/docs/zh/latest/plugins/forward-auth.md
+++ b/docs/zh/latest/plugins/forward-auth.md
@@ -33,6 +33,7 @@ Forward Auth 巧妙地将认证和授权逻辑移到了一个专门的外部服
 | -- | -- | -- | -- | -- | -- |
 | host | string | 必须 |  |  | 设置 `authorization` 服务的地址 (eg. https://localhost:9188) |
 | ssl_verify | boolean | 可选 | true |   | 是否验证证书 |
+| request_method | string | 可选 | GET | ["GET","POST"] | `client` 请求 `authorization` 服务的方法。当设置为 POST时,会将 request body 转发至`authorization` 服务。 |
 | request_headers | array[string] | 可选 |  |  | 设置需要由 `client` 转发到 `authorization` 服务的请求头。未设置时,只有 Apache APISIX 的(X-Forwarded-XXX)会被转发到 `authorization` 服务。 |
 | upstream_headers | array[string] | 可选 |  |  | 认证通过时,设置 `authorization` 服务转发至 `upstream` 的请求头。如果不设置则不转发任何请求头。
 | client_headers | array[string] | 可选 |  |  | 认证失败时,由 `authorization` 服务向 `client` 发送的响应头。如果不设置则不转发任何响应头。 |
diff --git a/t/plugin/forward-auth.t b/t/plugin/forward-auth.t
index b624101..cf6cc89 100644
--- a/t/plugin/forward-auth.t
+++ b/t/plugin/forward-auth.t
@@ -44,7 +44,9 @@ __DATA__
                 {uri = "http://127.0.0.1:8199"},
                 {request_headers = {"test"}},
                 {uri = 3233},
-                {uri = "http://127.0.0.1:8199", request_headers = "test"}
+                {uri = "http://127.0.0.1:8199", request_headers = "test"},
+                {uri = "http://127.0.0.1:8199", request_method = "POST"},
+                {uri = "http://127.0.0.1:8199", request_method = "PUT"}
             }
             local plugin = require("apisix.plugins.forward-auth")
 
@@ -59,6 +61,8 @@ done
 property "uri" is required
 property "uri" validation failed: wrong type: expected string, got number
 property "request_headers" validation failed: wrong type: expected array, got string
+done
+property "request_method" validation failed: matches none of the enum values
 
 
 
@@ -108,6 +112,28 @@ property "request_headers" validation failed: wrong type: expected array, got st
                                         if core.request.header(ctx, \"Authorization\") == \"444\" then
                                             core.response.exit(403, core.request.headers(ctx));
                                         end
+                                    end",
+                                    "return function(conf, ctx)
+                                        local core = require(\"apisix.core\")
+                                        if core.request.get_method() == \"POST\" then
+                                           local req_body, err = core.request.get_body()
+                                           if err then
+                                               core.response.exit(400)
+                                           end
+                                           if req_body then
+                                               local data, err = core.json.decode(req_body)
+                                               if err then
+                                                   core.response.exit(400)
+                                               end
+                                               if data[\"authorization\"] == \"555\" then
+                                                   core.response.set_header(\"X-User-ID\", \"i-am-an-user\")
+                                                   core.response.exit(200)
+                                               elseif data[\"authorization\"] == \"666\" then
+                                                   core.response.set_header(\"Location\", \"http://example.com/auth\")
+                                                   core.response.exit(403)
+                                               end
+                                           end
+                                        end
                                     end"
                                 ]
                             }
@@ -166,6 +192,24 @@ property "request_headers" validation failed: wrong type: expected array, got st
                         "uri": "/empty"
                     }]],
                 },
+                {
+                    url = "/apisix/admin/routes/3",
+                    data = [[{
+                        "plugins": {
+                            "forward-auth": {
+                                "uri": "http://127.0.0.1:1984/auth",
+                                "request_method": "POST",
+                                "upstream_headers": ["X-User-ID"],
+                                "client_headers": ["Location"]
+                            },
+                            "proxy-rewrite": {
+                                "uri": "/echo"
+                            }
+                        },
+                        "upstream_id": "u1",
+                        "uri": "/ping"
+                    }]],
+                },
             }
 
             local t = require("lib.test_admin").test
@@ -177,7 +221,7 @@ property "request_headers" validation failed: wrong type: expected array, got st
         }
     }
 --- response_body eval
-"201passed\n" x 5
+"201passed\n" x 6
 
 
 
@@ -246,3 +290,22 @@ Authorization: 333
 --- error_code: 403
 --- response_headers
 !Location
+
+
+
+=== TEST 9: hit route (test upstream_headers when use post method)
+--- request
+POST /ping
+{"authorization": "555"}
+--- response_body_like eval
+qr/\"x-user-id\":\"i-am-an-user\"/
+
+
+
+=== TEST 10: hit route (test client_headers when use post method)
+--- request
+POST /ping
+{"authorization": "666"}
+--- error_code: 403
+--- response_headers
+Location: http://example.com/auth