Project: APISIX (Orchestration & Management / API Gateway)
File: forward-auth.md

title: forward-auth keywords: Apache APISIX API Gateway Plugin Forward Authentication forward-auth description: This document contains information about the Apache APISIX forward-auth Plugin. <!-- --> 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. | Name | Type | Required | Default | Valid values | Description | | -- | - | -- | - | -- | - | | 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_headers | array[string] | False | | | Client 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_headers | array[string] | False | | | Authorization service response headers to be forwarded to the Upstream. If not set, no headers are forwarded to the Upstream service. | | client_headers | array[string] | False | | | Authorization service response headers to be sent to the client when authorization fails. If not set, no headers will be sent to the client. | | timeout | integer | False | 3000ms | [1, 60000]ms | Timeout for the authorization service HTTP call. | | keepalive | boolean | False | true | | When set to `true`, keeps the connection alive for multiple requests. | | keepalive_timeout | integer | False | 60000ms | [1000, ...]ms | Idle time after which the connection is closed. | | keepalive_pool | integer | False | 5 | [1, ...]ms | Connection pool limit. | | allow_degradation | boolean | False | false | | When set to `true`, allows authentication to be skipped when authentication server is

| | statusonerror | integer | False | 403 | [200,...,599] | Sets the HTTP status that is returned to the client when there is a network error to the authorization service. The default status is 403 (HTTP Forbidden). | APISIX will generate and send the request headers listed below to the authorization service: | Scheme | HTTP Method | Host | URI | Source IP | | -- | | - | | | | X-Forwarded-Proto | X-Forwarded-Method | X-Forwarded-Host | X-Forwarded-Uri | X-Forwarded-For | First, you need to setup your external authorization service. The example below uses Apache APISIX's Plugin to mock the service: :::note You can fetch the `admin_key` from `config.yaml` and save to an environment variable with the following command: ```bash adminkey=$(yq '.deployment.admin.adminkey[0].key' conf/config.yaml | sed 's/"//g') ``` ::: ```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\"); 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: ```shell curl -X PUT 'http://127.0.0.1:9180/apisix/admin/routes/1' \ -H "X-API-KEY: $admin_key" \ -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: ```shell 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: ```shell 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: ```shell curl -i http://127.0.0.1:9080/headers ``` ``` HTTP/1.1 403 Forbidden Location: http://example.com/auth ``` To remove 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. ```shell curl http://127.0.0.1:9180/apisix/admin/routes/1 -H "X-API-KEY: $admin_key" -X PUT -d ' { "methods": ["GET"], "uri": "/hello", "plugins": {}, "upstream": { "type": "roundrobin", "nodes": { "127.0.0.1:1980": 1 } } }' ```