nginx: Do not require Basic Authentication only if http request is OPTIONS
Asked Answered
W

2

11

The Authorization Header is not sent with an HTTP OPTIONS Request. I would like disable this authentication only when the request is OPTIONS and leave it on for other requests. Here is the relevant piece of config code I have at the moment. cannot seem to see why it does not work. I always get a 401 Unauthorized Error on OPTIONS request.

    location ~ /foo/bar
    {

      if ($request_method = OPTIONS) {
        set $auth_basic "off";
      }
      if ($request_method != OPTIONS)
      {
        set $auth_basic "Resctricted";
        set $auth_basic_user_file /var/www/.htpasswd;
      }
      auth_basic $auth_basic;
      auth_basic_user_file $auth_basic_user_file;
    }
Weig answered 16/6, 2017 at 21:42 Comment(0)
B
14

It looks like it is an old post, but found this solution :

Put the following configuration inside "location" and remove any auth_basic from server. This will work

  location / {
    # Your node proxy configuration for example #

    # Make options requests work #
    limit_except OPTIONS {
      auth_basic "Restricted access zone";
      auth_basic_user_file /etc/nginx/pass/protected;
    }
  }
Beheld answered 9/2, 2018 at 15:13 Comment(1)
Thanks, this is the simplest answer, confirmed that it works. It's really not clear from the nginx documentation that limit_except will achieve this. – Bray
J
4

The simplest way to deal with this is allow nginx to handle the OPTIONS request:

server {
    listen 80;
    server_name  example.com;
    root /var/www;

    auth_basic "Resctricted";
    auth_basic_user_file /var/www/.htpasswd;

    location / {
        if ($request_method = OPTIONS) {
            add_header Access-Control-Allow-Origin "http://example.com";
            add_header Access-Control-Allow-Methods "GET, OPTIONS";
            add_header Access-Control-Allow-Headers "Authorization";
            add_header Access-Control-Allow-Credentials "true";
            add_header Content-Length 0;
            add_header Content-Type text/plain;
            return 200;
        }
    }
}

This will allow OPTIONS to get a response without requiring authentication:

scott@Carl www $ curl -i -X OPTIONS http://example.com
HTTP/1.1 200 OK
Server: nginx
Date: Sat, 17 Jun 2017 00:09:52 GMT
Content-Type: application/octet-stream
Content-Length: 0
Connection: keep-alive
Access-Control-Allow-Origin: http://example.com
Access-Control-Allow-Methods: GET, OPTIONS
Access-Control-Allow-Headers: Authorization
Access-Control-Allow-Credentials: true
Content-Length: 0
Content-Type: text/plain

scott@Carl www $ curl -i http://example.com
HTTP/1.1 401 Unauthorized
Server: nginx
Date: Sat, 17 Jun 2017 00:09:59 GMT
Content-Type: text/html
Content-Length: 188
Connection: keep-alive
WWW-Authenticate: Basic realm="Resctricted"

<html>
<head><title>401 Authorization Required</title></head>
<body bgcolor="white">
<center><h1>401 Authorization Required</h1></center>
<hr><center>nginx</center>
</body>
</html>
Johannesburg answered 17/6, 2017 at 0:13 Comment(3)
Thanks for your answer. I came up with this with your help. Woudn't this be right? The authentication code have to be there because this is the only location that requires it. I still get a 401 Unauthorized. location ~ /foo/bar/ { if ($request_method = OPTIONS) { ... return 200; } auth_basic "Restricted"; auth_basic_user_file /var/www/.htpasswd; } – Weig
thx @Johannesburg - finally after hours I got right answer that "Methods: OPTIONS" cannot by behind AUTH πŸ™ˆπŸ˜„ – Streamlined
The key to this answer is in the return 200;, which doesn't let the suthentication handler take over once the response is done. I had that part missing and authentication was being enforced even for OPTIONS – Jobholder

© 2022 - 2024 β€” McMap. All rights reserved.