Skip to main content
Version: 2.13

forward-auth

Description#

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.

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.

Attributes#

NameTypeRequirementDefaultValidDescription
uristringrequiredAuthorization service uri (eg. https://localhost/auth)
ssl_verifybooleanoptionaltrueWhether to verify the certificate
request_headersarray[string]optionalclient 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_headersarray[string]optionalauthorization 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_headersarray[string]optionalauthorization 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.
timeoutintegeroptional3000ms[1, 60000]msAuthorization service HTTP call timeout
keepalivebooleanoptionaltrueHTTP keepalive
keepalive_timeoutintegeroptional60000ms[1000, ...]mskeepalive idle timeout
keepalive_poolintegeroptional5[1, ...]msConnection pool limit

Data Definition#

The request headers in the following list will have APISIX generated and sent to the authorization service.

SchemeHTTP MethodHostURISource IP
X-Forwarded-ProtoX-Forwarded-MethodX-Forwarded-HostX-Forwarded-UriX-Forwarded-For

Example#

First, you need to setup an external authorization service. Here is an example of using Apache APISIX's serverless plugin to mock.

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"
]
}
}
}'

Next, we create a route for testing.

curl -X PUT 'http://127.0.0.1:9080/apisix/admin/routes/1' \
-H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' \
-d '{
"uri": "/headers",
"plugins": {
"forward-auth": {
"uri": "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
curl http://127.0.0.1:9080/headers -H 'Authorization: 123'
{
"headers": {
"Authorization": "123",
"Next": "More-headers"
}
}
  1. upstream_headers Send authorization service response header to the upstream
curl http://127.0.0.1:9080/headers -H 'Authorization: 321'
{
"headers": {
"Authorization": "321",
"X-User-ID": "i-am-user",
"Next": "More-headers"
}
}
  1. client_headers Send authorization service response header to client when authorizing failed
curl -i http://127.0.0.1:9080/headers
HTTP/1.1 403 Forbidden
Location: http://example.com/auth

Finally, you can disable the forward-auth plugin by removing it from the route.