3

I've setup nginx as a reverse proxy to gunicorn for a django site running on Heroku. I'm using Anymail for my mailing list, and it needs to receive basic auth credentials for webhooks (I don't actually need to set up basic auth, I just need to pass the header with credentials along).

I can't seem to pass the credentials to the server though.

The weird thing is that this works and I can access the HTTP_AUTHORIZATION header in Django, which has the value "test", as expected:

proxy_set_header Authorization "test"; 

But this doesn't work, and no HTTP_AUTHORIZATION header is found by Django:

proxy_set_header Authorization $http_authorization; 

Here's my nginx.conf.erb:

daemon off;
#Heroku dynos have at least 4 cores.
worker_processes <%= ENV['NGINX_WORKERS'] || 4 %>;

events {
    use epoll;
    accept_mutex on;
    worker_connections 1024;
}

http {

    server_tokens off;

    include mime.types;
    default_type application/octet-stream;

    #Must read the body in 5 seconds.
    client_body_timeout 5;

    upstream app_server {
        server unix:/tmp/nginx.socket fail_timeout=0;
    }

    server {
        listen <%= ENV["PORT"] %>;

        server_name example.com "";

        keepalive_timeout 5;

        location / {

            proxy_set_header Host $host;
            proxy_pass http://app_server;

        }

        location /authtest {

            proxy_set_header Host $host;
            proxy_pass http://app_server;

            # this doesn't work - no HTTP_AUTHORIZATION header found by Django
            #proxy_set_header Authorization $http_authorization; 

            # this does work and returns the value "test" for the HTTP_AUTHORIZATION header 
            proxy_set_header Authorization "test"; 

            # tested enabling and disabling these, they don't appear to make a difference
            #proxy_pass_header Authorization; 
            #proxy_set_header X-Forwarded-User $remote_user;

        }

    }
}
Lewy Blue
  • 151
  • 1
  • 7
  • It sounds like nginx *by default* [proxies all headers](https://docs.nginx.com/nginx/admin-guide/web-server/reverse-proxy/#passing-request-headers) except Host and Connection, so by default I'd expect the auth header to be proxied. What happens if you just *completely omit* the entire `location /authtest {...}` block, so that everything is handled by the simple proxy `location / {...}` block? – medmunds Aug 04 '18 at 17:27

1 Answers1

1

OK, I found the problem - I've been testing on this on Chrome and Firefox by typing foo:bar@mysite.com/authtest into the URL bar.

Turns out that recently these browsers have started to silently strip the credentials unless there is actually basic auth set up on the page. Since I just want to pass along the credential to Django, there is no basic auth on the page so they were stripped.

Testing with https://httpstatus.io/ and setting the header explicitly, and the credentials are passed correctly.

Lewy Blue
  • 151
  • 1
  • 7