Keycloak on subpath and behind reverse proxy

After something else fundamentally broke, we updated from keycloak 11 (yes, I know) to Keycloak 26. However, we can’t seem to get the proxy config right. We’re using X-Forwarded-For-Headers everywhere, so that’s what we did with Keycloak as well.

Our HAProxy config is as follows:

backend haproxy
mode http
option forwardfor
    http-request set-header X-Real-IP %[src]
    http-request set-header X-Forwarded-Host %[req.hdr(Host)]
    http-request set-header Host %[req.hdr(Host)]
    http-request set-header X-Forwarded-Proto https
    server fastsso1 192.168.62.6:9012 check

We’re building a custom image where we enable Postgres, change the relative HTTP path to /org-auth/auth, and also enable hostname:v2

In Portainer, we’re setting the following environment variables:

  • KC_PROXY_HEADERS: xforwarded
  • KC_HTTP_ENABLED: true
  • KC_HOSTNAME: https://subdomain.domain.com (we’re doing SSL termination in HAProxy, we also tried without the https, and with the subpath)
  • KC_HOSTNAME_STRICT: true
  • KC_HTTP_RELATIVE_PATH: /org-auth/auth
  • KC_FEATURES: hostname:v2

Now, somehow, all requests end up at https://https//subdomain.domain.com/org-auth/auth/org-auth/auth/realms/DOMAIN.COM/protocol/openid-connect/auth

As far as I know, we’ve followed all the available documentation regarding hostname and reverse proxies, too, so I’m really at a loss here.

What could cause this doubling up?

Update: The Keycloak config was mostly fine, our authproxies still had bad state in them. In the end, we configured Keycloak as followed, and then restarted all the authproxies, and everything was fine:
KC_PROXY_HEADERS: xforwarded

  • KC_HTTP_ENABLED: true

  • KC_HOSTNAME: subdomain.domain.com

  • KC_HOSTNAME_STRICT: true

  • KC_HTTP_RELATIVE_PATH: /org-auth/auth

  • KC_FEATURES: hostname:v2

1 Like