Using basic authentication is a very quick way to protect a resource behind a proxy, however it does have a few drawbacks:
- It’s another set of passwords to maintain, will you actually rotate it after an employee leaves?
- The password is sent with every request with basic auth
- If the proxy isn’t configured using TLS then the password is transmitted in base 64 which can be decoded.
Here I present a way for Nginx to delegate the authentication. This allows the authentication logic to be handled by any programming language of your choice, allowing you to validate JWTs, check for cookies etc.
How it works
Nginx receives a request, and then sends a subrequest to your authentication backend, if that deems the request to be authenticated, it will then continute to proxy through to your protected application.
Contribute to Juddling/nginx-auth-request-example development by creating an account on GitHub.
We use Nginx’s auth_request module which will send a subrequest to your auth backend:
If the subrequest returns a 2xx response code, the access is allowed. If it returns 401 or 403, the access is denied with the corresponding error code.
In my example repo, I’ve written an example auth backend in Node.js, which just checks for the presences of a header, in practice yours will be validating JWTs / checking for cookies.
Possible use cases:
- My actual use case: Protecting an S3 bucket behind Cloudflare Access, TLDR: CF Access integrates with third-party auth, makes the user log in, then forwards you a header with JWT that you should validate.
- The hype around Go is too much for you, and you want to use it in your existing project — Easy: Add a location block to handle the subset of Go requests, add the auth_request directive in that block to delegate off to a handler you have written which return 200/403 and then your Go subset is protected
I’ve written a fully working example that you can run in docker, which protects a static HTML document.