Basic auth for a Tomcat app (JIRA) with Nginx as reverse proxy

12,084

Solution 1

Ok just found the solution on the nginx mailing list. I just had to tell nginx to not forward the auth headers to tomcat. Adding a couple of lines to the location blocks in nginx.conf did the trick:

  location / {
        proxy_set_header X-Forwarded-Host $host;
        proxy_set_header X-Forwarded-Server $host;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_pass http://127.0.0.1:8090/;
        proxy_redirect off;

        # Password
        auth_basic "Restricted";
        auth_basic_user_file /home/passwd/.htpasswd;

        # Don't forward auth to Tomcat
        proxy_set_header   Authorization "";
    }

Now i just have to figure out how to prevent nginx from asking for auth on each subdomain (jira, confluence, stash, etc). Having to introduce the credentials just once for all of them would be perfect, but that's another issue.

Hope this helps!

Cheers.

Solution 2

I had the same problem with Confluence. This was very useful (both the updated question and SDude's answer). I have the proxy params on each sub-path level ("/jira", "/wiki" for Confluence, etc.), so I added proxy_set_header Authorization ""; to each location container in nginx config which fixed the problem. It also cured a weird problem with Stash where Stash was prompting for login password through a browser auth box rather than its own login screen. With the above it now displays the actual login screen.

Share:
12,084

Related videos on Youtube

sdude
Author by

sdude

FinTech products builder.

Updated on September 18, 2022

Comments

  • sdude
    sdude almost 2 years

    I have several subdomains running the Atlassian Tomcat apps (jira.example.com, confluence.example.com, stash.example.com) and I would want to know if it is possible to password protect all of them with basic_auth with .htpasswd.

    Nginx it is working ok without the basic_auth directive, but if I try to introduce it like this in nginx.conf...

    user              nginx;
    worker_processes  1;
    
    error_log         /var/log/nginx/error.log;
    pid               /var/run/nginx.pid;
    
    events {
        worker_connections  1024;
    }
    
    
    http {
    
        include       /etc/nginx/mime.types;
        default_type  application/octet-stream;
    
        log_format  main  '$remote_addr - $remote_user [$time_local] $request '
                          '"$status" $body_bytes_sent "$http_referer" '
                          '"$http_user_agent" "$http_x_forwarded_for"';
    
        access_log  /var/log/nginx/access.log  main;
    
        sendfile        on;
        #tcp_nopush     on;
    
        #keepalive_timeout  0;
        keepalive_timeout  65;
    
        #gzip  on;
    
        # Load config files from the /etc/nginx/conf.d directory
        include /etc/nginx/conf.d/*.conf;
    
        # Our self-signed cert
        ssl_certificate     /etc/ssl/certs/fissl.crt;
        ssl_certificate_key /etc/ssl/private/fissl.key;
    
        # Password
        auth_basic "Restricted";
        auth_basic_user_file /home/passwd/.htpasswd;
    
        # redirect non-ssl Confluence to ssl
        server {
            listen 80;
            server_name  confluence.example.com;
            rewrite ^(.*) https://confluence.example.com$1 permanent;
        }
    
        # redirect non-ssl Jira to ssl
        server {
            listen 80;
            server_name  jira.example.com;
            rewrite ^(.*) https://jira.example.com$1 permanent;
        }
    
        #
        # The Confluence server
        #
        server {
            listen       443;
            server_name  confluence.example.com;
    
            ssl on;
    
            access_log  /var/log/nginx/confluence.access.log  main;
            error_log   /var/log/nginx/confluence.error.log;
    
            location / {
                proxy_pass http://127.0.0.1:8080;
                proxy_set_header X-Forwarded-Proto  https;
                proxy_set_header Host $http_host;            
            }
    
            error_page  404              /404.html;
            location = /404.html {
               root   /usr/share/nginx/html;
            }
    
            redirect server error pages to the static page /50x.html
    
            error_page   500 502 503 504  /50x.html;
            location = /50x.html {
               root   /usr/share/nginx/html;
            }
    
        }
    
        #
        # The Jira server
        #
        server {
            listen       443;
            server_name  jira.example.com;
    
            ssl on;
    
            access_log  /var/log/nginx/jira.access.log  main;
            error_log   /var/log/nginx/jira.error.log;
    
            location / {
                proxy_pass http://127.0.0.1:9090/;
                proxy_set_header X-Forwarded-Proto  https;
                proxy_set_header Host $http_host;
            }
    
            error_page  404              /404.html;
            location = /404.html {
                root   /usr/share/nginx/html;
            }
    
            # redirect server error pages to the static page /50x.html
            #
            error_page   500 502 503 504  /50x.html;
            location = /50x.html {
                root   /usr/share/nginx/html;
            }
    
        }
    }
    

    ..it asks for credentials, but then it returns a

    HTTP Status 401 - Basic Authentication Failure - Reason : AUTHENTICATION_DENIED

    Looks like someone managed to fix this with apache running as reverse proxy http://jira.10933.n7.nabble.com/mod-proxy-and-password-protecting-td17279.html but those links in that thread are dead...

    EDIT: Apparently this issue can be easily solved in Apache adding tomcatAuthentication="false" and using protocol="AJP/1.3" within Tomcat's server.xml connector. Or you can prevent apache from forwarding the auth with the directive RequestHeader unset authorization. Thing is, how to do it with Nginx? I guess I have to research more.. Any insights?

  • equivalent8
    equivalent8 about 10 years
    THX this helped me with totally unrelated problem with combination NginX - Jenkins (Jetty server)
  • skålfyfan
    skålfyfan over 8 years
    @equivalent8 pretty certain it just helped me fix the exact the same issue you had (nginx - Jenkins). Were you getting double prompted for authentication? Once by nginx, then by Jetty/Jenkins?
  • equivalent8
    equivalent8 over 8 years
    @skålfyfan don't know dude that was year ago :) but I briefly remember that may be the case :)