Skip to content

Failure to redirect to organization IdP when the organization scope is included #33699

@CarlosRodrigues

Description

@CarlosRodrigues

Before reporting an issue

  • I have read and understood the above terms for submitting issues, and I understand that my issue may be closed without action if I do not follow them.

Area

organizations

Describe the bug

Hi,

I'm having a strange behavior when redirecting to the organization linked IdP.

Steps to reproduce:

  • Create an org with a domain (e.g. test.com)
  • Create an IdP (in my case SAML) and link it to the org using the test.com domain, and tick the redirection checkbox.

With a client that already has the organizations mapper, proceed to the login page.
Now, here's where it starts to become strange. If the login page is loaded without the organization scope, it work as expected, and the browser redirects to the external IdP.

If the login url contains the organizations scope (so the token that is sent back to the front-end app includes the organizations claim in the access token), it fails with the following error:

Unexpected error when handling authentication request to identity provider.

and the following stack trace:

keycloak_web  | 2024-10-08 15:32:47,764 WARN  [org.keycloak.services] (executor-thread-57) KC-SERVICES0013: Failed authentication: java.lang.NullPointerException: Cannot invoke "org.keycloak.models.UserModel.getId()" because "user" is null
keycloak_web  |         at org.keycloak.models.cache.infinispan.organization.InfinispanOrganizationProvider.cacheKeyByMember(InfinispanOrganizationProvider.java:350)
keycloak_web  |         at org.keycloak.models.cache.infinispan.organization.InfinispanOrganizationProvider.getByMember(InfinispanOrganizationProvider.java:223)
keycloak_web  |         at org.keycloak.organization.authentication.authenticators.browser.OrganizationAuthenticator.shouldUserSelectOrganization(OrganizationAuthenticator.java:166)
keycloak_web  |         at org.keycloak.organization.authentication.authenticators.browser.OrganizationAuthenticator.action(OrganizationAuthenticator.java:98)
keycloak_web  |         at org.keycloak.authentication.DefaultAuthenticationFlow.processAction(DefaultAuthenticationFlow.java:149)
keycloak_web  |         at org.keycloak.authentication.AuthenticationProcessor.authenticationAction(AuthenticationProcessor.java:1034)
keycloak_web  |         at org.keycloak.services.resources.LoginActionsService.processFlow(LoginActionsService.java:378)
keycloak_web  |         at org.keycloak.services.resources.LoginActionsService.processAuthentication(LoginActionsService.java:349)
keycloak_web  |         at org.keycloak.services.resources.LoginActionsService.authenticate(LoginActionsService.java:341)
keycloak_web  |         at org.keycloak.services.resources.LoginActionsService.authenticateForm(LoginActionsService.java:407)
keycloak_web  |         at org.keycloak.services.resources.LoginActionsService$quarkusrestinvoker$authenticateForm_13d428b70e62601585246c086a52f40868a3208e.invoke(Unknown Source)
keycloak_web  |         at org.jboss.resteasy.reactive.server.handlers.InvocationHandler.handle(InvocationHandler.java:29)
keycloak_web  |         at io.quarkus.resteasy.reactive.server.runtime.QuarkusResteasyReactiveRequestContext.invokeHandler(QuarkusResteasyReactiveRequestContext.java:141)
keycloak_web  |         at org.jboss.resteasy.reactive.common.core.AbstractResteasyReactiveContext.run(AbstractResteasyReactiveContext.java:147)
keycloak_web  |         at io.quarkus.vertx.core.runtime.VertxCoreRecorder$14.runWith(VertxCoreRecorder.java:635)
keycloak_web  |         at org.jboss.threads.EnhancedQueueExecutor$Task.doRunWith(EnhancedQueueExecutor.java:2516)
keycloak_web  |         at org.jboss.threads.EnhancedQueueExecutor$Task.run(EnhancedQueueExecutor.java:2495)
keycloak_web  |         at org.jboss.threads.EnhancedQueueExecutor$ThreadBody.run(EnhancedQueueExecutor.java:1521)
keycloak_web  |         at org.jboss.threads.DelegatingRunnable.run(DelegatingRunnable.java:11)
keycloak_web  |         at org.jboss.threads.ThreadLocalResettingRunnable.run(ThreadLocalResettingRunnable.java:11)
keycloak_web  |         at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
keycloak_web  |         at java.base/java.lang.Thread.run(Thread.java:1583)
keycloak_web  | 
keycloak_web  | 2024-10-08 15:32:47,765 WARN  [org.keycloak.events] (executor-thread-57) type="LOGIN_ERROR", realmId="25ba435c-ea99-42f5-ac00-65cd7951a6b1", realmName="REDACTED", clientId="frontend", userId="null", ipAddress="172.21.0.1", error="invalid_user_credentials", auth_method="openid-connect", auth_type="code", redirect_uri="https://REDACTED/", code_id="98a4fd8b-14af-46d5-9285-6586e93645cc"

the login url that works: /protocol/openid-connect/auth?client_id=frontend&redirect_uri=&response_mode=fragment&response_type=code&scope=openid&nonce=&code_challenge=&code_challenge_method=S256

and the one that doesn't work:
/protocol/openid-connect/auth?client_id=frontend&redirect_uri=&response_mode=fragment&response_type=code&scope=openid+organization&nonce=&code_challenge=&code_challenge_method=S256
(added "+organization" in the scope)

Thanks in advance!

Version

26

Regression

  • The issue is a regression

Expected behavior

User is redirected to the IdP

Actual behavior

Redirection to the external IdP doesn't work, and instead an error is thrown.

How to Reproduce?

Open the login page of a client with the organization scope.
Fill in an email from a linked organization IdP.

Anything else?

No response

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions