Authentication Based on Subrequest Result
Introduction
NGINX and NGINX Plus can authenticate each request to your website with an external server or service. To perform authentication, NGINX makes an HTTP subrequest to an external server where the subrequest is verified. If the subrequest returns a 2xx
response code, the access is allowed, if it returns 401
or 403
, the access is denied. Such type of authentication allows implementing various authentication schemes, such as multifactor authentication, or allows implementing LDAP or OAuth authentication.
Prerequisites
- NGINX Plus or NGINX Open Source
- External authentication server or service
Configuring NGINX and NGINX Plus
Make sure your NGINX Open Source is compiled with the
with-http_auth_request_module
configuration option. Run this command and verify that the output includes--with-http_auth_request_module
:$ nginx -V 2>&1 | grep -- 'http_auth_request_module'
Skip this step for NGINX Plus as it already includes the auth_request module.
In the location that requires request authentication, specify the
auth_request
directive in which specify an internal location where an authorization subrequest will be forwarded to:location /private/ { auth_request /auth; #... }
Here, for each request to /private, a subrequest to the internal /auth location will be made.
Specify an internal location and the
proxy_pass
directive inside this location that will proxy authentication subrequests to an authentication server or service:location = /auth { internal; proxy_pass http://auth-server; #... }
As the request body is discarded for authentication subrequests, you will need to set the
proxy_pass_request_body
directive tooff
and also set theContent-Length
header to a null string:location = /auth { internal; proxy_pass http://auth-server; proxy_pass_request_body off; proxy_set_header Content-Length ""; #... }
Pass the full original request URI with arguments with the
proxy_set_header
directive:location = /auth { internal; proxy_pass http://auth-server; proxy_pass_request_body off; proxy_set_header Content-Length ""; proxy_set_header X-Original-URI $request_uri; }
As an option, you can set a variable value basing on the result of the subrequest with the
auth_request_set
directive:location /private/ { auth_request /auth; auth_request_set $auth_status $upstream_status; }
Complete Example
This example sums up the previous steps into one configuration:
http {
#...
server {
#...
location /private/ {
auth_request /auth;
auth_request_set $auth_status $upstream_status;
}
location = /auth {
internal;
proxy_pass http://auth-server;
proxy_pass_request_body off;
proxy_set_header Content-Length "";
proxy_set_header X-Original-URI $request_uri;
}
}
}