Configure basic auth in nginx only for specific HTTP methods
β’ 255 words β’ ~2 min read β²
I am using nginx as reverse proxy for a handful of small applications. I recently added one where for convenience I only wanted to require basic authentication for the endpoints that write data.
The nginx configuration files are not exactly my daily concern, so to save future me (or maybe future you) some headaches with trial and error, here is what worked (and what didn't).
As I wanted to only secure POST requests, my first attempt was to formulate it using positive logic with an if directive. Didn't work out and the good folks at nginx even wrote an article about why if is evil when used in location context - which happens to be exactly the context I was in.
The alternative is to enumerate HTTP methods as being exempt from authentication in a limit_except directive. If you model your API like a halfway sane person (and not for instance use GraphQL...) that means GET (HEAD and OPTIONS could be thrown in for good measure). But beware: the proxy_pass directive must not be put into the limit_except block. It will make the nginx config invalid. nginx -t
will yell at you, and if you restart anyway, or like a certain person don't bother to testing the config changes before you restart, the server will crash immediately.
So, the final snippet looks like this:
location /my-application/api/ {
limit_except GET {
auth_basic "Restricted";
auth_basic_user_file /path/to/.htpasswd;
}
proxy_pass http://127.0.0.1:12345/;
proxy_buffering off;
proxy_set_header Host https://$host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}