Keycloak Token request rejected because of invalid redirect URI
Asked Answered
H

3

10

After upgrading to Keycloak version 1.9.1 we’ve started to get rejections from keycloak.js while getting token based on code.

If we enter base url (http://example.com) then the app works fine, login is successful and token is retrieved.

Unfortunately when entering this child page (https://example.com/?redirect_fragment=/asset-library/card-view/ - it is sent from javascript with redirect_fragment encoded, but in keycloak logs it’s visible with this fragment decoded) we get error 400 while getting token after succesful login and obtaining the code. The precise response is:

{
  "error_description": "Incorrect redirect_uri",
  "error":"invalid_grant”
}

Why is that? In valid redirects uri in keycloak we have (just in case):

- https://example.com*
- https://example.com/*
- https://example.com/?redirect_fragment=/asset-library/card-view/
- https://example.com/?redirect_fragment=%2Fasset-library%2Fcard-view%2F
- http://example.com*
- http://example.com/*
- http://example.com/?redirect_fragment=/asset-library/card-view/
- http://example.com/?redirect_fragment=%2Fasset-library%2Fcard-view%2F

Here are the logs of succesful log in with redirect URI beeing http://example.com :

11:38:47,934 DEBUG [org.jboss.jca.core.connectionmanager.pool.validator.ConnectionValidator] (ConnectionValidator) Notifying pools, interval: 30000
11:38:47,935 DEBUG [org.jboss.jca.core.connectionmanager.pool.strategy.OnePool] (ConnectionValidator) Checking for connection within frequency
11:38:47,936 DEBUG [org.jboss.jca.core.connectionmanager.pool.strategy.OnePool] (ConnectionValidator) Returning for connection within frequency
11:38:47,937 DEBUG [org.jboss.jca.core.connectionmanager.pool.strategy.OnePool] (ConnectionValidator) Checking for connection within frequency
11:38:47,938 DEBUG [org.jboss.jca.core.connectionmanager.pool.strategy.OnePool] (ConnectionValidator) Returning for connection within frequency
11:38:47,938 DEBUG [org.jboss.jca.core.connectionmanager.pool.strategy.OnePool] (ConnectionValidator) Checking for connection within frequency
11:38:49,335 DEBUG [org.springframework.boot.context.web.OrderedRequestContextFilter] (default task-14) Bound request context to thread: HttpServletRequestImpl [ GET /auth/realms/xxxxxx/protocol/openid-connect/auth ]
11:38:49,336 DEBUG [org.jboss.resteasy.resteasy_jaxrs.i18n] (default task-14) RESTEASY002315: PathInfo: /realms/xxxxxx/protocol/openid-connect/auth
11:38:49,348 DEBUG [org.keycloak.services] (default task-14) AUTHENTICATE
11:38:49,357 DEBUG [org.keycloak.services] (default task-14) AUTHENTICATE ONLY
11:38:49,358 DEBUG [org.keycloak.services] (default task-14) processFlow
11:38:49,358 DEBUG [org.keycloak.services] (default task-14) check execution: auth-cookie requirement: ALTERNATIVE
11:38:49,358 DEBUG [org.keycloak.services] (default task-14) authenticator: auth-cookie
11:38:49,359 DEBUG [org.keycloak.services] (default task-14) invoke authenticator.authenticate
11:38:49,360 DEBUG [org.keycloak.services] (default task-14) token active - active: true, issued-at: 1,461,152,319, not-before: 0
11:38:49,361 DEBUG [org.keycloak.services] (default task-14) authenticator SUCCESS: auth-cookie
11:38:49,361 DEBUG [org.keycloak.services] (default task-14) check execution: auth-spnego requirement: DISABLED
11:38:49,361 DEBUG [org.keycloak.services] (default task-14) execution is processed
11:38:49,362 DEBUG [org.keycloak.services] (default task-14) check execution: null requirement: ALTERNATIVE
11:38:49,362 DEBUG [org.keycloak.services] (default task-14) Skip alternative execution
11:38:49,362 DEBUG [org.keycloak.services] (default task-14) Using full scope for client
11:38:49,363 DEBUG [org.keycloak.events] (default task-14) type=LOGIN, realmId=xxxxxx, clientId=api, userId=64e2ec92-a6ee-4705-a8b3-adebe9c3c816, ipAddress=172.17.0.1, auth_method=openid-connect, auth_type=code, response_type=code, redirect_uri=https://example.com/, consent=no_consent_required, code_id=1e564327-4775-4cbc-8e15-c3b553bc7585, response_mode=fragment, username=xxxxxx
11:38:49,384 DEBUG [org.keycloak.services] (default task-14) Create login cookie - name: KEYCLOAK_IDENTITY, path: /auth/realms/xxxxxx, max-age: -1
11:38:49,385 DEBUG [org.keycloak.services] (default task-14) redirectAccessCode: state: 0ecc910f-b0d2-4b9f-80ae-105c2dc28644
11:38:49,387 DEBUG [org.springframework.boot.context.web.OrderedRequestContextFilter] (default task-14) Cleared thread-bound request context: HttpServletRequestImpl [ GET /auth/realms/xxxxxx/protocol/openid-connect/auth ]
11:38:50,139 DEBUG [org.springframework.boot.context.web.OrderedRequestContextFilter] (default task-6) Bound request context to thread: HttpServletRequestImpl [ POST /auth/realms/xxxxxx/protocol/openid-connect/token ]
11:38:50,140 DEBUG [org.jboss.resteasy.resteasy_jaxrs.i18n] (default task-6) RESTEASY002315: PathInfo: /realms/xxxxxx/protocol/openid-connect/token
11:38:50,147 DEBUG [org.keycloak.services] (default task-6) AUTHENTICATE CLIENT
11:38:50,148 DEBUG [org.keycloak.services] (default task-6) client authenticator: client-secret
11:38:50,148 DEBUG [org.keycloak.services] (default task-6) client authenticator SUCCESS: client-secret
11:38:50,149 DEBUG [org.keycloak.services] (default task-6) Client api authenticated by client-secret
11:38:50,178 DEBUG [org.keycloak.events] (default task-6) type=CODE_TO_TOKEN, realmId=xxxxxx, clientId=api, userId=64e2ec92-a6ee-4705-a8b3-adebe9c3c816, ipAddress=172.17.0.1, token_id=dd46b7cd-6233-4881-8fe1-96e4ed087b37, grant_type=authorization_code, refresh_token_type=Refresh, refresh_token_id=0751e640-397d-45d7-a799-485a0573f20a, code_id=1e564327-4775-4cbc-8e15-c3b553bc7585, client_auth_method=client-secret
11:38:50,182 DEBUG [org.springframework.boot.context.web.OrderedRequestContextFilter] (default task-6) Cleared thread-bound request context: HttpServletRequestImpl [ POST /auth/realms/xxxxxx/protocol/openid-connect/token ]
11:38:50,353 DEBUG [org.springframework.boot.context.web.OrderedRequestContextFilter] (default task-10) Bound request context to thread: HttpServletRequestImpl [ GET /auth/realms/xxxxxx/protocol/openid-connect/userinfo ]
11:38:50,354 DEBUG [org.jboss.resteasy.resteasy_jaxrs.i18n] (default task-10) RESTEASY002315: PathInfo: /realms/xxxxxx/protocol/openid-connect/userinfo
11:38:50,356 DEBUG [org.keycloak.events] (default task-10) type=USER_INFO_REQUEST, realmId=xxxxxx, clientId=api, userId=64e2ec92-a6ee-4705-a8b3-adebe9c3c816, ipAddress=172.17.0.1, auth_method=validate_access_token, username=xxxxxx
11:38:50,358 DEBUG [org.springframework.boot.context.web.OrderedRequestContextFilter] (default task-10) Cleared thread-bound request context: HttpServletRequestImpl [ GET /auth/realms/xxxxxx/protocol/openid-connect/userinfo ]

And here are the logs of failed login with redirect URI being https://example.com/?redirect_fragment=/asset-library/card-view/:

11:37:15,360 DEBUG [org.springframework.boot.context.web.OrderedRequestContextFilter] (default task-7) Bound request context to thread: HttpServletRequestImpl [ GET /auth/realms/xxxxxx/protocol/openid-connect/auth ]
11:37:15,361 DEBUG [org.jboss.resteasy.resteasy_jaxrs.i18n] (default task-7) RESTEASY002315: PathInfo: /realms/xxxxxx/protocol/openid-connect/auth
11:37:15,366 DEBUG [org.keycloak.services] (default task-7) AUTHENTICATE
11:37:15,367 DEBUG [org.keycloak.services] (default task-7) AUTHENTICATE ONLY
11:37:15,367 DEBUG [org.keycloak.services] (default task-7) processFlow
11:37:15,368 DEBUG [org.keycloak.services] (default task-7) check execution: auth-cookie requirement: ALTERNATIVE
11:37:15,368 DEBUG [org.keycloak.services] (default task-7) authenticator: auth-cookie
11:37:15,369 DEBUG [org.keycloak.services] (default task-7) invoke authenticator.authenticate
11:37:15,371 DEBUG [org.keycloak.services] (default task-7) token active - active: true, issued-at: 1,461,152,203, not-before: 0
11:37:15,373 DEBUG [org.keycloak.services] (default task-7) authenticator SUCCESS: auth-cookie
11:37:15,374 DEBUG [org.keycloak.services] (default task-7) check execution: auth-spnego requirement: DISABLED
11:37:15,374 DEBUG [org.keycloak.services] (default task-7) execution is processed
11:37:15,375 DEBUG [org.keycloak.services] (default task-7) check execution: null requirement: ALTERNATIVE
11:37:15,375 DEBUG [org.keycloak.services] (default task-7) Skip alternative execution
11:37:15,376 DEBUG [org.keycloak.services] (default task-7) Using full scope for client
11:37:15,377 DEBUG [org.keycloak.events] (default task-7) type=LOGIN, realmId=xxxxxx, clientId=api, userId=64e2ec92-a6ee-4705-a8b3-adebe9c3c816, ipAddress=172.17.0.1, auth_method=openid-connect, auth_type=code, response_type=code, redirect_uri=https://example.com/?redirect_fragment=/asset-library/card-view/, consent=no_consent_required, code_id=a47d3089-699e-4bc5-811c-e4a45655994a, response_mode=fragment, username=xxxxxx
11:37:15,397 DEBUG [org.keycloak.services] (default task-7) Create login cookie - name: KEYCLOAK_IDENTITY, path: /auth/realms/xxxxxx, max-age: -1
11:37:15,398 DEBUG [org.keycloak.services] (default task-7) redirectAccessCode: state: 0e2f72bc-14a4-46f8-8169-c55c85a50830
11:37:15,398 DEBUG [org.springframework.boot.context.web.OrderedRequestContextFilter] (default task-7) Cleared thread-bound request context: HttpServletRequestImpl [ GET /auth/realms/xxxxxx/protocol/openid-connect/auth ]
11:37:16,148 DEBUG [org.springframework.boot.context.web.OrderedRequestContextFilter] (default task-13) Bound request context to thread: HttpServletRequestImpl [ POST /auth/realms/xxxxxx/protocol/openid-connect/token ]
11:37:16,148 DEBUG [org.jboss.resteasy.resteasy_jaxrs.i18n] (default task-13) RESTEASY002315: PathInfo: /realms/xxxxxx/protocol/openid-connect/token
11:37:16,150 DEBUG [org.keycloak.services] (default task-13) AUTHENTICATE CLIENT
11:37:16,150 DEBUG [org.keycloak.services] (default task-13) client authenticator: client-secret
11:37:16,151 DEBUG [org.keycloak.services] (default task-13) client authenticator SUCCESS: client-secret
11:37:16,151 DEBUG [org.keycloak.services] (default task-13) Client api authenticated by client-secret
11:37:16,151 WARN  [org.keycloak.events] (default task-13) type=CODE_TO_TOKEN_ERROR, realmId=xxxxxx, clientId=api, userId=64e2ec92-a6ee-4705-a8b3-adebe9c3c816, ipAddress=172.17.0.1, error=invalid_code, grant_type=authorization_code, code_id=a47d3089-699e-4bc5-811c-e4a45655994a, client_auth_method=client-secret
11:37:16,153 DEBUG [org.springframework.boot.context.web.OrderedRequestContextFilter] (default task-13) Cleared thread-bound request context: HttpServletRequestImpl [ POST /auth/realms/xxxxxx/protocol/openid-connect/token ]
11:37:17,928 DEBUG [org.jboss.jca.core.connectionmanager.pool.validator.ConnectionValidator] (ConnectionValidator) Notifying pools, interval: 30000
11:37:17,928 DEBUG [org.jboss.jca.core.connectionmanager.pool.strategy.OnePool] (ConnectionValidator) Checking for connection within frequency
Hospitium answered 20/4, 2016 at 12:2 Comment(0)
S
3

Seems like you are trying both https and http URL schemes. The Valid Redirect URIs settings is a regex pattern against which are the redirect URIs validated.

Anyway, you should keep entire page on the secured HTTP for security reasons. Thus a redirect pattern like: https://example.com/* should work.

Syracuse answered 21/11, 2016 at 12:13 Comment(0)
S
0

the real problem is keycloak has 21 major versions and it works differently in each one. the documentation, however, does not aknowledge that and doesn't help a bit with setting up your integration with keycloak.

i had the exact same problem as this question and ended up fixing it watching a tutorial on youtube(link bellow).

so yeah, this is A solution to this problem, maybe not the best, but works fine. problably will be different in another version of keycloak but, as of version 21.1.1 this works well. Personaly, i wouldnt use keycloak ever again, i followed the documentation and spent hours trying to make it work just to throw all the knowledge i got from the official docs off the window and follow a tutorial. for example, the docs say that the redirect uri is required for the token request but, i didnt need it at the end. Anyways, I hope this helps anyone in need.

youtube video

Solvency answered 17/5, 2023 at 16:45 Comment(3)
Your comment does not help to solve the problem, since a redirect_uri is needed as the author mentioned.Likewise
like i said, i know that it should be needed, but i tried multiple times and couldn't get it to work, the tutorial helped me fix it, maybe if you watch, it can help you. I dont really understand it, but seems like you can just set the redirect uri in the keycloak server configs(just follow the tutorial) and it redirects correctly after logging in @LikewiseSolvency
i know it is counter-intuitive to abandon the docs and just do what some stranger says in a poor quality video, but it worked for me and thats good enough. after wasting days reading the docs to no avail, anything goesSolvency
P
0

I was stuck on this same issue, and finally found this in the openid-connect-core documentation:

3.1.3.2.  Token Request Validation
    The Authorization Server MUST validate the Token Request as follows:

        * Authenticate the Client if it was issued Client Credentials or if it uses another Client Authentication method, per Section 9.
        * Ensure the Authorization Code was issued to the authenticated Client.
        * Verify that the Authorization Code is valid.
        * If possible, verify that the Authorization Code has not been previously used.
        * Ensure that the redirect_uri parameter value is identical to the redirect_uri parameter value that was included in the initial Authorization Request. If the redirect_uri parameter value is not present when there is only one registered redirect_uri value, the Authorization Server MAY return an error (since the Client should have included the parameter) or MAY proceed without an error (since OAuth 2.0 permits the parameter to be omitted in this case).
        * Verify that the Authorization Code used was issued in response to an OpenID Connect Authentication Request (so that an ID Token will be returned from the Token Endpoint).

This solved the issue for me since I wasn't using the identical uri as the initial Authorization Request.

Provide answered 31/5 at 9:44 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.