KeyCloak 19.0.1 Admin Console behind k8s nginx gives invalid redirect_uri

Hello,

I am using keycloak 19.0.1, on local dev machine I can get my setup working and login to admin console. Local setup doesn’t use any reverse proxy.

On dev server, we use nginx reverse proxy (k8s nginx ingress).
What we saw is when we load admin console, it gives us invalid redirect_uri error.

I have googled forums for support and most said to configure headers, so my configuration for keycloak looks like this

KeyCloak 19:
–hostname-strict-https=false
–hostname-strict=false
KC_PROXY: edge
KC_HTTP_ENABLED: true
KC_HTTP_RELATIVE_PATH: /auth
KC_HOSTNAME: my.domain.com
KC_HOSTNAME_PORT: 7979

and my k8s nginx ingress setup…

apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
annotations:
kubernetes.io/ingress.class: nginx-internal
nginx.ingress.kubernetes.io/configuration-snippet: |
more_set_headers “X-Real-IP $remote_addr”;
more_set_headers “X-Forwarded-For $proxy_add_x_forwarded_for”;
more_set_headers “X-Forwarded-Proto $scheme”;
more_set_headers “X-Forwarded-Host $host”;
more_set_headers “X-Forwarded-Port $server_port”;
more_set_headers “Host $host”;

When I used with admin2 console feature enabled, I was getting 403 forbidden on auth/realms/master/protocol/openid-connect/login-status-iframe.html/init?client_id=account-console&origin=https%3A%2F%2Fqa.XXX.com, and loading admin console would get stuck,

so I disabled admin2 feature (KC_FEATURES_DISABLE: admin2),
and now with old admin console I get page displaying showing "invalid redirect_uri

Also tried setting setting ssl_required=NONE for master realm as was indicated in some forums but made no difference. (Ref: docker - Cannot access Keycloak account-console in Kubernetes (403) - Stack Overflow)

I am not sure what other nginx config is missing or being done incorrectly, or if something else I have missed.

Would really appreciate the help, thank you…

1 Like

I have set the http-host of keycloak to the hostname of the machine running Keycloak and it is running successfully.

I don’t know if this will solve your problem, but you can try if you want.

1 Like

Thank you, missed that config…
My KC_HOSTNAME is a public facing url (e.g: identity.company.com) while my keycloak is an internal url (keycloak-internal.company.com), will try set http-host to keycloak-internal.company.com and test

1 Like

Hi, so I tried the suggestion and this is what I found:

configuration (partial snippets of relevance):
env:
- name: KC_FEATURES_DISABLED
value: “admin2”
- name: KC_PROXY
value: “edge”
- name: KC_HTTP_PORT
value: “7979”
- name: KC_HOSTNAME_STRICT
value: “false”
- name: KC_HTTP_ENABLED
value: “true”
- name: KC_HTTP_RELATIVE_PATH
value: “/auth”
- name: KC_METRICS_ENABLED
value: “true”
- name: KC_HEALTH_ENABLED
value: “true”
- name: POD_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
- name: POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: POD_IP
valueFrom:
fieldRef:
fieldPath: status.podIP
- name: KC_HOSTNAME
value: identity-test.company.com
- name: KC_HTTP_HOST
value: keycloak-internal.company.com
ports:
- containerPort: 7979
name: http
protocol: TCP

apiVersion: v1
kind: Service
metadata:
labels:
app: keycloak-service
name: keycloak-service
namespace: dev
spec:
ports:

  • port: 7979
    name: http-alt
    protocol: TCP
    targetPort: http
  • port: 8443
    name: https-alt
    protocol: TCP
    targetPort: https
    selector:
    app: keycloak-service

apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: keycloak-service-internal
namespace: dev
annotations:
kubernetes.io/ingress.class: nginx-internal
nginx.ingress.kubernetes.io/rewrite-target: /
nginx.ingress.kubernetes.io/configuration-snippet: |
more_set_headers “X-Real-IP $remote_addr”;
more_set_headers “X-Forwarded-For $proxy_add_x_forwarded_for”;
more_set_headers “X-Forwarded-Proto $scheme”;
more_set_headers “X-Forwarded-Host $host”;
more_set_headers “X-Forwarded-Port $server_port”;
more_set_headers “Host $host”;

With passing both KC_HOSTNAME and KC_HTTP_HOST, keycloak doesnt start and throws error at startup:
ERROR [org.keycloak.quarkus.runtime.cli.ExecutionExceptionHandler] (main) Error details:: java.lang.RuntimeException: Unable to start HTTP server
at io.quarkus.vertx.http.runtime.VertxHttpRecorder.doServerStart(VertxHttpRecorder.java:624)
at io.quarkus.vertx.http.runtime.VertxHttpRecorder.startServer(VertxHttpRecorder.java:282)
at io.quarkus.deployment.steps.VertxHttpProcessor$openSocket1866188241.deploy_0(Unknown Source)
at io.quarkus.deployment.steps.VertxHttpProcessor$openSocket1866188241.deploy(Unknown Source)
at io.quarkus.runner.ApplicationImpl.doStart(Unknown Source)
at io.quarkus.runtime.Application.start(Application.java:101)
at io.quarkus.runtime.ApplicationLifecycleManager.run(ApplicationLifecycleManager.java:103)
at io.quarkus.runtime.Quarkus.run(Quarkus.java:67)
at org.keycloak.quarkus.runtime.KeycloakMain.start(KeycloakMain.java:103)

So, I reverted back to usual (i.e without KC_HTTP_HOST), and on quarkus startup saw that in logs it reads:
“Listening on: http://0.0.0.0:7979

When I tried accessing the admin console: keycloak-internal.company.com/auth/admin/master/console
it then redirects URL to
https://identity-test.company.com/auth/realms/master/protocol/openid-connect/auth?client_id=security-admin-console&redirect_uri=https%3A%2F%2Fkeycloak-internal.company.com%2Fauth%2Fadmin%2Fmaster%2Fconsole%2F&state=d837e1df-f63a-4830-95fd-92ccf9bec47f&response_mode=fragment&response_type=code&scope=openid&nonce=db60fc5f-126f-4608-8da1-aa324a31e183&code_challenge=zFN58CgQOKy1V_joA5FvqKUyrbhUovkgvrshVNibn1w&code_challenge_method=S256

and I get Invalid redirect_uri
I then manually changed the redirect_uri in parameter on browser and hit reload
https://identity-test.company.com/auth/realms/master/protocol/openid-connect/auth?client_id=security-admin-console&redirect_uri=https%3A%2F%2Fidentity-test.company.com%2Fauth%2Fadmin%2Fmaster%2Fconsole%2F&state=d837e1df-f63a-4830-95fd-92ccf9bec47f&response_mode=fragment&response_type=code&scope=openid&nonce=db60fc5f-126f-4608-8da1-aa324a31e183&code_challenge=zFN58CgQOKy1V_joA5FvqKUyrbhUovkgvrshVNibn1w&code_challenge_method=S256

I can see the admin console login, but upon login, it fail (The above was a hack anyways just to see the behaviour).

How or what can I configure or missing so I can use a nginx reverse proxy with the setup as above.
Not sure why I get Quarkus bind exception when I add http_host as suggested.

What happens if hostname-strict=true?

Thank you for your help, really appreciate a lot.

Tried various settings, it turned out that I had to in the master realm, set my valid redirect url’s which was missing. Once I entered a valid value there, the admin console login works then.

please can you explain in detail? like how you resolved it

Note: like I know where you set that valid redirect uris but how you decide what is your valid ones? when we use “/” we put *?

Update: Now I understood, we need full url like https://example.com/*

say your keycloak internal url is: mykc-internal.com
and you login to admin console at: mykc-internal.com/auth/admin/master/console

Now if you have KC_HOSTNAME as some public facing url, eg: company.com
Then when you hit based on setup:
Enter: mykc-internal.com/auth/admin/master/console
It will redirect to company.com/auth/realms/master/protocol/openid-connect/auth?client_id=&redirect_uri=https%3A%2F%2Fmykc-internal.com %2Fauth%2Fadmin%2Fmaster%2Fconsole%2F

At this point, you get invalid redirect_uri since your public dns and redirect uri are different.
So when you login to admin console (keep kc_hostname and redirect_uri same), you can then for that “client_id”, put the valid redirect uri as:
my-kc-internal.com/auth/admin/master/console

Putting * is a security flaw and not advised.

1 Like

@vikram do you use KC_HOSTNAME_PORT ? it causes blank admin page for me.

Hi @a.ahmadzadeh we use the default 8443 so havent had to to configure it, however having said that, going through your post, seeing you are using a different default port, have you also configured KC_HTTPS_PORT in conjunction with KC_HOSTNAME_PORT. I am not entirely sure how two play together but you can try.