6

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?

sdude
  • 291
  • 1
  • 2
  • 10

3 Answers3

13

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.

sdude
  • 291
  • 1
  • 2
  • 10
  • Wow, that really helped me, although I am not using Jira in Tomcat, but in the default Jetty container. – Stephan Feb 24 '14 at 15:38
  • 1
    THX this helped me with totally unrelated problem with combination NginX - Jenkins (Jetty server) – equivalent8 May 07 '14 at 13:44
  • @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? – skålfyfan Feb 23 '16 at 03:47
  • @skålfyfan don't know dude that was year ago :) but I briefly remember that may be the case :) – equivalent8 Feb 23 '16 at 18:20
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.

Ville
  • 247
  • 2
  • 11
-2

This works until you hit authenticated resources, which send back a 401 header to the client through the proxy which triggers a pop-up.

Below is From https://answers.atlassian.com/questions/2515/answers/39133735?flashId=366096075

This is super freaking old thread, but for anyone else who's come here with this issue. The work around is to unset the Authorization header when using Apache2 as a reverse proxy.

RequestHeader unset Authorization

The same can be done with NGiNX

proxy_set_header Authorization "";

This works great and solves the issue.

However, if your confluence installation allows anonymous access, and the authentication used with NGiNX/Apache2 isn't the same as Confluence. You'll run into pop-ups for specific elements.

For instance the following link "rest/mywork/latest/status/notification/new"

<status>
<status-code>401</status-code>
<message>
Client must be authenticated to access this resource.
</message>
</status>