Nginx auth_basic 401 htpasswd

nginx

I've got this strange error:

I have a Jenkins service running in 8090 which I want to password protect via Nginx auth_basic with proxy_pass
When doing the proxy-pass without auth_basic, I can access the site without issues:

server {
  listen 8080;
  location / {
    proxy_pass http://localhost:8090;
    proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504;
    proxy_redirect off;
    proxy_buffering off;
    proxy_pass_header Authorization;
    proxy_set_header        Host            $host;
    proxy_set_header        X-Real-IP       $remote_addr;
    proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
    # auth_basic "Restricted";                   #For Basic Auth
    # auth_basic_user_file /etc/nginx/htpasswd;  #For Basic Auth
  }
}

However, when uncommenting the two auth lines. I get the expected login page in the browser. If I enter invalid credentials, I get the expected errors in nginx/error.log:

(wrong user)

2014/07/30 18:59:58 [error] 15374#0: *1 user "afds" was not found in
"/etc/nginx/htpasswd", client: xx.xx.xx.xx, server: example.com,
request: "GET /job/xyz HTTP/1.1", host: "example.com:8080"

(good user, wrong password)

2014/07/30 19:01:43 [error] 15374#0: *44 user "jenkins": password
mismatch, client: xx.xx.xx.xx, server: example.com, request: "GET
/job/xyz HTTP/1.1", host: "example.com:8080"

But, if I enter the right user/password combination, I dont get anything in nginx/error.log but instead I get the following in nginx/access.log

xx.xx.xx.xx – jenkins [30/Jul/2014:19:03:53 -0500] "GET /job/xyz
HTTP/1.1" 401 278 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_4)
AppleWebKit/537.36 (KHTML, like Gecko) Chrome/36.0.1985.125
Safari/537.36"

And the browser asks for the password again.

Any idea why this is happening?

Best Answer

As @Lukas explained it, forwarding the Authorization header to the backend will makes your client attempting to authenticate with it. As you probably have not defined any authentication in your backend, it will answer with a 401, as the RFC 2617 requires:

If the origin server does not wish to accept the credentials sent with a request, it SHOULD return a 401 (Unauthorized) response.

Your backend has nothing to do with the authentication, since it is done by/with the proxy. Do not proxy that header field.

If you wish your backend to authenticate the client again on its side, you should activate auth_basic there too, with the same user/password database. Be careful when managing users, you would have 2 copies to keep synchronized now...