Skip to main content
Version: 3.0.0-beta

forward-auth

Description#

The forward-auth Plugin implements a classic external authentication model. When authentication fails, you can have a custom error message or redirect the user to an authentication page.

This Plugin moves the authentication and authorization logic to a dedicated external service. APISIX forwards the user's requests to the external service, blocks the original request, and replaces the result when the external service responds with a non 2xx status code.

Attributes#

NameTypeRequiredDefaultValid valuesDescription
uristringTrueURI of the authorization service.
ssl_verifybooleanFalsetrueWhen set to true, verifies the SSL certificate.
request_methodstringFalseGET["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_headersarray[string]FalseClient request headers to be sent to the authorization service. If not set, only the headers provided by APISIX are sent (for example, X-Forwarded-XXX).
upstream_headersarray[string]FalseAuthorization service response headers to be forwarded to the Upstream. If not set, no headers are forwarded to the Upstream service.
client_headersarray[string]FalseAuthorization service response headers to be sent to the client when authorization fails. If not set, no headers will be sent to the client.
timeoutintegerFalse3000ms[1, 60000]msTimeout for the authorization service HTTP call.
keepalivebooleanFalsetrueWhen set to true, keeps the connection alive for multiple requests.
keepalive_timeoutintegerFalse60000ms[1000, ...]msIdle time after which the connection is closed.
keepalive_poolintegerFalse5[1, ...]msConnection pool limit.

Data definition#

APISIX will generate and the send the request headers listed below to the authorization service:

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

Example usage#

First, you need to setup your external authorization service. The example below uses Apache APISIX's serverless Plugin to mock the service:

curl -X PUT 'http://127.0.0.1:9180/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"
]
}
}
}'

Now you can configure the forward-auth Plugin to a specific Route:

curl -X PUT 'http://127.0.0.1:9180/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"
}
}'

Now if we send the authorization details in the request header:

curl http://127.0.0.1:9080/headers -H 'Authorization: 123'
{
"headers": {
"Authorization": "123",
"Next": "More-headers"
}
}

The authorization service response can also be forwarded 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"
}
}

When authorization fails, the authorization service can send custom response back to the user:

curl -i http://127.0.0.1:9080/headers
HTTP/1.1 403 Forbidden
Location: http://example.com/auth

Disable Plugin#

To disable the forward-auth Plugin, you can delete the corresponding JSON configuration from the Plugin configuration. APISIX will automatically reload and you do not have to restart for this to take effect.

curl http://127.0.0.1:9180/apisix/admin/routes/1 -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -d '
{
"methods": ["GET"],
"uri": "/hello",
"plugins": {},
"upstream": {
"type": "roundrobin",
"nodes": {
"127.0.0.1:1980": 1
}
}
}'