Scim plugin behind reverse proxy that strips a path prefix makes the scim console unaccessible
Opened this issue · 9 comments
When the plugin is deployed with a KC container behind a reverse proxy (I'm using traefik) with a /login
path prefix that the reverse proxy uses to select the KC container as target and strips from the URL that is passed to KC, then the plugin is not accessible.
My KC-container is built with these env variables:
KC_HOSTNAME_URL=https://www.example.com/login KC_HOSTNAME_ADMIN_URL=https://www.example.com/login KC_HOSTNAME_PATH=/login
Keycloak itself works correctly at https://www.example.com/login/
(showing the landing page) and .../login/admin/master/console/
logging in to the console. The link to the SCIM Administration Console directs to
https://www.example.com/login/realms/master/scim/admin/frontend/
but leads to a We are sorry... Page not found
from KC.
The KC logs show this error message:
keycloak-1 | 2024-02-07 16:19:22,036 INFO [de.captaingoldfish.scim.sdk.keycloak.administration.AdministrationBaseEndpoint] (executor-thread-1) SCIM webadmin backend access was rejected. Only accessible under 'https://www.example.com/login' but 'https://www.example.com/login' was used instead
Everything works correctly when I remove the path prefix, or 'bake it into KC' with KC_HTTP_RELATIVE_PATH=/login
, which I prefer not to do.
Hi which version did you install exactly?
Sorry for the log-message it does not show the URLs correctly. If you deploy the latest Release kc-22-1.5.0-RC1 or kc-21.1.2.2-RC1 you will get an appropriate errormessage.
This happens normally under two different conditions:
- reverse-proxy is communicating with keycloak over http and keycloak does not have the property
KC_PROXY=edge
set. - reverse-proxy is communicating with keycloak over https and keycloak does have the property
KC_PROXY=edge
set.
The error in the comparison is normally the protocol that it is http instead of https or vice versa.
Thanks for the fast reply,
Plugin version: scim-for-keycloak-kc-23-1.5.0-RC1-enterprise.jar
KC 23.0.6
KC is running in edge mode, proxy uses http
Env-vars in the container:
KC_HOSTNAME_STRICT_HTTPS=false
KC_PROXY=edge
KC_HOSTNAME_ADMIN_URL=https://www.example.com/login
KC_DB_USERNAME=keycloak
KC_DB_PASSWORD=password
KC_HOSTNAME_URL=https://www.example.com/login
KC_HOSTNAME_PATH=/login
KC_DB_URL=jdbc:postgresql://postgres:5432/keycloak?ssl=all
KC_HOSTNAME_STRICT=false
KC_HTTP_ENABLED=true
Keycloak startup message:
keycloak-1 | 2024-02-07 19:50:17,961 INFO [org.keycloak.common.Profile] (main) Preview features enabled: account3, admin-fine-grained-authz, client-secret-rotation, declarative-user-profile, dpop, multi-site, recovery-codes, scripts, token-exchange, update-email
keycloak-1 | 2024-02-07 19:50:19,200 INFO [org.keycloak.quarkus.runtime.hostname.DefaultHostnameProvider] (main) Hostname settings: Base URL: https://www.example.com/login, Hostname: www.example.com, Strict HTTPS: true, Path: /login, Strict BackChannel: false, Admin URL: https://www.example.com/login, Admin: www.example.com, Port: -1, Proxied: true
keycloak-1 | 2024-02-07 19:50:19,281 INFO [de.captaingoldfish.scim.sdk.keycloak.EnterpriseLoader] (main)
When navigating the link, the error message is:
keycloak-1 | 2024-02-07 19:51:42,881 INFO [de.captaingoldfish.scim.sdk.keycloak.administration.AdministrationBaseEndpoint] (executor-thread-1) SCIM webadmin backend access was rejected. Only accessible under 'https://www.example.com/login' but 'https://www.example.com/realms/master/scim/admin/frontend/' was used instead
The was used instead url is exactly the one I would expect. The landing page links to https://www.example.com/login/realms/master/scim/admin/frontend/
and the proxy strips the login
.
With KC_HTTP_RELATIVE_PATH
not set and KC_HOSTNAME_PATH=/login
, the plugin should not expect the /login
to be there.
/Hartmut
I see, what is the problem. I will check later again in the sourcecode if I can fix this without workarounds. Until then I would recommend that you simply adjust the keycloak relative path until then:
KC_RELATIVE_PATH=/login
The context-path is read using the hostname-provider from keycloak itself:
HostnameProvider hostnameProvider = keycloakSession.getProvider(HostnameProvider.class);
String contextPath = hostnameProvider.getContextPath(keycloakUriInfo, UrlType.ADMIN)
So I am not reading the configuration manually. I am just using what keycloak already provides. For this reason I will need to check this in detail. I could try to remove the context-path in such checks. But I would prefer not to.
Is it an option for you to set KC_RELATIVE_PATH?
And I will see that I find a clean solution for this in due time.
Great! I do have a working system that I can go on using :-) This just bit me when I tried to get rid of the kc_relative_path. For the time being I will stick to the current situation. There is also another work-around available with slightly more complex reverse proxy rules exposing /realms/
, /resources/
, /robots.txt
and optionally /js/
of the KC container (as described in the KC documentation Exposed path recommendations).
Hi!
Any progress on this (preferably using hostname2)? I'd like to get rid of the kc_relative_path
It's documented by keycloak itself here:
https://www.keycloak.org/server/reverseproxy Different context-path on reverse proxy
I'm not exactly sure which place you are pointing at. I'm running KC25 now with KC_HOSTNAME=https://${HOST_NAME}/auth
and KC_HOSTNAME_ADMIN=https://${HOST_NAME}/auth
and the reverse proxy is stripping the /auth
prefix. From how I understand it, this simplicity in configuration is one of the major drivers of Keycloak's move to HOSTNAME2.
Do I understand you right that for SCIM to work correctly, I have to remove the HOSTNAME's /auth
, add KC_RELATIVE_PATH and not strip the prefix in the reverse proxy?
Got it working
- KC_HOSTNAME=http://${HOST_NAME}:9090/auth
- KC_HTTP_RELATIVE_PATH=/auth
And reverse proxy not stripping the /auth
from the URL.
It would be nice, though, to have the SCIM plugin to 'understand' the other way of configuring (i.e., without the relative-path and with proxy doing prefix-stripping; the SCIM plugin then has to get it's clues from the path in KC_HOSTNAME(_ADMIN).
okay, I just added a new configuration property to make this work. It is also logged during startup:
environment: KC_SPI_REALM_RESTAPI_EXTENSION_SCIM_ADMIN_URL_CHECK = no-context-path
property : spi-realm-restapi-extension-scim-admin-url-check = no-context-path
values : [strict, no-context-path]
default : strict
description: strict -> request URL and configured Keycloak URL must match exactly.
no-context-path -> only http-scheme (http or https), hostname and port need to match the request URL.
I solved it like this because there are a few configuration possibilities that could make the access insecure. Therefore, the check needs to be changed by configuration.
I am going to release this later today