Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

After 7.3.0 authentication for web mvc client against keycloak ends in endless redirect #174

Closed
yennor opened this issue Jan 10, 2024 · 8 comments
Assignees
Labels
bug Something isn't working

Comments

@yennor
Copy link
Contributor

yennor commented Jan 10, 2024

Describe the bug
I use a webmvc client authenticating against keycloak.
It works perfectly up to and with version 7.2.0.
From 7.3.0 on it doesn't work anymore.
The client always throws a

org.springframework.security.oauth2.core.OAuth2AuthenticationException: [invalid_grant] Incorrect redirect_uri 
exception.

Keycloak shows me a

type=CODE_TO_TOKEN_ERROR,  error=invalid_code, grant_type=authorization_code,  client_auth_method=client-secret
error.

I think I had a similar error in the past once. As far as I remember the problem was using different redirect_uri for the code and the token or something like that (long time ago).
I've tried to look through the changes from 7.2.0 to 7.3.0 but I don't understand them 100%. But something changed with the redirect_uri, as far as i can see.

But the whole thing ends in an endless redirect from keycloak, to localhost, back to keycloak, ...

config looks like:

issuer: https://example.com/realms/example
client-id: example
client-secret: secret
client-uri: http://localhost:8080

spring:
  security:
    oauth2:
      client:
        provider:
          keycloak:
            issuer-uri: ${issuer}
        registration:
          keycloak-user:
            authorization-grant-type: authorization_code
            client-name: My Keycloak instance
            client-id: ${client-id}
            client-secret: ${client-secret}
            provider: keycloak
            scope: openid,profile,email,offline_access

com:
  c4-soft:
    springaddons:
      oidc:
        ops:
        - iss: ${issuer}
          username-claim: $.preferred_username
          authorities:
          - path: $.realm_access.roles
          - path: $.resource_access.*.roles
        client:
          security-matchers: /**
          permit-all:
          - /login/**
          - /logout/**
          - /oauth2/**
          - /public/**
          - /webjars/**
          - /npm/**
          - /images/**
          client-uri: ${client-uri}
          post-login-redirect-path: /
          post-logout-redirect-path: /
          csrf: session
@yennor yennor added the bug Something isn't working label Jan 10, 2024
@ch4mpy
Copy link
Owner

ch4mpy commented Jan 10, 2024

This error is thrown by Keycloak.

Have you changed one of:

  • allowed redirect URIs in Keycloak
  • clientId in Spring
  • something in the client URI (hostname or port of the Spring app with oauth2Login)

The last two points lead to a new authorization-code callback that could possibly not be allowed in Keycloak.

But according to the little log you join, it seems that you have an issue with the authorization-code itself.

Please attach more Keycloak logs.

Please also add your security conf (SecurityFilterChain if you defined one and any other @Bean injected into it or into spring-addons one).

What is the version of Keycloak you are using?

Can you setup a minimal reproducer? I don't have this kind of error with my OAuth2 clients authenticating users on Keycloak 23.0.1

@yennor
Copy link
Contributor Author

yennor commented Jan 10, 2024

  • I didn't change any of the points you've mentioned. I'm only changing spring-addons from 7.2.0 to 7.3.1 and it stops working.
  • There's no SecurityFilterChain or any other bean injected into spring-addons.
  • Keycloak Version 21.1.0 (Unfortunately I don't have control over that version)
  • I'll try to setup a minimal reproducer. But can't do it today anymore. My battery's running out of power, and I've only got solar panels...
  • Here more keycloak logs. It doesn't log the success to the console, so I've attached a screenshot:
    image
  • more log:
2024-01-10T14:04:21.337-05:00 DEBUG 59833 --- [nio-8080-exec-1] mo.s.security.web.FilterChainProxy        : Securing GET /
2024-01-10T14:04:21.340-05:00 DEBUG 59833 --- [nio-8080-exec-1] mo.s.s.w.a.AnonymousAuthenticationFilter  : Set SecurityContextHolder to anonymous SecurityContext
2024-01-10T14:04:21.346-05:00 DEBUG 59833 --- [nio-8080-exec-1] mo.s.s.w.s.HttpSessionRequestCache        : Saved request http://localhost:8080/?continue to session
2024-01-10T14:04:21.351-05:00 DEBUG 59833 --- [nio-8080-exec-1] ms.w.a.DelegatingAuthenticationEntryPoint : Trying to match using And [Not [RequestHeaderRequestMatcher [expectedHeaderName=X-Requested-With, expectedHeaderValue=XMLHttpRequest]], Not [And [Or [Ant [pattern='/login'], Ant [pattern='/favicon.ico']], And [Not [RequestHeaderRequestMatcher [expectedHeaderName=X-Requested-With, expectedHeaderValue=XMLHttpRequest]], MediaTypeRequestMatcher [contentNegotiationStrategy=org.springframework.web.accept.ContentNegotiationManager@5e221658, matchingMediaTypes=[application/xhtml+xml, image/*, text/html, text/plain], useEquals=false, ignoredMediaTypes=[*/*]]]]], org.springframework.security.config.annotation.web.configurers.oauth2.client.OAuth2LoginConfigurer$$Lambda$1986/0x00007f38e0bb4f88@fd98f04]
2024-01-10T14:04:21.352-05:00 DEBUG 59833 --- [nio-8080-exec-1] ms.w.a.DelegatingAuthenticationEntryPoint : Match found! Executing org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint@34188df5
2024-01-10T14:04:21.352-05:00 DEBUG 59833 --- [nio-8080-exec-1] mo.s.s.web.DefaultRedirectStrategy        : Redirecting to http://localhost:8080/oauth2/authorization/keycloak-user
2024-01-10T14:04:21.367-05:00 DEBUG 59833 --- [nio-8080-exec-2] mo.s.security.web.FilterChainProxy        : Securing GET /oauth2/authorization/keycloak-user
2024-01-10T14:04:23.203-05:00 DEBUG 59833 --- [nio-8080-exec-3] mo.s.security.web.FilterChainProxy        : Securing GET /login/oauth2/code/keycloak-user?state=QI86x4nj74M0bgYe_IGhinOiipNDuJTRyO3cfg_MkXQ%3D&session_state=f866f353-749c-4861-8e31-416f18763a1c&code=05eb52a0-9f44-4b09-8699-efba074b9b2b.f866f353-749c-4861-8e31-416f18763a1c.d0d36e71-da18-474d-95d6-a58a3af492fd
2024-01-10T14:04:23.669-05:00 DEBUG 59833 --- [nio-8080-exec-3] m.s.a.DefaultAuthenticationEventPublisher : No event was found for the exception org.springframework.security.oauth2.core.OAuth2AuthenticationException
2024-01-10T14:04:23.685-05:00 DEBUG 59833 --- [nio-8080-exec-4] mo.s.security.web.FilterChainProxy        : Securing GET /
2024-01-10T14:04:23.686-05:00 DEBUG 59833 --- [nio-8080-exec-4] mo.s.s.w.a.AnonymousAuthenticationFilter  : Set SecurityContextHolder to anonymous SecurityContext
2024-01-10T14:04:23.688-05:00 DEBUG 59833 --- [nio-8080-exec-4] mo.s.s.w.s.HttpSessionRequestCache        : Saved request http://localhost:8080/?continue to session
2024-01-10T14:04:23.688-05:00 DEBUG 59833 --- [nio-8080-exec-4] ms.w.a.DelegatingAuthenticationEntryPoint : Trying to match using And [Not [RequestHeaderRequestMatcher [expectedHeaderName=X-Requested-With, expectedHeaderValue=XMLHttpRequest]], Not [And [Or [Ant [pattern='/login'], Ant [pattern='/favicon.ico']], And [Not [RequestHeaderRequestMatcher [expectedHeaderName=X-Requested-With, expectedHeaderValue=XMLHttpRequest]], MediaTypeRequestMatcher [contentNegotiationStrategy=org.springframework.web.accept.ContentNegotiationManager@5e221658, matchingMediaTypes=[application/xhtml+xml, image/*, text/html, text/plain], useEquals=false, ignoredMediaTypes=[*/*]]]]], org.springframework.security.config.annotation.web.configurers.oauth2.client.OAuth2LoginConfigurer$$Lambda$1986/0x00007f38e0bb4f88@fd98f04]
2024-01-10T14:04:23.689-05:00 DEBUG 59833 --- [nio-8080-exec-4] ms.w.a.DelegatingAuthenticationEntryPoint : Match found! Executing org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint@34188df5
2024-01-10T14:04:23.689-05:00 DEBUG 59833 --- [nio-8080-exec-4] mo.s.s.web.DefaultRedirectStrategy        : Redirecting to http://localhost:8080/oauth2/authorization/keycloak-user
2024-01-10T14:04:23.699-05:00 DEBUG 59833 --- [nio-8080-exec-5] mo.s.security.web.FilterChainProxy        : Securing GET /oauth2/authorization/keycloak-user
2024-01-10T14:04:23.958-05:00 DEBUG 59833 --- [nio-8080-exec-6] mo.s.security.web.FilterChainProxy        : Securing GET /login/oauth2/code/keycloak-user?state=49MqUTPNet-NDmHXDLH3xeTEXB_74b5yEgkX14NEX1k%3D&session_state=f866f353-749c-4861-8e31-416f18763a1c&code=48a870d8-ed20-4334-b2db-f976a2bc9b55.f866f353-749c-4861-8e31-416f18763a1c.d0d36e71-da18-474d-95d6-a58a3af492fd
2024-01-10T14:04:24.674-05:00 DEBUG 59833 --- [nio-8080-exec-6] m.s.a.DefaultAuthenticationEventPublisher : No event was found for the exception org.springframework.security.oauth2.core.OAuth2AuthenticationException
2024-01-10T14:04:24.687-05:00 DEBUG 59833 --- [nio-8080-exec-7] mo.s.security.web.FilterChainProxy        : Securing GET /
2024-01-10T14:04:24.688-05:00 DEBUG 59833 --- [nio-8080-exec-7] mo.s.s.w.a.AnonymousAuthenticationFilter  : Set SecurityContextHolder to anonymous SecurityContext
2024-01-10T14:04:24.690-05:00 DEBUG 59833 --- [nio-8080-exec-7] mo.s.s.w.s.HttpSessionRequestCache        : Saved request http://localhost:8080/?continue to session
2024-01-10T14:04:24.690-05:00 DEBUG 59833 --- [nio-8080-exec-7] ms.w.a.DelegatingAuthenticationEntryPoint : Trying to match using And [Not [RequestHeaderRequestMatcher [expectedHeaderName=X-Requested-With, expectedHeaderValue=XMLHttpRequest]], Not [And [Or [Ant [pattern='/login'], Ant [pattern='/favicon.ico']], And [Not [RequestHeaderRequestMatcher [expectedHeaderName=X-Requested-With, expectedHeaderValue=XMLHttpRequest]], MediaTypeRequestMatcher [contentNegotiationStrategy=org.springframework.web.accept.ContentNegotiationManager@5e221658, matchingMediaTypes=[application/xhtml+xml, image/*, text/html, text/plain], useEquals=false, ignoredMediaTypes=[*/*]]]]], org.springframework.security.config.annotation.web.configurers.oauth2.client.OAuth2LoginConfigurer$$Lambda$1986/0x00007f38e0bb4f88@fd98f04]
2024-01-10T14:04:24.690-05:00 DEBUG 59833 --- [nio-8080-exec-7] ms.w.a.DelegatingAuthenticationEntryPoint : Match found! Executing org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint@34188df5
2024-01-10T14:04:24.690-05:00 DEBUG 59833 --- [nio-8080-exec-7] mo.s.s.web.DefaultRedirectStrategy        : Redirecting to http://localhost:8080/oauth2/authorization/keycloak-user
2024-01-10T14:04:24.701-05:00 DEBUG 59833 --- [nio-8080-exec-8] mo.s.security.web.FilterChainProxy        : Securing GET /oauth2/authorization/keycloak-user

@ch4mpy
Copy link
Owner

ch4mpy commented Jan 10, 2024

Could you please join the complete URI for the authorization-code flow (with scheme, authority and params). Something like:

@yennor
Copy link
Contributor Author

yennor commented Jan 13, 2024

here we go.
I'll prepare a minimal setup and provide the link here in a moment..

GET http://localhost:8080/ => 302 http://localhost:8080/oauth2/authorization/keycloak-user

GET http://localhost:8080/oauth2/authorization/keycloak-user => 302 Location:
https://auth.intranet.example.com/realms/example.com/protocol/openid-connect/auth?response_type=code&client_id=hotline-thurgau-dev&scope=openid%20profile%20email%20offline_access&state=2GoZQboLNYpOvEuyJE4WUgs8HMhM1ajJmEIZeyHMraY%3D&redirect_uri=http://localhost:8080/login/oauth2/code/keycloak-user&nonce=6dQBt6IKShPGPgBYKJHLk1j3vmBTXoV_732RCFaw5UM

GET https://auth.intranet.example.com/realms/example.com/protocol/openid-connect/auth?response_type=code&client_id=hotline-thurgau-dev&scope=openid%20profile%20email%20offline_access&state=2GoZQboLNYpOvEuyJE4WUgs8HMhM1ajJmEIZeyHMraY%3D&redirect_uri=http://localhost:8080/login/oauth2/code/keycloak-user&nonce=6dQBt6IKShPGPgBYKJHLk1j3vmBTXoV_732RCFaw5UM => 200

POST https://auth.intranet.example.com/realms/example.com/login-actions/authenticate?session_code=ezx_VSj1RRrmYqnbS6D95XZVO1NxHNxfVhL0D4Q3xeQ&execution=d89c4380-50ef-4a97-a4cc-1a76df1d11a9&client_id=hotline-thurgau-dev&tab_id=WbntdJBVkh0 => 302 http://localhost:8080/login/oauth2/code/keycloak-user?state=2GoZQboLNYpOvEuyJE4WUgs8HMhM1ajJmEIZeyHMraY%3D&session_state=393fd19d-2163-40d6-880f-c9f94b6ca567&code=138186ac-15de-49c1-9977-4f75b493086a.393fd19d-2163-40d6-880f-c9f94b6ca567.d0d36e71-da18-474d-95d6-a58a3af492fd

GET http://localhost:8080/login/oauth2/code/keycloak-user?state=2GoZQboLNYpOvEuyJE4WUgs8HMhM1ajJmEIZeyHMraY%3D&session_state=393fd19d-2163-40d6-880f-c9f94b6ca567&code=138186ac-15de-49c1-9977-4f75b493086a.393fd19d-2163-40d6-880f-c9f94b6ca567.d0d36e71-da18-474d-95d6-a58a3af492fd => 302 http://localhost:8080/

GET http://localhost:8080/ => 302 http://localhost:8080/oauth2/authorization/keycloak-user

GET http://localhost:8080/oauth2/authorization/keycloak-user => 302 https://auth.intranet.example.com/realms/example.com/protocol/openid-connect/auth?response_type=code&client_id=hotline-thurgau-dev&scope=openid%20profile%20email%20offline_access&state=fHDCCU8sji8AHZkkw8HWanZfWVVoxoJA18ImNhwcFa8%3D&redirect_uri=http://localhost:8080/login/oauth2/code/keycloak-user&nonce=8xIWLJckGPv2oEFg8ssoISG3nmexWqCks5bo0_kkLDg

GET https://auth.intranet.example.com/realms/example.com/protocol/openid-connect/auth?response_type=code&client_id=hotline-thurgau-dev&scope=openid%20profile%20email%20offline_access&state=fHDCCU8sji8AHZkkw8HWanZfWVVoxoJA18ImNhwcFa8%3D&redirect_uri=http://localhost:8080/login/oauth2/code/keycloak-user&nonce=8xIWLJckGPv2oEFg8ssoISG3nmexWqCks5bo0_kkLDg => 302 http://localhost:8080/login/oauth2/code/keycloak-user?state=fHDCCU8sji8AHZkkw8HWanZfWVVoxoJA18ImNhwcFa8%3D&session_state=393fd19d-2163-40d6-880f-c9f94b6ca567&code=ddeb1751-5710-455d-b986-cd7811ceeda9.393fd19d-2163-40d6-880f-c9f94b6ca567.d0d36e71-da18-474d-95d6-a58a3af492fd

GET http://localhost:8080/login/oauth2/code/keycloak-user?state=fHDCCU8sji8AHZkkw8HWanZfWVVoxoJA18ImNhwcFa8%3D&session_state=393fd19d-2163-40d6-880f-c9f94b6ca567&code=ddeb1751-5710-455d-b986-cd7811ceeda9.393fd19d-2163-40d6-880f-c9f94b6ca567.d0d36e71-da18-474d-95d6-a58a3af492fd => 302 http://localhost:8080/

etc...

@yennor
Copy link
Contributor Author

yennor commented Jan 13, 2024

here i've added a minimal projekt
https://github.com/yennor/springaddonsmin

@ch4mpy
Copy link
Owner

ch4mpy commented Jan 14, 2024

@yennor thank you for the reproducer, it is of great help for investigations.

What I spotted so far is that inside DefaultAuthorizationCodeTokenResponseClient::getTokenResponse, when inspecting the body of the request, the value of the redirect_uri has changed from https://localhost:7080/login/oauth2/code/keycloak-user to https://localhost:7080/oauth2/authorization/keycloak-user (which is wrong as we gave https://localhost:7080/login/oauth2/code/keycloak-user to Keycloak as redirect_uri in the authorization request).

This is a regression I'll fix (haven't found why yet and have limited time today, but will do soon).

@ch4mpy
Copy link
Owner

ch4mpy commented Jan 15, 2024

@yennor I published a 7.3.2 which should fix this issue. Please confirm and close.

This issue was specific to synchronized apps (servlets).

@yennor
Copy link
Contributor Author

yennor commented Jan 15, 2024

works like a charm. thanks a lot :-)

@yennor yennor closed this as completed Jan 15, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants