spacewander commented on a change in pull request #6037:
URL: https://github.com/apache/apisix/pull/6037#discussion_r779976644



##########
File path: apisix/core/request.lua
##########
@@ -278,6 +278,15 @@ function _M.get_path(ctx)
 end
 
 
+function _M.get_uri(ctx)

Review comment:
       We should not add a common method that is only used by a place. 
Actually, I think we should remove the `get_path` too.
   
   It is strange that `get_path` fetches `$uri` but `get_uri` fetches 
`$request_uri`. Look like it is a premature optimization that brings 
inconsistent names.

##########
File path: apisix/plugins/forward-auth.lua
##########
@@ -0,0 +1,143 @@
+--
+-- Licensed to the Apache Software Foundation (ASF) under one or more
+-- contributor license agreements.  See the NOTICE file distributed with
+-- this work for additional information regarding copyright ownership.
+-- The ASF licenses this file to You under the Apache License, Version 2.0
+-- (the "License"); you may not use this file except in compliance with
+-- the License.  You may obtain a copy of the License at
+--
+--     http://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+--
+
+local ipairs = ipairs
+local core   = require("apisix.core")
+local http   = require("resty.http")
+
+local schema = {
+    type = "object",
+    properties = {
+        host = {type = "string"},
+        ssl_verify = {
+            type = "boolean",
+            default = true,
+        },
+        request_headers = {
+            type = "array",
+            default = {},
+            items = {type = "string"},
+            description = "client request header that will be sent to the 
authorization"
+        },
+        upstream_headers = {
+            type = "array",
+            default = {},
+            items = {type = "string"},
+            description = "authorization response header that will be sent to 
the upstream"
+        },
+        client_headers = {
+            type = "array",
+            default = {},
+            items = {type = "string"},
+            description = "authorization response header that will be sent to"
+                           .. "the client when authorize failure"
+        },
+        timeout = {
+            type = "integer",
+            minimum = 1,
+            maximum = 60000,
+            default = 3000,
+            description = "timeout in milliseconds",
+        },
+        keepalive = {type = "boolean", default = true},
+        keepalive_timeout = {type = "integer", minimum = 1000, default = 
60000},
+        keepalive_pool = {type = "integer", minimum = 1, default = 5},
+    },
+    required = {"host"}
+}
+
+
+local _M = {
+    version = 0.1,
+    priority = 2002,
+    name = "forward-auth",
+    schema = schema,
+}
+
+
+function _M.check_schema(conf)
+    return core.schema.check(schema, conf)
+end
+
+
+function _M.access(conf, ctx)
+    local auth_headers = {
+        ["X-Forwarded-Proto"] = core.request.get_scheme(ctx),
+        ["X-Forwarded-Method"] = core.request.get_method(),
+        ["X-Forwarded-Host"] = core.request.get_host(ctx),
+        ["X-Forwarded-Uri"] = core.request.get_uri(ctx),
+        ["X-Forwarded-For"] = core.request.get_remote_client_ip(ctx),
+    }
+
+    -- append headers that need to be get from the client request header
+    if #conf.request_headers > 0 then
+        for _, header in ipairs(conf.request_headers) do
+            auth_headers[header] = core.request.header(ctx, header)
+        end
+    else
+        auth_headers = core.table.merge(core.request.headers(), auth_headers)

Review comment:
       Ditto

##########
File path: docs/en/latest/plugins/forward-auth.md
##########
@@ -0,0 +1,135 @@
+---
+title: forward-auth
+---
+
+<!--
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License.  You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+-->
+
+## Summary
+
+- [**Description**](#description)
+- [**Attributes**](#attributes)
+- [**Example**](#example)
+
+## Description
+
+The `forward-auth` plugin implement a classic external authentication model. 
We can implement a custom error return or user redirection to the 
authentication page if the authentication fails.
+
+Forward Auth cleverly moves the authentication and authorization logic to a 
dedicated external service, where the gateway forwards the user's request to 
the authentication service and blocks the original request and replaces the 
result when the authentication service responds with a non-20x status.
+
+## Attributes
+
+| Name | Type | Requirement | Default | Valid | Description |
+| -- | -- | -- | -- | -- | -- |
+| host | string | required |  |  | Authorization service host (eg. 
https://localhost:9188) |
+| ssl_verify | boolean | optional | true |   | Whether to verify the 
certificate |
+| request_headers | array[string] | optional |  |  | `client` request header 
that will be sent to the `authorization` service |
+| upstream_headers | array[string] | optional |  |  | `authorization` service 
response header that will be sent to the `upstream` |
+| client_headers | array[string] | optional |  |  | `authorization` response 
header that will be sent to the `client` when authorize failure |
+| timeout | integer | optional | 3000ms | [1, 60000]ms | Authorization service 
HTTP call timeout |
+| keepalive | boolean | optional | true |  | HTTP keepalive |
+| keepalive_timeout | integer | optional | 60000ms | [1000, ...]ms | keepalive 
idle timeout |
+| keepalive_pool | integer | optional | 5 | [1, ...]ms | Connection pool limit 
|
+
+## Example
+
+First, you need to setup an external authorization service. Here is an example 
of using Apache APISIX's serverless plugin to mock.
+
+```shell
+$ curl -X PUT 'http://127.0.0.1:9080/apisix/admin/routes/auth' \
+    -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' \
+    -H 'Content-Type: application/json' \
+    -d '{
+    "uri": "/auth",
+    "plugins": {
+        "serverless-pre-function": {
+            "phase": "rewrite",
+            "functions": [
+                "return function (conf, ctx) local core = 
require(\"apisix.core\"); local authorization = core.request.header(ctx, 
\"Authorization\"); if authorization == \"123\" then core.response.exit(200); 
elseif authorization == \"321\" then core.response.set_header(\"X-User-ID\", 
\"i-am-user\"); core.response.exit(200); else 
core.response.set_header(\"Location\", \"http://example.com/auth\";); 
core.response.exit(403); end end"
+            ]
+        }
+    },
+    "upstream": {
+        "nodes": {},
+        "scheme": "https",
+        "type": "roundrobin"
+    }
+}'
+```
+
+Next, we create a route for testing.
+
+```shell
+$ curl -X PUT http://127.0.0.1:9080/apisix/admin/routes/1
+    -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1'
+    -d '{
+    "uri": "/headers",
+    "plugins": {
+        "forward-auth": {
+            "host": "http://127.0.0.1:9080/auth";,
+            "request_headers": ["Authorization"],
+            "upstream_headers": ["X-User-ID"],
+            "client_headers": ["Location"]
+        }
+    },
+    "upstream": {
+        "nodes": {
+            "httpbin.org:80": 1
+        },
+        "type": "roundrobin"
+    }
+}'
+```
+
+We can perform the following three tests.
+
+1. **request_headers** Send Authorization header from `client` to 
`authorization` service
+
+```shell
+$ curl http://127.0.0.1:9080/headers -H 'Authorization: 123'
+{
+    "headers": {
+        "Authorization": "123",
+        "Next": "More-headers"
+    }
+}
+```
+
+2. **upstream_headers** Send `authorization` service response header to the 
`upstream`
+
+```shell
+$ curl http://127.0.0.1:9080/headers -H 'Authorization: 321'
+{
+    "headers": {
+        "Authorization": "321",
+        "X-User-ID": "i-am-user",
+        "Next": "More-headers"
+    }
+}
+```
+
+3. **client_headers** Send `authorization` service response header to `client` 
when authorize failure

Review comment:
       ```suggestion
   3. **client_headers** Send `authorization` service response header to 
`client` when authorizing failed
   ```

##########
File path: docs/en/latest/plugins/forward-auth.md
##########
@@ -0,0 +1,135 @@
+---
+title: forward-auth
+---
+
+<!--
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License.  You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+-->
+
+## Summary
+
+- [**Description**](#description)
+- [**Attributes**](#attributes)
+- [**Example**](#example)
+
+## Description
+
+The `forward-auth` plugin implement a classic external authentication model. 
We can implement a custom error return or user redirection to the 
authentication page if the authentication fails.
+
+Forward Auth cleverly moves the authentication and authorization logic to a 
dedicated external service, where the gateway forwards the user's request to 
the authentication service and blocks the original request and replaces the 
result when the authentication service responds with a non-20x status.
+
+## Attributes
+
+| Name | Type | Requirement | Default | Valid | Description |
+| -- | -- | -- | -- | -- | -- |
+| host | string | required |  |  | Authorization service host (eg. 
https://localhost:9188) |
+| ssl_verify | boolean | optional | true |   | Whether to verify the 
certificate |
+| request_headers | array[string] | optional |  |  | `client` request header 
that will be sent to the `authorization` service |
+| upstream_headers | array[string] | optional |  |  | `authorization` service 
response header that will be sent to the `upstream` |

Review comment:
       Ditto

##########
File path: docs/en/latest/plugins/forward-auth.md
##########
@@ -0,0 +1,135 @@
+---
+title: forward-auth
+---
+
+<!--
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License.  You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+-->
+
+## Summary
+
+- [**Description**](#description)
+- [**Attributes**](#attributes)
+- [**Example**](#example)
+
+## Description
+
+The `forward-auth` plugin implement a classic external authentication model. 
We can implement a custom error return or user redirection to the 
authentication page if the authentication fails.
+
+Forward Auth cleverly moves the authentication and authorization logic to a 
dedicated external service, where the gateway forwards the user's request to 
the authentication service and blocks the original request and replaces the 
result when the authentication service responds with a non-20x status.

Review comment:
       ```suggestion
   Forward Auth cleverly moves the authentication and authorization logic to a 
dedicated external service, where the gateway forwards the user's request to 
the authentication service and blocks the original request, and replaces the 
result when the authentication service responds with a non-2xx status.
   ```

##########
File path: apisix/plugins/forward-auth.lua
##########
@@ -0,0 +1,143 @@
+--
+-- Licensed to the Apache Software Foundation (ASF) under one or more
+-- contributor license agreements.  See the NOTICE file distributed with
+-- this work for additional information regarding copyright ownership.
+-- The ASF licenses this file to You under the Apache License, Version 2.0
+-- (the "License"); you may not use this file except in compliance with
+-- the License.  You may obtain a copy of the License at
+--
+--     http://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+--
+
+local ipairs = ipairs
+local core   = require("apisix.core")
+local http   = require("resty.http")
+
+local schema = {
+    type = "object",
+    properties = {
+        host = {type = "string"},
+        ssl_verify = {
+            type = "boolean",
+            default = true,
+        },
+        request_headers = {
+            type = "array",
+            default = {},
+            items = {type = "string"},
+            description = "client request header that will be sent to the 
authorization"

Review comment:
       ```suggestion
               description = "client request header that will be sent to the 
authorization service"
   ```

##########
File path: apisix/plugins/forward-auth.lua
##########
@@ -0,0 +1,143 @@
+--
+-- Licensed to the Apache Software Foundation (ASF) under one or more
+-- contributor license agreements.  See the NOTICE file distributed with
+-- this work for additional information regarding copyright ownership.
+-- The ASF licenses this file to You under the Apache License, Version 2.0
+-- (the "License"); you may not use this file except in compliance with
+-- the License.  You may obtain a copy of the License at
+--
+--     http://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+--
+
+local ipairs = ipairs
+local core   = require("apisix.core")
+local http   = require("resty.http")
+
+local schema = {
+    type = "object",
+    properties = {
+        host = {type = "string"},
+        ssl_verify = {
+            type = "boolean",
+            default = true,
+        },
+        request_headers = {
+            type = "array",
+            default = {},
+            items = {type = "string"},
+            description = "client request header that will be sent to the 
authorization"
+        },
+        upstream_headers = {
+            type = "array",
+            default = {},
+            items = {type = "string"},
+            description = "authorization response header that will be sent to 
the upstream"
+        },
+        client_headers = {
+            type = "array",
+            default = {},
+            items = {type = "string"},
+            description = "authorization response header that will be sent to"
+                           .. "the client when authorize failure"

Review comment:
       ```suggestion
                              .. "the client when authorizing failed"
   ```

##########
File path: apisix/plugins/forward-auth.lua
##########
@@ -0,0 +1,143 @@
+--
+-- Licensed to the Apache Software Foundation (ASF) under one or more
+-- contributor license agreements.  See the NOTICE file distributed with
+-- this work for additional information regarding copyright ownership.
+-- The ASF licenses this file to You under the Apache License, Version 2.0
+-- (the "License"); you may not use this file except in compliance with
+-- the License.  You may obtain a copy of the License at
+--
+--     http://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+--
+
+local ipairs = ipairs
+local core   = require("apisix.core")
+local http   = require("resty.http")
+
+local schema = {
+    type = "object",
+    properties = {
+        host = {type = "string"},
+        ssl_verify = {
+            type = "boolean",
+            default = true,
+        },
+        request_headers = {
+            type = "array",
+            default = {},
+            items = {type = "string"},
+            description = "client request header that will be sent to the 
authorization"
+        },
+        upstream_headers = {
+            type = "array",
+            default = {},
+            items = {type = "string"},
+            description = "authorization response header that will be sent to 
the upstream"
+        },
+        client_headers = {
+            type = "array",
+            default = {},
+            items = {type = "string"},
+            description = "authorization response header that will be sent to"
+                           .. "the client when authorize failure"
+        },
+        timeout = {
+            type = "integer",
+            minimum = 1,
+            maximum = 60000,
+            default = 3000,
+            description = "timeout in milliseconds",
+        },
+        keepalive = {type = "boolean", default = true},
+        keepalive_timeout = {type = "integer", minimum = 1000, default = 
60000},
+        keepalive_pool = {type = "integer", minimum = 1, default = 5},
+    },
+    required = {"host"}
+}
+
+
+local _M = {
+    version = 0.1,
+    priority = 2002,
+    name = "forward-auth",
+    schema = schema,
+}
+
+
+function _M.check_schema(conf)
+    return core.schema.check(schema, conf)
+end
+
+
+function _M.access(conf, ctx)
+    local auth_headers = {
+        ["X-Forwarded-Proto"] = core.request.get_scheme(ctx),
+        ["X-Forwarded-Method"] = core.request.get_method(),
+        ["X-Forwarded-Host"] = core.request.get_host(ctx),
+        ["X-Forwarded-Uri"] = core.request.get_uri(ctx),
+        ["X-Forwarded-For"] = core.request.get_remote_client_ip(ctx),
+    }
+
+    -- append headers that need to be get from the client request header
+    if #conf.request_headers > 0 then
+        for _, header in ipairs(conf.request_headers) do
+            auth_headers[header] = core.request.header(ctx, header)

Review comment:
       Better not trust the client's `X-Forwarded-XX` by default

##########
File path: t/plugin/forward-auth.t
##########
@@ -0,0 +1,157 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License.  You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+use t::APISIX 'no_plan';
+
+repeat_each(1);
+no_long_string();
+no_root_location();
+
+add_block_preprocessor(sub {
+    my ($block) = @_;
+
+    if ((!defined $block->error_log) && (!defined $block->no_error_log)) {
+        $block->set_value("no_error_log", "[error]");
+    }
+
+    if (!defined $block->request) {
+        $block->set_value("request", "GET /t");
+    }
+});
+
+run_tests();
+
+__DATA__
+
+=== TEST 1: sanity
+--- config
+    location /t {
+        content_by_lua_block {
+            local test_cases = {
+                {host = "http://127.0.0.1:8199"},
+                {request_headers = {"test"}},
+                {host = 3233},
+                {host = "http://127.0.0.1:8199";, request_headers = "test"}
+            }
+            local plugin = require("apisix.plugins.forward-auth")
+
+            for _, case in ipairs(test_cases) do
+                local ok, err = plugin.check_schema(case)
+                ngx.say(ok and "done" or err)
+            end
+        }
+    }
+--- response_body
+done
+property "host" is required
+property "host" validation failed: wrong type: expected string, got number
+property "request_headers" validation failed: wrong type: expected array, got 
string
+
+
+
+=== TEST 2: setup route with plugin
+--- config
+    location /t {
+        content_by_lua_block {
+            local datas = {
+                {
+                    url = "/apisix/admin/routes/auth",
+                    data = [[{
+                        "plugins": {
+                            "serverless-pre-function": {
+                                "phase": "rewrite",
+                                "functions": ["return function (conf, ctx) 
local core = require(\"apisix.core\"); local authorization = 
core.request.header(ctx, \"Authorization\"); if authorization == \"123\" then 
core.response.exit(200); elseif authorization == \"321\" then 
core.response.set_header(\"X-User-ID\", \"i-am-an-user\"); 
core.response.exit(200); else core.response.set_header(\"Location\", 
\"http://example.com/auth\";); core.response.exit(403); end end"]
+                            }
+                        },
+                        "uri": "/auth"
+                    }]],
+                },
+                {
+                    url = "/apisix/admin/routes/echo",
+                    data = [[{
+                        "plugins": {
+                            "serverless-pre-function": {
+                                "phase": "rewrite",
+                                "functions": ["return function (conf, ctx) 
local core = require(\"apisix.core\"); core.response.exit(200, 
core.request.headers(ctx)); end"]
+                            }
+                        },
+                        "uri": "/echo"
+                    }]],
+                },
+                {
+                    url = "/apisix/admin/routes/1",
+                    data = [[{
+                        "plugins": {
+                            "forward-auth": {
+                                "host": "http://127.0.0.1:1984/auth";,
+                                "request_headers": ["Authorization"],
+                                "upstream_headers": ["X-User-ID"],
+                                "client_headers": ["Location"]
+                            },
+                            "proxy-rewrite": {
+                                "uri": "/echo"
+                            }
+                        },
+                        "upstream": {
+                            "nodes": {
+                                "127.0.0.1:1984": 1
+                            },
+                            "type": "roundrobin"
+                        },
+                        "uri": "/hello"
+                    }]],
+                },
+            }
+
+            local t = require("lib.test_admin").test
+
+            for _, data in ipairs(datas) do
+                local code, body = t(data.url, ngx.HTTP_PUT, data.data)
+                ngx.say(code..body)
+            end
+        }
+    }
+--- response_body eval
+"201passed\n" x 3
+
+
+
+=== TEST 3: hit route (test request_headers)
+--- request
+GET /hello
+--- more_headers
+Authorization: 123
+--- response_body_like eval
+qr/\"authorization\":\"123\"/
+
+
+
+=== TEST 4: hit route (test upstream_headers)
+--- request
+GET /hello
+--- more_headers
+Authorization: 321
+--- response_body_like eval
+qr/\"x-user-id\":\"i-am-an-user\"/
+
+
+
+=== TEST 5: hit route (test client_headers)
+--- request
+GET /hello
+--- error_code: 403
+--- response_headers
+Location: http://example.com/auth

Review comment:
       Let's add a test that the client passes X-Forwarded-XX by itself

##########
File path: t/plugin/forward-auth.t
##########
@@ -0,0 +1,157 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License.  You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+use t::APISIX 'no_plan';
+
+repeat_each(1);
+no_long_string();
+no_root_location();
+
+add_block_preprocessor(sub {
+    my ($block) = @_;
+
+    if ((!defined $block->error_log) && (!defined $block->no_error_log)) {
+        $block->set_value("no_error_log", "[error]");
+    }
+
+    if (!defined $block->request) {
+        $block->set_value("request", "GET /t");
+    }
+});
+
+run_tests();
+
+__DATA__
+
+=== TEST 1: sanity
+--- config
+    location /t {
+        content_by_lua_block {
+            local test_cases = {
+                {host = "http://127.0.0.1:8199"},
+                {request_headers = {"test"}},
+                {host = 3233},
+                {host = "http://127.0.0.1:8199";, request_headers = "test"}
+            }
+            local plugin = require("apisix.plugins.forward-auth")
+
+            for _, case in ipairs(test_cases) do
+                local ok, err = plugin.check_schema(case)
+                ngx.say(ok and "done" or err)
+            end
+        }
+    }
+--- response_body
+done
+property "host" is required
+property "host" validation failed: wrong type: expected string, got number
+property "request_headers" validation failed: wrong type: expected array, got 
string
+
+
+
+=== TEST 2: setup route with plugin
+--- config
+    location /t {
+        content_by_lua_block {
+            local datas = {
+                {
+                    url = "/apisix/admin/routes/auth",
+                    data = [[{
+                        "plugins": {
+                            "serverless-pre-function": {
+                                "phase": "rewrite",
+                                "functions": ["return function (conf, ctx) 
local core = require(\"apisix.core\"); local authorization = 
core.request.header(ctx, \"Authorization\"); if authorization == \"123\" then 
core.response.exit(200); elseif authorization == \"321\" then 
core.response.set_header(\"X-User-ID\", \"i-am-an-user\"); 
core.response.exit(200); else core.response.set_header(\"Location\", 
\"http://example.com/auth\";); core.response.exit(403); end end"]

Review comment:
       Let's log down the X-Forwarded-XX received by the service. And better to 
break down the very long code.

##########
File path: docs/en/latest/plugins/forward-auth.md
##########
@@ -0,0 +1,135 @@
+---
+title: forward-auth
+---
+
+<!--
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License.  You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+-->
+
+## Summary
+
+- [**Description**](#description)
+- [**Attributes**](#attributes)
+- [**Example**](#example)
+
+## Description
+
+The `forward-auth` plugin implement a classic external authentication model. 
We can implement a custom error return or user redirection to the 
authentication page if the authentication fails.
+
+Forward Auth cleverly moves the authentication and authorization logic to a 
dedicated external service, where the gateway forwards the user's request to 
the authentication service and blocks the original request and replaces the 
result when the authentication service responds with a non-20x status.
+
+## Attributes
+
+| Name | Type | Requirement | Default | Valid | Description |
+| -- | -- | -- | -- | -- | -- |
+| host | string | required |  |  | Authorization service host (eg. 
https://localhost:9188) |
+| ssl_verify | boolean | optional | true |   | Whether to verify the 
certificate |
+| request_headers | array[string] | optional |  |  | `client` request header 
that will be sent to the `authorization` service |
+| upstream_headers | array[string] | optional |  |  | `authorization` service 
response header that will be sent to the `upstream` |
+| client_headers | array[string] | optional |  |  | `authorization` response 
header that will be sent to the `client` when authorize failure |
+| timeout | integer | optional | 3000ms | [1, 60000]ms | Authorization service 
HTTP call timeout |
+| keepalive | boolean | optional | true |  | HTTP keepalive |
+| keepalive_timeout | integer | optional | 60000ms | [1000, ...]ms | keepalive 
idle timeout |
+| keepalive_pool | integer | optional | 5 | [1, ...]ms | Connection pool limit 
|
+
+## Example
+
+First, you need to setup an external authorization service. Here is an example 
of using Apache APISIX's serverless plugin to mock.
+
+```shell
+$ curl -X PUT 'http://127.0.0.1:9080/apisix/admin/routes/auth' \
+    -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' \
+    -H 'Content-Type: application/json' \
+    -d '{
+    "uri": "/auth",
+    "plugins": {
+        "serverless-pre-function": {
+            "phase": "rewrite",
+            "functions": [
+                "return function (conf, ctx) local core = 
require(\"apisix.core\"); local authorization = core.request.header(ctx, 
\"Authorization\"); if authorization == \"123\" then core.response.exit(200); 
elseif authorization == \"321\" then core.response.set_header(\"X-User-ID\", 
\"i-am-user\"); core.response.exit(200); else 
core.response.set_header(\"Location\", \"http://example.com/auth\";); 
core.response.exit(403); end end"
+            ]
+        }
+    },
+    "upstream": {
+        "nodes": {},
+        "scheme": "https",

Review comment:
       Let's remove useless field

##########
File path: docs/en/latest/plugins/forward-auth.md
##########
@@ -0,0 +1,135 @@
+---
+title: forward-auth
+---
+
+<!--
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License.  You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+-->
+
+## Summary
+
+- [**Description**](#description)
+- [**Attributes**](#attributes)
+- [**Example**](#example)
+
+## Description
+
+The `forward-auth` plugin implement a classic external authentication model. 
We can implement a custom error return or user redirection to the 
authentication page if the authentication fails.

Review comment:
       ```suggestion
   The `forward-auth` plugin implements a classic external authentication 
model. We can implement a custom error return or user redirection to the 
authentication page if the authentication fails.
   ```

##########
File path: docs/en/latest/plugins/forward-auth.md
##########
@@ -0,0 +1,135 @@
+---
+title: forward-auth
+---
+
+<!--
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License.  You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+-->
+
+## Summary
+
+- [**Description**](#description)
+- [**Attributes**](#attributes)
+- [**Example**](#example)
+
+## Description
+
+The `forward-auth` plugin implement a classic external authentication model. 
We can implement a custom error return or user redirection to the 
authentication page if the authentication fails.
+
+Forward Auth cleverly moves the authentication and authorization logic to a 
dedicated external service, where the gateway forwards the user's request to 
the authentication service and blocks the original request and replaces the 
result when the authentication service responds with a non-20x status.
+
+## Attributes
+
+| Name | Type | Requirement | Default | Valid | Description |
+| -- | -- | -- | -- | -- | -- |
+| host | string | required |  |  | Authorization service host (eg. 
https://localhost:9188) |
+| ssl_verify | boolean | optional | true |   | Whether to verify the 
certificate |
+| request_headers | array[string] | optional |  |  | `client` request header 
that will be sent to the `authorization` service |

Review comment:
       Let's doc the behavior when this field is empty




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


Reply via email to