Signup/Sign In
PUBLISHED ON: MARCH 10, 2023

Add authentication to any app with nginx

Have you ever felt hesitant to write the necessary code to handle OAuth 2.0 or passwords despite wishing to hide an application behind a login form? In this tutorial, We'll demonstrate how to utilise the nginx auth request module to automatically implement OAuth 2.0 protection for any application running on top of your nginx server. You don't have to worry about the OAuth dance since Vouch, a Go microservice, takes care of it for you.

How to use nginx auth_request module?

Although it is included with nginx, this module needs to be enabled during nginx compilation. Simply include the --with_http_auth_request module flag when compiling nginx after downloading the source code.

Every time a request comes in, the auth_request module forwards it to a different server to determine whether the user is authenticated. It then uses the HTTP response to determine whether to allow the request to continue to the backend server. This module sits between the internet and your backend server that nginx passes requests onto.

Configure Your Protected nginx Host

Starting with a typical nginx server block, you just need to add a couple lines to enable the auth_request module. Here is an example server block that should look similar to your own config. This example just serves a folder of static HTML files, but the same idea applies whether you’re passing the request on to a fastcgi backend or using proxy_pass.

server {
  listen 443 ssl http2;
  server_name leet.domain.com;

  ssl_certificate /etc/letsencrypt/live/domain.com/fullchain.pem;
  ssl_certificate_key /etc/letsencrypt/live/domain.com/privkey.pem;

  root /web/sites/leet.domain.com;

  index index.html;
}

Instead of having to worry about the complexities of the OAuth dance, you can use the Vouch microservice to take care of it for you. In this tutorial, we will show you how to use the auth_request module and Vouch to add OAuth 2.0 protection to your application.

Steps to configure authentication with Nginx and Vouch:

  1. Compile nginx with the --with_http_auth_request module flag. This enables the auth_request module, which allows you to forward requests to a different server to determine whether the user is authenticated.

  2. Add the following lines to your existing nginx server block to enable the auth_request module:

# Any request to this server will first be sent to this URL
auth_request /vouch-validate;

location = /vouch-validate {
  # This address is where Vouch will be listening on
  proxy_pass http://127.0.0.1:8080/validate;
  proxy_pass_request_body off;

  proxy_set_header Content-Length "";
  proxy_set_header X-Real-IP $remote_addr;
  proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
  proxy_set_header X-Forwarded-Proto $scheme;

  # these return values are passed to the @error401 call
  auth_request_set $auth_resp_jwt $upstream_http_x_vouch_jwt;
  auth_request_set $auth_resp_err $upstream_http_x_vouch_err;
  auth_request_set $auth_resp_failcount $upstream_http_x_vouch_failcount;
}

error_page 401 = @error401;

# When the user is not logged in, redirect them to Vouch's login URL
location @error401 {
  return 302 https://login.domain.com/login?url=https://$http_host$request_uri&vouch-failcount=$auth_resp_failcount&X-Vouch-Token=$auth_resp_jwt&error=$auth_resp_err;
}

The auth_request directive tells the auth_request module to send any request to the specified URL (/vouch-validate in this case) before deciding whether it is allowed to continue to the backend server. The location block captures that URL and proxies it to the Vouch server that will be listening on port 8080. The proxy_pass_request_body off directive tells nginx not to send the POST body to Vouch, since we only care about the cookie.

The error_page directive tells nginx what to do if Vouch returns an HTTP 401 response (indicating that the user is not authenticated), which is to pass it to the location block defined by @error401. This location block will redirect the user's browser to Vouch's login URL, which will kick off the flow to the real authentication backend.

  1. Configure a new server block for Vouch so that it has a publicly accessible URL, such as https://login.domain.com. This server

    block should proxy the request to the backend Vouch server on http://127.0.0.1:8080/validate. Here is an example Vouch server block:

    server {
      listen 443 ssl http2;
      server_name login.domain.com;
    
      ssl_certificate /etc/letsencrypt/live/domain.com/fullchain.pem;
      ssl_certificate_key /etc/letsencrypt/live/domain.com/privkey.pem;
    
      location / {
        # This address is where Vouch will be listening on
        proxy_pass http://127.0.0.1:8080;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
      }
    }
    

    This server block listens on port 443 (HTTPS) and proxies requests to the backend Vouch server on http://127.0.0.1:8080. It also sets the appropriate headers for the proxied request.

  2. Configure Vouch to use the desired OAuth provider and any necessary parameters. This will depend on the specific provider you are using, so please refer to the Vouch documentation for more information.

  3. Restart nginx to apply the changes with systemctl restart nginx

Conclusion

In this tutorial, we have demonstrated how to use the nginx auth_request module and Vouch to implement OAuth 2.0 protection for applications running on top of an nginx server. The auth_request module is included with nginx but must be enabled during nginx compilation. The module acts as a reverse proxy, forwarding requests to a different server to determine if the user is authenticated, and then using the response to allow or deny the request to continue to the backend server. Vouch is a Go microservice that handles the authentication process. The tutorial provides detailed instructions on how to configure nginx and Vouch to add authentication to an application.



About the author:
Pradeep has expertise in Linux, Go, Nginx, Apache, CyberSecurity, AppSec and various other technical areas. He has contributed to numerous publications and websites, providing his readers with insightful and informative content.