Doc
Doc

Reputation: 5266

Keycloak behind reverse proxy mixes internal and external addresses

I'm trying to setup a keycloak instance behind a reverse proxy with nginx and I almost did it.

My (partial) docker-compose:

version: '3.4'                                                                          
                                                                                    
services:  
  [...]
                                                                                                                                                                                                                                                 
  keycloak:                                                                             
    image: jboss/keycloak                                                                                                                                     
    environment:                                                                        
      - DB_VENDOR=[vendor]
      - DB_USER=[user]                                                                      
      - DB_PASSWORD=[password]
      - DB_ADDR=[dbaddr]
      - DB_DATABASE=[dbname]
      - KEYCLOAK_USER=[adminuser]                                                         
      - KEYCLOAK_PASSWORD=[adminpassword]                                                       
      - KEYCLOAK_IMPORT=/tmp/my-realm.json                                           
      - KEYCLOAK_FRONTEND_URL=https://auth.mydomain.blah/auth                          
      - PROXY_ADDRESS_FORWARDING=true                                                   
      - REDIRECT_SOCKET=proxy-https
                                                 
  [...]

my nginx conf is just

server {
    listen       443 ssl;
    server_name  auth.mydomain.blah;
  
    ssl_certificate /etc/letsencrypt/live/auth.mydomain.blah/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/auth.mydomain.blah/privkey.pem;

    location / {
        proxy_pass http://keycloak:8080;
    }
}

and it works, I can access keycloak from https://auth.mydomain.blah/auth BUT when I look at https://auth.mydomain.blah/auth/realms/campi/.well-known/openid-configuration I get this:

{
  "issuer": "https://auth.mydomain.blah/auth/realms/campi",
  "authorization_endpoint": "https://auth.mydomain.blah/auth/realms/campi/protocol/openid-connect/auth",
  "token_endpoint": "http://keycloak:8080/auth/realms/campi/protocol/openid-connect/token",
  "introspection_endpoint": "http://keycloak:8080/auth/realms/campi/protocol/openid-connect/token/introspect",
  "userinfo_endpoint": "http://keycloak:8080/auth/realms/campi/protocol/openid-connect/userinfo",
  "end_session_endpoint": "https://auth.mydomain.blah/auth/realms/campi/protocol/openid-connect/logout",
  "jwks_uri": "http://keycloak:8080/auth/realms/campi/protocol/openid-connect/certs",
  "check_session_iframe": "https://auth.mydomain.blah/auth/realms/campi/protocol/openid-connect/login-status-iframe.html",
  [...]

why does keycloak mix internal and external uris? what am I missing?

Upvotes: 1

Views: 4008

Answers (2)

Jan Garaj
Jan Garaj

Reputation: 28646

https://www.keycloak.org/docs/latest/server_installation/index.html#_setting-up-a-load-balancer-or-proxy

Your reverse proxy/nginx is not forwarding host headers properly, so Keycloak has no idea which host/protocol has been used for the request and it using backend/internal host name. You need to set a few proxy_set_header lines:

server {
    listen       443 ssl;
    server_name  auth.mydomain.blah;
  
    ssl_certificate /etc/letsencrypt/live/auth.mydomain.blah/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/auth.mydomain.blah/privkey.pem;

    location / {
            proxy_pass          http://keycloak:8080;
            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;
    }
}

Upvotes: 7

Jerry Saravia
Jerry Saravia

Reputation: 3837

We have the same "issue" at my company.

Internally access it via keycloak-admin.internaldomain.com but externally for our normal users they hit keycloak.externaldomain.com.

If I load the .well-known/openid-configuration url internally it has the internal address, but loading it using the external url it has that one.

It hasn't caused any issues at all for us, other than explaining it occasionally to an engineer that sees the difference. Otherwise though, no issues.

It appears keycloak just uses whatever domain it is being accessed with.

Upvotes: -1

Related Questions