user3133542
user3133542

Reputation: 1715

Authentification with keycloak behind a reverse proxy is failing

Following setup is done:

I've created a docker-container for postgres-database, java application, keycloak and nginx-server (running an angularjs-app) each one separately.

With docker-compose the resulting setup is:

version: '3.3'
services:
  nginx:
    build:
      context: frontend
    image: 127.0.0.1:5000/abe_frontend
    ports:
      - "80:80"
    logging:
      driver: "json-file"
      options:
        max-size: "100k"
        max-file: "10"
    restart: unless-stopped

  backend:
    build:
      context: backend
    image: 127.0.0.1:5000/abe_backend
    volumes:
      - ./data/abe_backend/data:/abedata
    expose:
      - "8080"
    depends_on:
      - postgres
    environment:
      SPRING_PROFILES_ACTIVE: docker
      SPRING_DATASOURCE_URL: jdbc:postgresql://postgres:5432/abe_db
      DB_USER: abe_user
      DB_PASSWORD: test
      KEYCLOAK_ENABLED: "true"
      KEYCLOAK_URL: "http://keycloak:8080/auth"
     KEYCLOAK_REALM: abe
      KEYCLOAK_RESOURCE: "abe_backend"
    logging:
      driver: "json-file"
      options:
        max-size: "100k"
        max-file: "10"
    restart: unless-stopped


  postgres:
    build:
      context: postgres
    image: 127.0.0.1:5000/abe_postgres
    volumes:
      - ./data/postgres/data:/var/lib/postgresql/data
    ports:
      - "5432:5432"
    environment:
      POSTGRES_DB: postgres
      POSTGRES_USER: admin
      POSTGRES_PASSWORD: "test"
      PG_DATA: "/var/lib/postgresql/data/pgdata"
      KEYCLOAK_DB: "keycloak_db"
      KEYCLOAK_DB_USER: "keycloak_admin"
      KEYCLOAK_DB_PASSWORD: "test"
      ABE_DB: "abe_db"
      ABE_DB_USER: "abe_user"
      ABE_DB_PASSWORD: "test"
    logging:
      driver: "json-file"
      options:
        max-size: "200k"
        max-file: "10"

  keycloak:
    build:
      context: keycloak
    image: 127.0.0.1:5000/abe_keycloak
#    expose:
#      - "8080"
    ports:
      - "8282:8080"
    depends_on:
      - postgres
    environment:
      DB_VENDOR: "POSTGRES"
      DP_PORT: "5432"
      DB_ADDR: "postgres"
      DB_DATABASE: "keycloak_db"
      DB_USER: "keycloak_admin"
      DB_PASSWORD: "test"
      KEYCLOAK_USER: "admin"
      KEYCLOAK_PASSWORD: "test"
      PROXY_ADDRESS_FORWARDING: "true"
    logging:
      driver: "json-file"
      options:
        max-size: "200k"
        max-file: "10"

keycloak.json in the angularjs.app is downloaded from keycloak server:

{
  "realm": "abe",
  "auth-server-url": "http://localhost:8282/auth/",
  "ssl-required": "external",
  "resource": "abe_frontend",
  "public-client": true,
  "confidential-port": 0
}

reverse nginx-proxy passes requests for frontend and keycloak:

location /service {
    include /etc/nginx/cors.conf;
    proxy_set_header Host $host;
    proxy_pass http://backend:8080/;
}

location /auth/ {
    proxy_pass http://keycloak:8080/auth/;
    proxy_set_header    Host               $host;
    proxy_set_header    X-Real-IP          $remote_addr;
    proxy_set_header    X-Forwarded-For    $proxy_add_x_forwarded_for;
    proxy_set_header    X-Forwarded-Host   $host;
    proxy_set_header    X-Forwarded-Server $host;
    proxy_set_header    X-Forwarded-Port   $server_port;
    proxy_set_header    X-Forwarded-Proto  $scheme;
}

Now when I start the angularjs-app in localhost:80, i get following error in the console outputs of the backend container:

 Failed to verify token: org.keycloak.common.VerificationException: Invalid token issuer. Expected 'http://keycloak:8080/auth/realms/abe', but was 'http://localhost:8282/auth/realms/abe'

Upvotes: 3

Views: 4888

Answers (1)

bsaverino
bsaverino

Reputation: 1285

As you have a proxy in front of Keycloak and your frontend, you must make use of it and ensure that the token issuer, auth server and url are the same.

Assuming that you access your application through the proxy (localhost:80), then in your case a valid configuration could be:

"auth-server-url": "http://localhost/auth/"

and

location /auth/ {
    ...
    proxy_set_header    Host               localhost
    proxy_set_header    X-Forwarded-Host   localhost
    ...
}

To make things cleaner and better you would later need to set the proxy host or the public DNS name once you have one, instead of localhost.

Upvotes: 2

Related Questions