You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Using a IIS reverse proxy results in unexpected redirect to admin console on successful login (standard flow) - disregarding provided redirect_uri
#39887
Hi, I am looking for some guidance on how to continue pursuing / troubleshooting this issue I am encountering (or hopefully explain what I've likely misconfigured). (using version 26.2.4)
I have a working client setup/integration with keycloak using the standard flow. The client has a valid redirect_uri defined that redirects back to my application. The full flow is working as expected, but in moving to production I would prefer IIS to handle all certification handling. As such, I've made an effort to move/re-configure my keycloak instance to support a reverse-proxy through IIS.
I have thing working to a degree; my reverse proxy successfully forwards my request to localhost:8080 and prompts me with a login-screen. Much like my existing setup, I can see that the url includes a valid redirect uri. Upon successful login; I am however redirected to my reverse proxy's base url; resulting in the opening the admin console.
I have tried to run keycloak with log-level DEBUG, but am having issues identifying the reason behind this behavior. Related logs can be found below:
What I fail to understand is why the valid url (which worked before setting up the reverse-proxy) is now not being used; and instead keycloak is opting to use the x-forwarded http headers instead.
Let me know if any additional info is needed to help troubleshoot further. Thanks!
LOG EXTRACT
2025-05-21 21:47:22,027 DEBUG [org.hibernate.event.internal.AbstractSaveEventListener] (org.keycloak.models.sessions.infinispan.changes.PersistentSessionsWorker$BatchWorker) Generated identifier: component[clientId,clientStorageProvider,externalClientId,offline,userSessionId]{offline=0, clientId=bad53b5d-5c67-41d3-a519-8f122af39294, clientStorageProvider=local, externalClientId=local, userSessionId=9f717f2d-7ea7-48b9-b18f-e93573326c15}, using strategy: org.hibernate.id.CompositeNestedGeneratedValueGenerator
2025-05-21 21:47:22,027 DEBUG [org.keycloak.transaction.JtaTransactionWrapper] (org.keycloak.models.sessions.infinispan.changes.PersistentSessionsWorker$BatchWorker) JtaTransactionWrapper commit. Request Context: Non-HTTP task
2025-05-21 21:47:22,027 DEBUG [org.hibernate.event.internal.AbstractFlushingEventListener] (org.keycloak.models.sessions.infinispan.changes.PersistentSessionsWorker$BatchWorker) Processing flush-time cascades
2025-05-21 21:47:22,027 DEBUG [org.hibernate.event.internal.AbstractFlushingEventListener] (org.keycloak.models.sessions.infinispan.changes.PersistentSessionsWorker$BatchWorker) Dirty checking collections
2025-05-21 21:47:22,027 DEBUG [org.hibernate.event.internal.AbstractFlushingEventListener] (org.keycloak.models.sessions.infinispan.changes.PersistentSessionsWorker$BatchWorker) Flushed: 1 insertions, 0 updates, 0 deletions to 1 objects
2025-05-21 21:47:22,027 DEBUG [org.hibernate.event.internal.AbstractFlushingEventListener] (org.keycloak.models.sessions.infinispan.changes.PersistentSessionsWorker$BatchWorker) Flushed: 0 (re)creations, 0 updates, 0 removals to 0 collections
2025-05-21 21:47:22,027 DEBUG [org.hibernate.internal.util.EntityPrinter] (org.keycloak.models.sessions.infinispan.changes.PersistentSessionsWorker$BatchWorker) Listing entities:
2025-05-21 21:47:22,027 DEBUG [org.hibernate.internal.util.EntityPrinter] (org.keycloak.models.sessions.infinispan.changes.PersistentSessionsWorker$BatchWorker) org.keycloak.models.jpa.session.PersistentClientSessionEntity{data={"authMethod":"openid-connect","redirectUri":"https://front-end-client-url.com:443/","notes":{"clientId":"bad53b5d-5c67-41d3-a519-8f122af39294","scope":"openid api-client-test.all","userSessionStartedAt":"1747856841","iss":"https://reverse-proxy-iis-url:50000/realms/test_realm","startedAt":"1747856841","response_type":"code","level-of-authentication":"-1","code_challenge_method":"S256","redirect_uri":"https://front-end-client-url.com:443/","state":"a8f06f5cd9854fb8988161cf1e0066ae","code_challenge":"5mK7cxKs_K-Zlabh2ZX1LRs-BUX0Zj-HNCsLSmfbEGM"}}, version=0, timestamp=1747856841}
2025-05-21 21:47:22,028 DEBUG [org.hibernate.SQL] (org.keycloak.models.sessions.infinispan.changes.PersistentSessionsWorker$BatchWorker) insert into OFFLINE_CLIENT_SESSION (DATA,TIMESTAMP,VERSION,CLIENT_ID,CLIENT_STORAGE_PROVIDER,EXTERNAL_CLIENT_ID,OFFLINE_FLAG,USER_SESSION_ID) values (?,?,?,?,?,?,?,?)
2025-05-21 21:47:22,029 DEBUG [org.hibernate.orm.jdbc.batch] (org.keycloak.models.sessions.infinispan.changes.PersistentSessionsWorker$BatchWorker) PreparedStatementDetails did not contain PreparedStatement on #releaseStatements : insert into OFFLINE_CLIENT_SESSION (DATA,TIMESTAMP,VERSION,CLIENT_ID,CLIENT_STORAGE_PROVIDER,EXTERNAL_CLIENT_ID,OFFLINE_FLAG,USER_SESSION_ID) values (?,?,?,?,?,?,?,?)
2025-05-21 21:47:22,029 DEBUG [org.hibernate.engine.transaction.internal.TransactionImpl] (org.keycloak.models.sessions.infinispan.changes.PersistentSessionsWorker$BatchWorker) On TransactionImpl creation, JpaCompliance#isJpaTransactionComplianceEnabled == false
2025-05-21 21:47:22,029 DEBUG [org.hibernate.resource.jdbc.internal.LogicalConnectionManagedImpl] (org.keycloak.models.sessions.infinispan.changes.PersistentSessionsWorker$BatchWorker) Initiating JDBC connection release from beforeTransactionCompletion
2025-05-21 21:47:22,029 DEBUG [org.hibernate.orm.jdbc.batch] (org.keycloak.models.sessions.infinispan.changes.PersistentSessionsWorker$BatchWorker) PreparedStatementDetails did not contain PreparedStatement on #releaseStatements : insert into OFFLINE_CLIENT_SESSION (DATA,TIMESTAMP,VERSION,CLIENT_ID,CLIENT_STORAGE_PROVIDER,EXTERNAL_CLIENT_ID,OFFLINE_FLAG,USER_SESSION_ID) values (?,?,?,?,?,?,?,?)
2025-05-21 21:47:22,030 DEBUG [org.hibernate.orm.jdbc.batch] (org.keycloak.models.sessions.infinispan.changes.PersistentSessionsWorker$BatchWorker) PreparedStatementDetails did not contain PreparedStatement on #releaseStatements : insert into OFFLINE_CLIENT_SESSION (DATA,TIMESTAMP,VERSION,CLIENT_ID,CLIENT_STORAGE_PROVIDER,EXTERNAL_CLIENT_ID,OFFLINE_FLAG,USER_SESSION_ID) values (?,?,?,?,?,?,?,?)
2025-05-21 21:47:22,030 DEBUG [org.hibernate.resource.jdbc.internal.LogicalConnectionManagedImpl] (org.keycloak.models.sessions.infinispan.changes.PersistentSessionsWorker$BatchWorker) Initiating JDBC connection release from afterTransaction
2025-05-21 21:47:22,030 DEBUG [org.keycloak.transaction.JtaTransactionWrapper] (org.keycloak.models.sessions.infinispan.changes.PersistentSessionsWorker$BatchWorker) JtaTransactionWrapper end. Request Context: Non-HTTP task
2025-05-21 21:47:22,030 DEBUG [org.keycloak.transaction.JtaTransactionWrapper] (org.keycloak.models.sessions.infinispan.changes.PersistentSessionsWorker$BatchWorker) JtaTransactionWrapper resuming suspended user transaction: TransactionImple < ac, BasicAction: 0:ffffac148609:c81c:682e2cfa:1e3 status: ActionStatus.RUNNING >
2025-05-21 21:47:22,030 DEBUG [org.hibernate.engine.jdbc.internal.JdbcCoordinatorImpl] (org.keycloak.models.sessions.infinispan.changes.PersistentSessionsWorker$BatchWorker) HHH000420: Closing un-released batch
2025-05-21 21:47:22,030 DEBUG [org.hibernate.orm.jdbc.batch] (org.keycloak.models.sessions.infinispan.changes.PersistentSessionsWorker$BatchWorker) PreparedStatementDetails did not contain PreparedStatement on #releaseStatements : insert into OFFLINE_CLIENT_SESSION (DATA,TIMESTAMP,VERSION,CLIENT_ID,CLIENT_STORAGE_PROVIDER,EXTERNAL_CLIENT_ID,OFFLINE_FLAG,USER_SESSION_ID) values (?,?,?,?,?,?,?,?)
2025-05-21 21:47:22,030 DEBUG [org.hibernate.orm.jdbc.batch] (org.keycloak.models.sessions.infinispan.changes.PersistentSessionsWorker$BatchWorker) PreparedStatementDetails did not contain PreparedStatement on #releaseStatements : insert into OFFLINE_CLIENT_SESSION (DATA,TIMESTAMP,VERSION,CLIENT_ID,CLIENT_STORAGE_PROVIDER,EXTERNAL_CLIENT_ID,OFFLINE_FLAG,USER_SESSION_ID) values (?,?,?,?,?,?,?,?)
2025-05-21 21:47:22,030 DEBUG [org.keycloak.transaction.JtaTransactionWrapper] (org.keycloak.models.sessions.infinispan.changes.PersistentSessionsWorker$BatchWorker) JtaTransactionWrapper commit. Request Context: Non-HTTP task
2025-05-21 21:47:22,030 DEBUG [org.keycloak.transaction.JtaTransactionWrapper] (org.keycloak.models.sessions.infinispan.changes.PersistentSessionsWorker$BatchWorker) JtaTransactionWrapper end. Request Context: Non-HTTP task
2025-05-21 21:47:22,052 DEBUG [io.quarkus.vertx.http.runtime.ForwardedParser] (vert.x-eventloop-thread-0) Using X-Forwarded-Proto to set scheme to https
2025-05-21 21:47:22,052 DEBUG [io.quarkus.vertx.http.runtime.ForwardedParser] (vert.x-eventloop-thread-0) Using reverse-proxy-iis-url to set host to reverse-proxy-iis-url and port to -1
2025-05-21 21:47:22,052 DEBUG [io.quarkus.vertx.http.runtime.ForwardedParser] (vert.x-eventloop-thread-0) Using X-Forwarded-Port to set port to 50000
2025-05-21 21:47:22,052 DEBUG [io.quarkus.vertx.http.runtime.ForwardedParser] (vert.x-eventloop-thread-0) Recalculated absoluteURI to https://reverse-proxy-iis-url:50000/?state=a8f06f5cd9854fb8988161cf1e0066ae&session_state=9f717f2d-7ea7-48b9-b18f-e93573326c15&iss=https%3A%2F%2Freverse-proxy-iis-url%3A50000%2Frealms%2Ftest_realm&code=9c85f540-3410-445a-a4c9-6b3067207308.9f717f2d-7ea7-48b9-b18f-e93573326c15.bad53b5d-5c67-41d3-a519-8f122af39294
2025-05-21 21:47:22,053 DEBUG [org.keycloak.transaction.JtaTransactionWrapper] (executor-thread-8) new JtaTransactionWrapper. Was existing transaction suspended: false Request Context: HTTP GET /
2025-05-21 21:47:22,054 DEBUG [org.keycloak.transaction.JtaTransactionWrapper] (executor-thread-8) JtaTransactionWrapper commit. Request Context: HTTP GET /
2025-05-21 21:47:22,054 DEBUG [org.keycloak.transaction.JtaTransactionWrapper] (executor-thread-8) JtaTransactionWrapper end. Request Context: HTTP GET /
It looks like from the logs you expect a redirect to https://front-end-client-url.com:443, is that correct? Can you share what you have configured the client valid redirect uris as?
Something similar was brought up in #37153 - the code path for determining the redirect should be:
I found #37153 when searching the existing discussions, but I was unclear how standard flow / implicit flow differed so I figured I would write a question of my own; hope that's fine!
Below is a screenshot of my configurations of my 'front-end' client:
I've tried with/without the home URL (I did not have this defined in my non-proxy setup).
The only difference I see between the two setups is that the reverse-proxy sends the X-Forwarded-Proto/X-Forwarded-Port/X-Forwarded-Host headers - whereas my previous setup did not; does keycloak defer to using these before using a provided redirect_uri?
Is there an approach / is it feasible to append new debug entries manually in the source code and rebuild the solution; or is there a better approach to troubleshooting issues like these?
does keycloak defer to using these before using a provided redirect_uri?
Most code in keycloak does not consider those headers directly, rather they are used to determine the effective request origin. In this case that seems to be https://reverse-proxy-iis-url:50000
Without the proxy-header setting the request would be seen as using the scheme / host / port of the keycloak server (http://localhost:8080 ?), not the proxy server.
Also note that on keycloak 26.2 that hostname-strict-https=false, and proxy=edge are not valid configuration options.
Is there an approach / is it feasible to append new debug entries manually in the source code and rebuild the solution; or is there a better approach to troubleshooting issues like these?
In double checking what you provided, it looks like your valid redirect URIs should work. Can you confirm that using just * gives you the same behavior? If so then we'll need to look beyond the redirect validation logic.
As for additional troubleshooting it may be worth a try to step up to trace logging. At the very least I'd expect that to show Keycloak is returning a 302 to localhost.
Setting both valid redirect + post redirect as '*' results in the same behaviour sadly.
At least that confirms the issue lies elsewhere.
I am in doubt if you are referencing extra logging on Keycloak's side or in the communication between the reverse proxy (IIS) and Keycloak. In either case, are you able to share some resources that could help me setting this up?
I mean on the keycloak side: log-level=trace
That should show a good representation of the conversation between the proxy and keycloak.
I've attached the full log for clarity sake; important lines occur @ ~66377
I don't see any clear indication in these logs as to why Keycloak decides to re-calcuate the redirect-uri [66412]. Do you see anything of interest here?
No worries,
I've included the requested quarkus options. I have a hard time understanding these logs; but it seems as if it's getting a 302 response and referencing the front-end-client-url (as expected??). Is this where you would have expected it to reference localhost:8080 instead? I've noted that nothing in the log reference localhost / localhost:8080; I suspect this is due to the forwarded X-Forwarded-Host.
I find it interesting that keycloaks uses a "303 See Other" response to redirect to the reverse-proxy again (2nd io.quarkus.http.access-log entry below); this indicates to me at least that it knows this is not the intended redirect-uri.
Is there a likelihood that it fails to redirect to my front-end URL as internally Keycloak is still hosted on HTTP and redirecting to a HTTPS resource is not expected/valid? Something akin to #39085?
2025-05-22 22:43:57,626 INFO [io.quarkus.http.access-log] (executor-thread-3) "/realms/test_realm/login-actions/authenticate?session_code=cLhz5uSIYsEV7LFfre6SXu7UabHJ4Nz7tnJB3KEOSe8&execution=d721e097-b333-44be-9446-e5300ad3d978&client_id=frontend-client-test&tab_id=Vlu9_GJq_Ho&client_data=eyJydSI6Imh0dHBzOi8vbG9naWEtd21zLXdlYi10ZXN0LnJuLmRrOjQ0My8iLCJydCI6ImNvZGUiLCJzdCI6ImQ3ZmFjNTYzNzJmMjQ1N2U5MDdkYTE1NzlkOGJlYjI5In0 302 https://front-end-client-url.com/?state=d7fac56372f2457e907da1579d8beb29&session_state=89a42579-d151-41f7-983f-bda11bbb074c&iss=https%3A%2F%2Freverse-proxy-iis-url.com%3A50000%2Frealms%2Ftest_realm&code=7cf3e83d-a073-4d7b-8516-3a3915debdf7.89a42579-d151-41f7-983f-bda11bbb074c.bad53b5d-5c67-41d3-a519-8f122af39294"
2025-05-22 22:43:57,643 DEBUG [io.quarkus.vertx.http.runtime.ForwardedParser] (vert.x-eventloop-thread-0) Using X-Forwarded-Proto to set scheme to https
2025-05-22 22:43:57,643 DEBUG [io.quarkus.vertx.http.runtime.ForwardedParser] (vert.x-eventloop-thread-0) Using reverse-proxy-iis-url.com to set host to reverse-proxy-iis-url.com and port to -1
2025-05-22 22:43:57,643 DEBUG [io.quarkus.vertx.http.runtime.ForwardedParser] (vert.x-eventloop-thread-0) Using X-Forwarded-Port to set port to 50000
2025-05-22 22:43:57,643 DEBUG [io.quarkus.vertx.http.runtime.ForwardedParser] (vert.x-eventloop-thread-0) Recalculated absoluteURI to https://reverse-proxy-iis-url.com:50000/?state=d7fac56372f2457e907da1579d8beb29&session_state=89a42579-d151-41f7-983f-bda11bbb074c&iss=https%3A%2F%2Freverse-proxy-iis-url.com%3A50000%2Frealms%2Ftest_realm&code=7cf3e83d-a073-4d7b-8516-3a3915debdf7.89a42579-d151-41f7-983f-bda11bbb074c.bad53b5d-5c67-41d3-a519-8f122af39294
2025-05-22 22:43:57,645 DEBUG [org.keycloak.transaction.JtaTransactionWrapper] (executor-thread-3) new JtaTransactionWrapper. Was existing transaction suspended: false Request Context: HTTP GET /
2025-05-22 22:43:57,646 DEBUG [org.keycloak.transaction.JtaTransactionWrapper] (executor-thread-3) JtaTransactionWrapper commit. Request Context: HTTP GET /
2025-05-22 22:43:57,646 DEBUG [org.keycloak.transaction.JtaTransactionWrapper] (executor-thread-3) JtaTransactionWrapper end. Request Context: HTTP GET /
2025-05-22 22:43:57,646 INFO [io.quarkus.http.access-log] (executor-thread-3) "/?state=d7fac56372f2457e907da1579d8beb29&session_state=89a42579-d151-41f7-983f-bda11bbb074c&iss=https%3A%2F%2Freverse-proxy-iis-url.com%3A50000%2Frealms%2Ftest_realm&code=7cf3e83d-a073-4d7b-8516-3a3915debdf7.89a42579-d151-41f7-983f-bda11bbb074c.bad53b5d-5c67-41d3-a519-8f122af39294 303 https://reverse-proxy-iis-url.com:50000/?state=d7fac56372f2457e907da1579d8beb29&session_state=89a42579-d151-41f7-983f-bda11bbb074c&iss=https%3A%2F%2Freverse-proxy-iis-url.com%3A50000%2Frealms%2Ftest_realm&code=7cf3e83d-a073-4d7b-8516-3a3915debdf7.89a42579-d151-41f7-983f-bda11bbb074c.bad53b5d-5c67-41d3-a519-8f122af39294/"
2025-05-22 22:43:57,654 DEBUG [io.quarkus.vertx.http.runtime.ForwardedParser] (vert.x-eventloop-thread-0) Using X-Forwarded-Proto to set scheme to https
2025-05-22 22:43:57,654 DEBUG [io.quarkus.vertx.http.runtime.ForwardedParser] (vert.x-eventloop-thread-0) Using reverse-proxy-iis-url.com to set host to reverse-proxy-iis-url.com and port to -1
2025-05-22 22:43:57,654 DEBUG [io.quarkus.vertx.http.runtime.ForwardedParser] (vert.x-eventloop-thread-0) Using X-Forwarded-Port to set port to 50000
2025-05-22 22:43:57,654 DEBUG [io.quarkus.vertx.http.runtime.ForwardedParser] (vert.x-eventloop-thread-0) Recalculated absoluteURI to https://reverse-proxy-iis-url.com:50000/?state=d7fac56372f2457e907da1579d8beb29&session_state=89a42579-d151-41f7-983f-bda11bbb074c&iss=https%3A%2F%2Freverse-proxy-iis-url.com%3A50000%2Frealms%2Ftest_realm&code=7cf3e83d-a073-4d7b-8516-3a3915debdf7.89a42579-d151-41f7-983f-bda11bbb074c.bad53b5d-5c67-41d3-a519-8f122af39294/
Is this where you would have expected it to reference localhost:8080 instead?
Yes - if Keycloak were directly at fault for this behavior.
I find it interesting that keycloaks uses a "303 See Other" response to redirect to the reverse-proxy again (2nd io.quarkus.http.access-log entry below);
Actually the problem is with the request, not the response. Something is asking for GET /?state=... - that is a request against the root of Keycloak, which is basically an attempt to fetch the welcome page, so Keycloak is responding with a 303
reacted with thumbs up emoji reacted with thumbs down emoji reacted with laugh emoji reacted with hooray emoji reacted with confused emoji reacted with heart emoji reacted with rocket emoji reacted with eyes emoji
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Hi, I am looking for some guidance on how to continue pursuing / troubleshooting this issue I am encountering (or hopefully explain what I've likely misconfigured). (using version 26.2.4)
I have a working client setup/integration with keycloak using the standard flow. The client has a valid redirect_uri defined that redirects back to my application. The full flow is working as expected, but in moving to production I would prefer IIS to handle all certification handling. As such, I've made an effort to move/re-configure my keycloak instance to support a reverse-proxy through IIS.
I have thing working to a degree; my reverse proxy successfully forwards my request to localhost:8080 and prompts me with a login-screen. Much like my existing setup, I can see that the url includes a valid redirect uri. Upon successful login; I am however redirected to my reverse proxy's base url; resulting in the opening the admin console.
I have tried to run keycloak with log-level DEBUG, but am having issues identifying the reason behind this behavior. Related logs can be found below:
What I fail to understand is why the valid url (which worked before setting up the reverse-proxy) is now not being used; and instead keycloak is opting to use the x-forwarded http headers instead.
Let me know if any additional info is needed to help troubleshoot further. Thanks!
LOG EXTRACT
2025-05-21 21:47:22,027 DEBUG [org.hibernate.event.internal.AbstractSaveEventListener] (org.keycloak.models.sessions.infinispan.changes.PersistentSessionsWorker$BatchWorker) Generated identifier: component[clientId,clientStorageProvider,externalClientId,offline,userSessionId]{offline=0, clientId=bad53b5d-5c67-41d3-a519-8f122af39294, clientStorageProvider=local, externalClientId=local, userSessionId=9f717f2d-7ea7-48b9-b18f-e93573326c15}, using strategy: org.hibernate.id.CompositeNestedGeneratedValueGenerator
2025-05-21 21:47:22,027 DEBUG [org.keycloak.transaction.JtaTransactionWrapper] (org.keycloak.models.sessions.infinispan.changes.PersistentSessionsWorker$BatchWorker) JtaTransactionWrapper commit. Request Context: Non-HTTP task
2025-05-21 21:47:22,027 DEBUG [org.hibernate.event.internal.AbstractFlushingEventListener] (org.keycloak.models.sessions.infinispan.changes.PersistentSessionsWorker$BatchWorker) Processing flush-time cascades
2025-05-21 21:47:22,027 DEBUG [org.hibernate.event.internal.AbstractFlushingEventListener] (org.keycloak.models.sessions.infinispan.changes.PersistentSessionsWorker$BatchWorker) Dirty checking collections
2025-05-21 21:47:22,027 DEBUG [org.hibernate.event.internal.AbstractFlushingEventListener] (org.keycloak.models.sessions.infinispan.changes.PersistentSessionsWorker$BatchWorker) Flushed: 1 insertions, 0 updates, 0 deletions to 1 objects
2025-05-21 21:47:22,027 DEBUG [org.hibernate.event.internal.AbstractFlushingEventListener] (org.keycloak.models.sessions.infinispan.changes.PersistentSessionsWorker$BatchWorker) Flushed: 0 (re)creations, 0 updates, 0 removals to 0 collections
2025-05-21 21:47:22,027 DEBUG [org.hibernate.internal.util.EntityPrinter] (org.keycloak.models.sessions.infinispan.changes.PersistentSessionsWorker$BatchWorker) Listing entities:
2025-05-21 21:47:22,027 DEBUG [org.hibernate.internal.util.EntityPrinter] (org.keycloak.models.sessions.infinispan.changes.PersistentSessionsWorker$BatchWorker) org.keycloak.models.jpa.session.PersistentClientSessionEntity{data={"authMethod":"openid-connect","redirectUri":"https://front-end-client-url.com:443/","notes":{"clientId":"bad53b5d-5c67-41d3-a519-8f122af39294","scope":"openid api-client-test.all","userSessionStartedAt":"1747856841","iss":"https://reverse-proxy-iis-url:50000/realms/test_realm","startedAt":"1747856841","response_type":"code","level-of-authentication":"-1","code_challenge_method":"S256","redirect_uri":"https://front-end-client-url.com:443/","state":"a8f06f5cd9854fb8988161cf1e0066ae","code_challenge":"5mK7cxKs_K-Zlabh2ZX1LRs-BUX0Zj-HNCsLSmfbEGM"}}, version=0, timestamp=1747856841}
2025-05-21 21:47:22,028 DEBUG [org.hibernate.SQL] (org.keycloak.models.sessions.infinispan.changes.PersistentSessionsWorker$BatchWorker) insert into OFFLINE_CLIENT_SESSION (DATA,TIMESTAMP,VERSION,CLIENT_ID,CLIENT_STORAGE_PROVIDER,EXTERNAL_CLIENT_ID,OFFLINE_FLAG,USER_SESSION_ID) values (?,?,?,?,?,?,?,?)
2025-05-21 21:47:22,029 DEBUG [org.hibernate.orm.jdbc.batch] (org.keycloak.models.sessions.infinispan.changes.PersistentSessionsWorker$BatchWorker) PreparedStatementDetails did not contain PreparedStatement on #releaseStatements : insert into OFFLINE_CLIENT_SESSION (DATA,TIMESTAMP,VERSION,CLIENT_ID,CLIENT_STORAGE_PROVIDER,EXTERNAL_CLIENT_ID,OFFLINE_FLAG,USER_SESSION_ID) values (?,?,?,?,?,?,?,?)
2025-05-21 21:47:22,029 DEBUG [org.hibernate.engine.transaction.internal.TransactionImpl] (org.keycloak.models.sessions.infinispan.changes.PersistentSessionsWorker$BatchWorker) On TransactionImpl creation, JpaCompliance#isJpaTransactionComplianceEnabled == false
2025-05-21 21:47:22,029 DEBUG [org.hibernate.resource.jdbc.internal.LogicalConnectionManagedImpl] (org.keycloak.models.sessions.infinispan.changes.PersistentSessionsWorker$BatchWorker) Initiating JDBC connection release from beforeTransactionCompletion
2025-05-21 21:47:22,029 DEBUG [org.hibernate.orm.jdbc.batch] (org.keycloak.models.sessions.infinispan.changes.PersistentSessionsWorker$BatchWorker) PreparedStatementDetails did not contain PreparedStatement on #releaseStatements : insert into OFFLINE_CLIENT_SESSION (DATA,TIMESTAMP,VERSION,CLIENT_ID,CLIENT_STORAGE_PROVIDER,EXTERNAL_CLIENT_ID,OFFLINE_FLAG,USER_SESSION_ID) values (?,?,?,?,?,?,?,?)
2025-05-21 21:47:22,030 DEBUG [org.hibernate.orm.jdbc.batch] (org.keycloak.models.sessions.infinispan.changes.PersistentSessionsWorker$BatchWorker) PreparedStatementDetails did not contain PreparedStatement on #releaseStatements : insert into OFFLINE_CLIENT_SESSION (DATA,TIMESTAMP,VERSION,CLIENT_ID,CLIENT_STORAGE_PROVIDER,EXTERNAL_CLIENT_ID,OFFLINE_FLAG,USER_SESSION_ID) values (?,?,?,?,?,?,?,?)
2025-05-21 21:47:22,030 DEBUG [org.hibernate.resource.jdbc.internal.LogicalConnectionManagedImpl] (org.keycloak.models.sessions.infinispan.changes.PersistentSessionsWorker$BatchWorker) Initiating JDBC connection release from afterTransaction
2025-05-21 21:47:22,030 DEBUG [org.keycloak.transaction.JtaTransactionWrapper] (org.keycloak.models.sessions.infinispan.changes.PersistentSessionsWorker$BatchWorker) JtaTransactionWrapper end. Request Context: Non-HTTP task
2025-05-21 21:47:22,030 DEBUG [org.keycloak.transaction.JtaTransactionWrapper] (org.keycloak.models.sessions.infinispan.changes.PersistentSessionsWorker$BatchWorker) JtaTransactionWrapper resuming suspended user transaction: TransactionImple < ac, BasicAction: 0:ffffac148609:c81c:682e2cfa:1e3 status: ActionStatus.RUNNING >
2025-05-21 21:47:22,030 DEBUG [org.hibernate.engine.jdbc.internal.JdbcCoordinatorImpl] (org.keycloak.models.sessions.infinispan.changes.PersistentSessionsWorker$BatchWorker) HHH000420: Closing un-released batch
2025-05-21 21:47:22,030 DEBUG [org.hibernate.orm.jdbc.batch] (org.keycloak.models.sessions.infinispan.changes.PersistentSessionsWorker$BatchWorker) PreparedStatementDetails did not contain PreparedStatement on #releaseStatements : insert into OFFLINE_CLIENT_SESSION (DATA,TIMESTAMP,VERSION,CLIENT_ID,CLIENT_STORAGE_PROVIDER,EXTERNAL_CLIENT_ID,OFFLINE_FLAG,USER_SESSION_ID) values (?,?,?,?,?,?,?,?)
2025-05-21 21:47:22,030 DEBUG [org.hibernate.orm.jdbc.batch] (org.keycloak.models.sessions.infinispan.changes.PersistentSessionsWorker$BatchWorker) PreparedStatementDetails did not contain PreparedStatement on #releaseStatements : insert into OFFLINE_CLIENT_SESSION (DATA,TIMESTAMP,VERSION,CLIENT_ID,CLIENT_STORAGE_PROVIDER,EXTERNAL_CLIENT_ID,OFFLINE_FLAG,USER_SESSION_ID) values (?,?,?,?,?,?,?,?)
2025-05-21 21:47:22,030 DEBUG [org.keycloak.transaction.JtaTransactionWrapper] (org.keycloak.models.sessions.infinispan.changes.PersistentSessionsWorker$BatchWorker) JtaTransactionWrapper commit. Request Context: Non-HTTP task
2025-05-21 21:47:22,030 DEBUG [org.keycloak.transaction.JtaTransactionWrapper] (org.keycloak.models.sessions.infinispan.changes.PersistentSessionsWorker$BatchWorker) JtaTransactionWrapper end. Request Context: Non-HTTP task
2025-05-21 21:47:22,052 DEBUG [io.quarkus.vertx.http.runtime.ForwardedParser] (vert.x-eventloop-thread-0) Using X-Forwarded-Proto to set scheme to https
2025-05-21 21:47:22,052 DEBUG [io.quarkus.vertx.http.runtime.ForwardedParser] (vert.x-eventloop-thread-0) Using reverse-proxy-iis-url to set host to reverse-proxy-iis-url and port to -1
2025-05-21 21:47:22,052 DEBUG [io.quarkus.vertx.http.runtime.ForwardedParser] (vert.x-eventloop-thread-0) Using X-Forwarded-Port to set port to 50000
2025-05-21 21:47:22,052 DEBUG [io.quarkus.vertx.http.runtime.ForwardedParser] (vert.x-eventloop-thread-0) Recalculated absoluteURI to https://reverse-proxy-iis-url:50000/?state=a8f06f5cd9854fb8988161cf1e0066ae&session_state=9f717f2d-7ea7-48b9-b18f-e93573326c15&iss=https%3A%2F%2Freverse-proxy-iis-url%3A50000%2Frealms%2Ftest_realm&code=9c85f540-3410-445a-a4c9-6b3067207308.9f717f2d-7ea7-48b9-b18f-e93573326c15.bad53b5d-5c67-41d3-a519-8f122af39294
2025-05-21 21:47:22,053 DEBUG [org.keycloak.transaction.JtaTransactionWrapper] (executor-thread-8) new JtaTransactionWrapper. Was existing transaction suspended: false Request Context: HTTP GET /
2025-05-21 21:47:22,054 DEBUG [org.keycloak.transaction.JtaTransactionWrapper] (executor-thread-8) JtaTransactionWrapper commit. Request Context: HTTP GET /
2025-05-21 21:47:22,054 DEBUG [org.keycloak.transaction.JtaTransactionWrapper] (executor-thread-8) JtaTransactionWrapper end. Request Context: HTTP GET /
keycloak.conf:
http-enabled=true
hostname-strict=false
proxy-headers=xforwarded
hostname-strict-https=false
proxy=edge
All reactions
Replies: 2 comments · 7 replies
Uh oh!
There was an error while loading. Please reload this page.
It looks like from the logs you expect a redirect to https://front-end-client-url.com:443, is that correct? Can you share what you have configured the client valid redirect uris as?
Something similar was brought up in #37153 - the code path for determining the redirect should be:
keycloak/services/src/main/java/org/keycloak/protocol/oidc/utils/RedirectUtils.java
Line 89 in 0fc0dcd
Unfortunately not all of the code branches there have logs, so it may not completely clear from a debug log what is going on.
All reactions
Uh oh!
There was an error while loading. Please reload this page.
Hi Shawkins,
I found #37153 when searching the existing discussions, but I was unclear how standard flow / implicit flow differed so I figured I would write a question of my own; hope that's fine!
But yes, in my initial redirect to the keycloak login-page I include my expected redirect uri as query params:
https://reverse-proxy-iis-url:50000/realms/test_realm/protocol/openid-connect/auth?client_id=frontend-client-test&redirect_uri=https%3A%2F%2Ffront-end-client-url%3A443%2F&response_type=code&scope=openid+api-client-test.all&state=7c9f41cdb78f40dd8457603d31a8daef&code_challenge=q9Et3g9FsGXX-TUL3C5630BwEmZZzd2NLqex2oY7Lv4&code_challenge_method=S256
Below is a screenshot of my configurations of my 'front-end' client:

I've tried with/without the home URL (I did not have this defined in my non-proxy setup).
The only difference I see between the two setups is that the reverse-proxy sends the X-Forwarded-Proto/X-Forwarded-Port/X-Forwarded-Host headers - whereas my previous setup did not; does keycloak defer to using these before using a provided redirect_uri?
Is there an approach / is it feasible to append new debug entries manually in the source code and rebuild the solution; or is there a better approach to troubleshooting issues like these?
All reactions
Uh oh!
There was an error while loading. Please reload this page.
Most code in keycloak does not consider those headers directly, rather they are used to determine the effective request origin. In this case that seems to be https://reverse-proxy-iis-url:50000
Without the proxy-header setting the request would be seen as using the scheme / host / port of the keycloak server (http://localhost:8080 ?), not the proxy server.
Also note that on keycloak 26.2 that hostname-strict-https=false, and proxy=edge are not valid configuration options.
In double checking what you provided, it looks like your valid redirect URIs should work. Can you confirm that using just * gives you the same behavior? If so then we'll need to look beyond the redirect validation logic.
As for additional troubleshooting it may be worth a try to step up to trace logging. At the very least I'd expect that to show Keycloak is returning a 302 to localhost.
All reactions
Uh oh!
There was an error while loading. Please reload this page.
At least that confirms the issue lies elsewhere.
I mean on the keycloak side: log-level=trace
That should show a good representation of the conversation between the proxy and keycloak.
All reactions
Uh oh!
There was an error while loading. Please reload this page.
keycloak-log.txt
I've attached the full log for clarity sake; important lines occur @ ~66377
I don't see any clear indication in these logs as to why Keycloak decides to re-calcuate the redirect-uri [66412]. Do you see anything of interest here?
All reactions
Uh oh!
There was an error while loading. Please reload this page.
Sorry, the trace log did not contain entries I would have expected. I think you can use the keycloak quarkus.properties file to pass a couple of quarkus specific options - https://quarkus.io/guides/http-reference#configuring-http-access-logs
quarkus.http.access-log.enabled=true
quarkus.http.access-log.pattern="%{REQUEST_URL} %{RESPONSE_CODE} %{o,Location}"
Can you add those and go back to just debug logging?
All reactions
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
No worries,
I've included the requested quarkus options. I have a hard time understanding these logs; but it seems as if it's getting a 302 response and referencing the front-end-client-url (as expected??). Is this where you would have expected it to reference localhost:8080 instead? I've noted that nothing in the log reference localhost / localhost:8080; I suspect this is due to the forwarded X-Forwarded-Host.
I find it interesting that keycloaks uses a "303 See Other" response to redirect to the reverse-proxy again (2nd io.quarkus.http.access-log entry below); this indicates to me at least that it knows this is not the intended redirect-uri.
Is there a likelihood that it fails to redirect to my front-end URL as internally Keycloak is still hosted on HTTP and redirecting to a HTTPS resource is not expected/valid? Something akin to #39085?
quarkuslog.txt
[15561->15573]:
All reactions
Uh oh!
There was an error while loading. Please reload this page.
Yes - if Keycloak were directly at fault for this behavior.
Actually the problem is with the request, not the response. Something is asking for GET /?state=... - that is a request against the root of Keycloak, which is basically an attempt to fetch the welcome page, so Keycloak is responding with a 303
keycloak/services/src/main/java/org/keycloak/services/resources/WelcomeResource.java
Line 93 in 00d556d
Determine why the browser or the proxy server is sending this request and you'll be able to fix being sent to Keycloak's admin console.
All reactions