kayx23 commented on code in PR #12405: URL: https://github.com/apache/apisix/pull/12405#discussion_r2189432742
########## docs/en/latest/plugins/forward-auth.md: ########## @@ -166,6 +167,122 @@ HTTP/1.1 403 Forbidden Location: http://example.com/auth ``` +### Using data from POST body to make decision on Authorization service + +::: note +When the decision is to be made on the basis of POST body, then it is recommended to use `$post_arg.xyz` with `extra_headers` field and make the decision on Authorization service on basis of headers rather than using POST `request_method` to pass the entire request body to Authorization service. +::: + +Setup Auth service to extract `tenant_id` from header. + +```shell +curl -X PUT 'http://127.0.0.1:9180/apisix/admin/routes/auth' \ + -H "X-API-KEY: $admin_key" \ + -H 'Content-Type: application/json' \ + -d '{ + "uri": "/auth", + "plugins": { + "serverless-pre-function": { + "phase": "rewrite", + "functions": [ + "return function(conf, ctx) + local core = require(\"apisix.core\") + if core.request.header(ctx, \"tenant_id\") then + core.response.set_header(\"X-User-ID\", \"i-am-an-user\"); + core.response.exit(200); + else + core.response.exit(400, \"tenant_id is required\") + end + end" + ] + } + } +}' +``` + +Setup route to extract `tenant_id` from body and pass in the header. Review Comment: ```suggestion Create a route that accepts POST requests and uses the `forward-auth` plugin to call the auth endpoint with the `tenant_id` from the request. The request is forwarded to the upstream service only if the auth check returns 200. ``` ########## docs/en/latest/plugins/forward-auth.md: ########## @@ -166,6 +167,122 @@ HTTP/1.1 403 Forbidden Location: http://example.com/auth ``` +### Using data from POST body to make decision on Authorization service + +::: note +When the decision is to be made on the basis of POST body, then it is recommended to use `$post_arg.xyz` with `extra_headers` field and make the decision on Authorization service on basis of headers rather than using POST `request_method` to pass the entire request body to Authorization service. +::: + +Setup Auth service to extract `tenant_id` from header. Review Comment: ```suggestion Create a serverless function on the `/auth` route that checks for the presence of the `tenant_id` header. If present, the route responds with HTTP 200 and sets the `X-User-ID` header to a fixed value `i-am-an-user`. If `tenant_id` is missing, it returns HTTP 400 with an error message. ``` ########## docs/en/latest/plugins/forward-auth.md: ########## @@ -40,8 +40,9 @@ This Plugin moves the authentication and authorization logic to a dedicated exte | ----------------- | ------------- | -------- | ------- | -------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------- | | uri | string | True | | | URI of the authorization service. | | ssl_verify | boolean | False | true | | When set to `true`, verifies the SSL certificate. | -| request_method | string | False | GET | ["GET","POST"] | HTTP method for a client to send requests to the authorization service. When set to `POST` the request body is send to the authorization service. | +| request_method | string | False | GET | ["GET","POST"] | HTTP method for a client to send requests to the authorization service. When set to `POST` the request body is send to the authorization service. (not recommended. See `extra_headers`) | Review Comment: Redirecting users to `extra_headers` in the attribute table does not explain clearly why one should consider `extra_headers` instead. This paragraph is a bit more clear, so perhaps you would want to link to this section. <img width="959" alt="image" src="https://github.com/user-attachments/assets/63b15260-ecfa-4527-828f-5b6dd41e4762" /> ########## docs/en/latest/plugins/forward-auth.md: ########## @@ -166,6 +167,122 @@ HTTP/1.1 403 Forbidden Location: http://example.com/auth ``` +### Using data from POST body to make decision on Authorization service + +::: note +When the decision is to be made on the basis of POST body, then it is recommended to use `$post_arg.xyz` with `extra_headers` field and make the decision on Authorization service on basis of headers rather than using POST `request_method` to pass the entire request body to Authorization service. +::: + +Setup Auth service to extract `tenant_id` from header. + +```shell +curl -X PUT 'http://127.0.0.1:9180/apisix/admin/routes/auth' \ + -H "X-API-KEY: $admin_key" \ + -H 'Content-Type: application/json' \ + -d '{ + "uri": "/auth", + "plugins": { + "serverless-pre-function": { + "phase": "rewrite", + "functions": [ + "return function(conf, ctx) + local core = require(\"apisix.core\") + if core.request.header(ctx, \"tenant_id\") then + core.response.set_header(\"X-User-ID\", \"i-am-an-user\"); + core.response.exit(200); + else + core.response.exit(400, \"tenant_id is required\") + end + end" + ] + } + } +}' +``` + +Setup route to extract `tenant_id` from body and pass in the header. + +```shell +curl -X PUT 'http://127.0.0.1:9180/apisix/admin/routes/1' \ + -H "X-API-KEY: $admin_key" \ + -d '{ + "uri": "/post", + "methods": ["POST"], + "plugins": { + "forward-auth": { + "uri": "http://127.0.0.1:9080/auth", + "request_method": "GET", + "extra_headers": {"tenant_id": "$post_arg.tenant_id"} + } + }, + "upstream": { + "nodes": { + "httpbin.org:80": 1 + }, + "type": "roundrobin" + } +}' +``` + +Now if we send the request: + +```shell +curl -i http://127.0.0.1:9080/post -X POST -d '{ + "tenant_id": 123 +}' +``` + Review Comment: ```suggestion You should receive an `HTTP/1.1 200 OK` response similar to the following: ``` ########## docs/en/latest/plugins/forward-auth.md: ########## @@ -166,6 +167,122 @@ HTTP/1.1 403 Forbidden Location: http://example.com/auth ``` +### Using data from POST body to make decision on Authorization service + +::: note +When the decision is to be made on the basis of POST body, then it is recommended to use `$post_arg.xyz` with `extra_headers` field and make the decision on Authorization service on basis of headers rather than using POST `request_method` to pass the entire request body to Authorization service. +::: + +Setup Auth service to extract `tenant_id` from header. + +```shell +curl -X PUT 'http://127.0.0.1:9180/apisix/admin/routes/auth' \ + -H "X-API-KEY: $admin_key" \ + -H 'Content-Type: application/json' \ + -d '{ + "uri": "/auth", + "plugins": { + "serverless-pre-function": { + "phase": "rewrite", + "functions": [ + "return function(conf, ctx) + local core = require(\"apisix.core\") + if core.request.header(ctx, \"tenant_id\") then + core.response.set_header(\"X-User-ID\", \"i-am-an-user\"); + core.response.exit(200); + else + core.response.exit(400, \"tenant_id is required\") + end + end" + ] + } + } +}' +``` + +Setup route to extract `tenant_id` from body and pass in the header. + +```shell +curl -X PUT 'http://127.0.0.1:9180/apisix/admin/routes/1' \ + -H "X-API-KEY: $admin_key" \ + -d '{ + "uri": "/post", + "methods": ["POST"], + "plugins": { + "forward-auth": { + "uri": "http://127.0.0.1:9080/auth", + "request_method": "GET", + "extra_headers": {"tenant_id": "$post_arg.tenant_id"} + } + }, + "upstream": { + "nodes": { + "httpbin.org:80": 1 + }, + "type": "roundrobin" + } +}' +``` + +Now if we send the request: + +```shell +curl -i http://127.0.0.1:9080/post -X POST -d '{ + "tenant_id": 123 +}' +``` + +```shell +HTTP/1.1 200 OK +Content-Type: application/json +Content-Length: 491 +Connection: keep-alive +Date: Mon, 07 Jul 2025 06:50:39 GMT +Access-Control-Allow-Origin: * +Access-Control-Allow-Credentials: true +Server: APISIX/3.13.0 Review Comment: <img width="529" alt="image" src="https://github.com/user-attachments/assets/4eab5afa-7b44-4d7f-a5fc-64eaceea5b30" /> ########## docs/en/latest/plugins/forward-auth.md: ########## @@ -166,6 +167,122 @@ HTTP/1.1 403 Forbidden Location: http://example.com/auth ``` +### Using data from POST body to make decision on Authorization service + +::: note +When the decision is to be made on the basis of POST body, then it is recommended to use `$post_arg.xyz` with `extra_headers` field and make the decision on Authorization service on basis of headers rather than using POST `request_method` to pass the entire request body to Authorization service. +::: + +Setup Auth service to extract `tenant_id` from header. + +```shell +curl -X PUT 'http://127.0.0.1:9180/apisix/admin/routes/auth' \ + -H "X-API-KEY: $admin_key" \ + -H 'Content-Type: application/json' \ + -d '{ + "uri": "/auth", + "plugins": { + "serverless-pre-function": { + "phase": "rewrite", + "functions": [ + "return function(conf, ctx) + local core = require(\"apisix.core\") + if core.request.header(ctx, \"tenant_id\") then + core.response.set_header(\"X-User-ID\", \"i-am-an-user\"); + core.response.exit(200); + else + core.response.exit(400, \"tenant_id is required\") + end + end" + ] + } + } +}' +``` + +Setup route to extract `tenant_id` from body and pass in the header. + +```shell +curl -X PUT 'http://127.0.0.1:9180/apisix/admin/routes/1' \ + -H "X-API-KEY: $admin_key" \ + -d '{ + "uri": "/post", + "methods": ["POST"], + "plugins": { + "forward-auth": { + "uri": "http://127.0.0.1:9080/auth", + "request_method": "GET", + "extra_headers": {"tenant_id": "$post_arg.tenant_id"} + } + }, + "upstream": { + "nodes": { + "httpbin.org:80": 1 + }, + "type": "roundrobin" + } +}' +``` + +Now if we send the request: Review Comment: ```suggestion Send a POST request with the `tenant_id` header: ``` ########## docs/en/latest/plugins/forward-auth.md: ########## @@ -166,6 +167,122 @@ HTTP/1.1 403 Forbidden Location: http://example.com/auth ``` +### Using data from POST body to make decision on Authorization service + +::: note +When the decision is to be made on the basis of POST body, then it is recommended to use `$post_arg.xyz` with `extra_headers` field and make the decision on Authorization service on basis of headers rather than using POST `request_method` to pass the entire request body to Authorization service. +::: + +Setup Auth service to extract `tenant_id` from header. + +```shell +curl -X PUT 'http://127.0.0.1:9180/apisix/admin/routes/auth' \ + -H "X-API-KEY: $admin_key" \ + -H 'Content-Type: application/json' \ + -d '{ + "uri": "/auth", + "plugins": { + "serverless-pre-function": { + "phase": "rewrite", + "functions": [ + "return function(conf, ctx) + local core = require(\"apisix.core\") + if core.request.header(ctx, \"tenant_id\") then + core.response.set_header(\"X-User-ID\", \"i-am-an-user\"); + core.response.exit(200); + else + core.response.exit(400, \"tenant_id is required\") + end + end" + ] + } + } +}' +``` + +Setup route to extract `tenant_id` from body and pass in the header. + +```shell +curl -X PUT 'http://127.0.0.1:9180/apisix/admin/routes/1' \ + -H "X-API-KEY: $admin_key" \ + -d '{ + "uri": "/post", + "methods": ["POST"], + "plugins": { + "forward-auth": { + "uri": "http://127.0.0.1:9080/auth", + "request_method": "GET", + "extra_headers": {"tenant_id": "$post_arg.tenant_id"} + } + }, + "upstream": { + "nodes": { + "httpbin.org:80": 1 + }, + "type": "roundrobin" + } +}' +``` + +Now if we send the request: + +```shell +curl -i http://127.0.0.1:9080/post -X POST -d '{ + "tenant_id": 123 +}' +``` + +```shell +HTTP/1.1 200 OK +Content-Type: application/json +Content-Length: 491 +Connection: keep-alive +Date: Mon, 07 Jul 2025 06:50:39 GMT +Access-Control-Allow-Origin: * +Access-Control-Allow-Credentials: true +Server: APISIX/3.13.0 + +{ + "args": {}, + "data": "", + "files": {}, + "form": { + "{\n \"tenant_id\": 123\n}": "" + }, + "headers": { + "Accept": "*/*", + "Content-Length": "23", + "Content-Type": "application/x-www-form-urlencoded", + "Host": "127.0.0.1", + "User-Agent": "curl/8.13.0", + "X-Amzn-Trace-Id": "Root=1-686b6e3f-2fdeff70183e71551f5c5729", + "X-Forwarded-Host": "127.0.0.1" + }, + "json": null, + "origin": "127.0.0.1, 106.215.83.33", + "url": "http://127.0.0.1/post" +} + +``` + +When tenant_id not passed Review Comment: ```suggestion Send a POST request without the `tenant_id` header: ``` ########## docs/en/latest/plugins/forward-auth.md: ########## @@ -166,6 +167,122 @@ HTTP/1.1 403 Forbidden Location: http://example.com/auth ``` +### Using data from POST body to make decision on Authorization service + +::: note +When the decision is to be made on the basis of POST body, then it is recommended to use `$post_arg.xyz` with `extra_headers` field and make the decision on Authorization service on basis of headers rather than using POST `request_method` to pass the entire request body to Authorization service. +::: + +Setup Auth service to extract `tenant_id` from header. + +```shell +curl -X PUT 'http://127.0.0.1:9180/apisix/admin/routes/auth' \ + -H "X-API-KEY: $admin_key" \ + -H 'Content-Type: application/json' \ + -d '{ + "uri": "/auth", + "plugins": { + "serverless-pre-function": { + "phase": "rewrite", + "functions": [ + "return function(conf, ctx) + local core = require(\"apisix.core\") + if core.request.header(ctx, \"tenant_id\") then + core.response.set_header(\"X-User-ID\", \"i-am-an-user\"); + core.response.exit(200); + else + core.response.exit(400, \"tenant_id is required\") + end + end" + ] + } + } +}' +``` + +Setup route to extract `tenant_id` from body and pass in the header. + +```shell +curl -X PUT 'http://127.0.0.1:9180/apisix/admin/routes/1' \ + -H "X-API-KEY: $admin_key" \ + -d '{ + "uri": "/post", + "methods": ["POST"], + "plugins": { + "forward-auth": { + "uri": "http://127.0.0.1:9080/auth", + "request_method": "GET", + "extra_headers": {"tenant_id": "$post_arg.tenant_id"} + } + }, + "upstream": { + "nodes": { + "httpbin.org:80": 1 + }, + "type": "roundrobin" + } +}' +``` + +Now if we send the request: + +```shell +curl -i http://127.0.0.1:9080/post -X POST -d '{ + "tenant_id": 123 +}' +``` + +```shell +HTTP/1.1 200 OK +Content-Type: application/json +Content-Length: 491 +Connection: keep-alive +Date: Mon, 07 Jul 2025 06:50:39 GMT +Access-Control-Allow-Origin: * +Access-Control-Allow-Credentials: true +Server: APISIX/3.13.0 + +{ + "args": {}, + "data": "", + "files": {}, + "form": { + "{\n \"tenant_id\": 123\n}": "" + }, + "headers": { + "Accept": "*/*", + "Content-Length": "23", + "Content-Type": "application/x-www-form-urlencoded", + "Host": "127.0.0.1", + "User-Agent": "curl/8.13.0", + "X-Amzn-Trace-Id": "Root=1-686b6e3f-2fdeff70183e71551f5c5729", + "X-Forwarded-Host": "127.0.0.1" + }, + "json": null, + "origin": "127.0.0.1, 106.215.83.33", + "url": "http://127.0.0.1/post" +} + Review Comment: remove this empty line ########## docs/en/latest/plugins/forward-auth.md: ########## @@ -166,6 +167,122 @@ HTTP/1.1 403 Forbidden Location: http://example.com/auth ``` +### Using data from POST body to make decision on Authorization service + +::: note +When the decision is to be made on the basis of POST body, then it is recommended to use `$post_arg.xyz` with `extra_headers` field and make the decision on Authorization service on basis of headers rather than using POST `request_method` to pass the entire request body to Authorization service. +::: + +Setup Auth service to extract `tenant_id` from header. + +```shell +curl -X PUT 'http://127.0.0.1:9180/apisix/admin/routes/auth' \ + -H "X-API-KEY: $admin_key" \ + -H 'Content-Type: application/json' \ + -d '{ + "uri": "/auth", + "plugins": { + "serverless-pre-function": { + "phase": "rewrite", + "functions": [ + "return function(conf, ctx) + local core = require(\"apisix.core\") + if core.request.header(ctx, \"tenant_id\") then + core.response.set_header(\"X-User-ID\", \"i-am-an-user\"); + core.response.exit(200); + else + core.response.exit(400, \"tenant_id is required\") + end + end" + ] + } + } +}' +``` + +Setup route to extract `tenant_id` from body and pass in the header. + +```shell +curl -X PUT 'http://127.0.0.1:9180/apisix/admin/routes/1' \ + -H "X-API-KEY: $admin_key" \ + -d '{ + "uri": "/post", + "methods": ["POST"], + "plugins": { + "forward-auth": { + "uri": "http://127.0.0.1:9080/auth", + "request_method": "GET", + "extra_headers": {"tenant_id": "$post_arg.tenant_id"} + } + }, + "upstream": { + "nodes": { + "httpbin.org:80": 1 + }, + "type": "roundrobin" + } +}' +``` + +Now if we send the request: + +```shell +curl -i http://127.0.0.1:9080/post -X POST -d '{ + "tenant_id": 123 +}' +``` + +```shell +HTTP/1.1 200 OK +Content-Type: application/json +Content-Length: 491 +Connection: keep-alive +Date: Mon, 07 Jul 2025 06:50:39 GMT +Access-Control-Allow-Origin: * +Access-Control-Allow-Credentials: true +Server: APISIX/3.13.0 + +{ + "args": {}, + "data": "", + "files": {}, + "form": { + "{\n \"tenant_id\": 123\n}": "" + }, + "headers": { + "Accept": "*/*", + "Content-Length": "23", + "Content-Type": "application/x-www-form-urlencoded", + "Host": "127.0.0.1", + "User-Agent": "curl/8.13.0", + "X-Amzn-Trace-Id": "Root=1-686b6e3f-2fdeff70183e71551f5c5729", + "X-Forwarded-Host": "127.0.0.1" + }, + "json": null, + "origin": "127.0.0.1, 106.215.83.33", + "url": "http://127.0.0.1/post" +} + +``` + +When tenant_id not passed + +```shell + curl -i http://127.0.0.1:9080/post -X POST -d '{ + "abc": 123 +}' + + +HTTP/1.1 400 Bad Request +Date: Mon, 07 Jul 2025 06:54:04 GMT +Content-Type: text/plain; charset=utf-8 +Transfer-Encoding: chunked +Connection: keep-alive +Server: APISIX/3.13.0 + +tenant_id is required +``` Review Comment: Change this block to --- ```shell curl -i http://127.0.0.1:9080/post -X POST -d '{ "abc": 123 }' ``` You should receive an `HTTP/1.1 400 Bad Request` response with the following message: ```text tenant_id is required ``` -- 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: notifications-unsubscr...@apisix.apache.org For queries about this service, please contact Infrastructure at: us...@infra.apache.org