0

I have two docker services (an angular web-app and a tomcat backend), which I want to protect with a third docker service, which is an nginx configured as a reverse-proxy. My proxy configuration is working, but I'm suffering with the basic authorization my reverse-proxy should also handle. When I protect my angular frontend service with basic auth via reverse-proxy config, everything works fine, but my backend is still exposed for everyone. When I add also basic auth to the backend service, I have the problem, that my basic auth configuration header from my frontend is not forwarded/added to the backend REST requests. Is it possible to configure the nginx reverse proxy to add the Authorization header to each request send by the frontend. Or maybe I'm thinking wrong and there is a better solution?

infrastructure scheme

browser

Here is my docker and nginx configuration:

reverse-proxy config:

worker_processes 1;

events { worker_connections 1024; }

http {

    sendfile on;

    upstream docker-nginx {
        server frontend-nginx:80;
    }

    upstream docker-tomcat {
        server backend-tomcat:8080;
    }

    map $upstream_http_docker_distribution_api_version $docker_distribution_api_version {
        '' 'registry/2.0';
    }

    server {
        listen 80;

        location / {

            auth_basic "Protected area";
            auth_basic_user_file /etc/nginx/conf.d/nginx.htpasswd;

            add_header 'Docker-Distribution-Api-Version' $docker_distribution_api_version always;

            proxy_pass         http://docker-nginx;
            proxy_redirect     off;
        }
    }

    server {
        listen 8080;

        location / {

            auth_basic "Protected area";
            auth_basic_user_file /etc/nginx/conf.d/nginx.htpasswd;

            add_header 'Docker-Distribution-Api-Version' $docker_distribution_api_version always;

            proxy_pass         http://docker-tomcat;
            proxy_redirect     off;
        }
    }

}

docker-compose (setting up all containers):

version: '2.4'

services:
  reverse-proxy:
    container_name: reverse-proxy
    image: nginx:alpine
    volumes:
      - ./auth:/etc/nginx/conf.d
      - ./auth/nginx.conf:/etc/nginx/nginx.conf:ro
    ports:
      - "80:80"
      - "8080:8080"
    restart: always
    links:
      - registry:registry

  frontend-nginx:
    container_name: frontend
    build: './frontend'
    volumes:
      - /dockerdev/frontend/dist/:/usr/share/nginx/html
    depends_on:
          - reverse-proxy
          - bentley-tomcat
    restart: always

  backend-tomcat:
    container_name: backend
    build: './backend'
    volumes:
      - /data:/data
    depends_on:
      - reverse-proxy
    restart: always

  registry:
    image: registry:2
    ports:
      - 127.0.0.1:5000:5000
    volumes:
      - ./data:/var/lib/registry

frontend Dockerfile:

FROM nginx
COPY ./dist/ /usr/share/nginx/html
COPY ./fast-nginx-default.conf /etc/nginx/conf.d/default.conf

frontend config:

server {
  listen 80;
  sendfile on;
  default_type application/octet-stream;

  gzip on;
  gzip_http_version 1.1;
  gzip_disable      "MSIE [1-6]\.";
  gzip_min_length   256;
  gzip_vary         on;
  gzip_proxied      expired no-cache no-store private auth;
  gzip_types        text/plain text/css application/json application/javascript application/x-javascript text/xml application/xml application/xml+rss text/javascript;
  gzip_comp_level   9;

  root /usr/share/nginx/html;

  location / {
    try_files $uri $uri/ /index.html =404;
  }
}

backend Dockerfile:

FROM openjdk:11
RUN mkdir -p /usr/local/bin/tomcat
COPY ./backend-0.0.1-SNAPSHOT.jar /usr/local/bin/tomcat/backend-0.0.1-SNAPSHOT.jar
WORKDIR /usr/local/bin/tomcat
CMD ["java", "-jar", "backend-0.0.1-SNAPSHOT.jar"]
Ole
  • 161
  • 1
  • 3
  • 12

2 Answers2

1

Try adding this directives to your location block

proxy_set_header Authorization $http_authorization;
proxy_pass_header  Authorization;
Thomas Sablik
  • 16,127
  • 7
  • 34
  • 62
  • I already tried to add both directives, but the header is not added to my frontend REST request to the backend. – Ole Dec 02 '18 at 15:48
  • Now I understand, I think. Your angular client send request to the backend. You need to add the Authorization header to your angular client. Remember that angular is frontend. That means that the user downloads the code and executes it on the client computer outside of your network. – Thomas Sablik Dec 03 '18 at 09:14
0

I've solved my issue, by listining on port 80 for request with /api and redirected them to the tomcat on port 8080. For that I also had to adjust my front- and backend requests, now all my backend request begin with /api. By this solution I'm able to implement the basic auth on port 80 for protecting the front- and backend.

worker_processes 1;

events { worker_connections 1024; }

http {

    sendfile on;

    client_max_body_size 25M;

    upstream docker-nginx {
        server frontend-nginx:80;
    }

    upstream docker-tomcat {
        server backend-tomcat:8080;
    }

    server {
        listen 80;

        location /api {

            proxy_pass http://docker-tomcat;
        }

    location / {

            auth_basic "Protected area";
            auth_basic_user_file /etc/nginx/conf.d/nginx.htpasswd;

            proxy_pass         http://docker-nginx;
            proxy_redirect     off;
        }
    }
}
Ole
  • 161
  • 1
  • 3
  • 12