From 9a3d81c23ef66c9a6b7d59d83ce13716198b4d79 Mon Sep 17 00:00:00 2001 From: Pedro Igor Date: Wed, 9 Oct 2024 12:15:46 -0300 Subject: [PATCH] Only process organization selection when the user is identified Closes #33699 Signed-off-by: Pedro Igor --- .../browser/OrganizationAuthenticator.java | 2 +- .../organization/utils/Organizations.java | 4 ++-- .../OrganizationOIDCProtocolMapperTest.java | 24 +++++++++++++++++++ 3 files changed, 27 insertions(+), 3 deletions(-) diff --git a/services/src/main/java/org/keycloak/organization/authentication/authenticators/browser/OrganizationAuthenticator.java b/services/src/main/java/org/keycloak/organization/authentication/authenticators/browser/OrganizationAuthenticator.java index 37cf701e7f..65a9e4eba7 100644 --- a/services/src/main/java/org/keycloak/organization/authentication/authenticators/browser/OrganizationAuthenticator.java +++ b/services/src/main/java/org/keycloak/organization/authentication/authenticators/browser/OrganizationAuthenticator.java @@ -159,7 +159,7 @@ public class OrganizationAuthenticator extends IdentityProviderAuthenticator { String rawScope = authSession.getClientNote(OAuth2Constants.SCOPE); OrganizationScope scope = OrganizationScope.valueOfScope(rawScope); - if (!OrganizationScope.ANY.equals(scope)) { + if (!OrganizationScope.ANY.equals(scope) || user == null) { return false; } diff --git a/services/src/main/java/org/keycloak/organization/utils/Organizations.java b/services/src/main/java/org/keycloak/organization/utils/Organizations.java index cf41db90aa..b74a6d9222 100644 --- a/services/src/main/java/org/keycloak/organization/utils/Organizations.java +++ b/services/src/main/java/org/keycloak/organization/utils/Organizations.java @@ -210,8 +210,8 @@ public class Organizations { if (organizations.size() == 1) { // single organization mapped from authentication session return organizations.get(0); - } else if (scope != null) { - // organization scope requested but no single organization mapped from the scope + } else if (scope != null && user != null) { + // organization scope requested but no user and no single organization mapped from the scope return null; } } diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/organization/mapper/OrganizationOIDCProtocolMapperTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/organization/mapper/OrganizationOIDCProtocolMapperTest.java index 1b44c3dc2b..ded4e1c439 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/organization/mapper/OrganizationOIDCProtocolMapperTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/organization/mapper/OrganizationOIDCProtocolMapperTest.java @@ -33,6 +33,7 @@ import static org.junit.Assert.assertTrue; import java.net.MalformedURLException; import java.net.URL; +import java.time.Duration; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -47,6 +48,7 @@ import org.keycloak.admin.client.resource.ClientScopeResource; import org.keycloak.admin.client.resource.OrganizationResource; import org.keycloak.common.util.MultivaluedHashMap; import org.keycloak.common.util.UriUtils; +import org.keycloak.models.OrganizationModel; import org.keycloak.organization.protocol.mappers.oidc.OrganizationMembershipMapper; import org.keycloak.protocol.ProtocolMapperUtils; import org.keycloak.protocol.oidc.OIDCLoginProtocol; @@ -57,6 +59,8 @@ import org.keycloak.representations.AccessToken; import org.keycloak.representations.RefreshToken; import org.keycloak.representations.idm.ClientRepresentation; import org.keycloak.representations.idm.ClientScopeRepresentation; +import org.keycloak.representations.idm.FederatedIdentityRepresentation; +import org.keycloak.representations.idm.IdentityProviderRepresentation; import org.keycloak.representations.idm.MemberRepresentation; import org.keycloak.representations.idm.OrganizationRepresentation; import org.keycloak.representations.idm.ProtocolMapperRepresentation; @@ -540,6 +544,26 @@ public class OrganizationOIDCProtocolMapperTest extends AbstractOrganizationTest assertEquals("invalid_scope", queryParams.getFirst("error")); } + @Test + public void testAuthenticatingUsingBroker() { + driver.manage().timeouts().pageLoadTimeout(Duration.ofDays(1)); + OrganizationResource organization = testRealm().organizations().get(createOrganization().getId()); + IdentityProviderRepresentation idp = organization.identityProviders().get(bc.getIDPAlias()).toRepresentation(); + idp.getConfig().put(OrganizationModel.ORGANIZATION_DOMAIN_ATTRIBUTE, "neworg.org"); + testRealm().identityProviders().get(bc.getIDPAlias()).update(idp); + + oauth.scope(OAuth2Constants.ORGANIZATION); + openIdentityFirstLoginPage(bc.getUserEmail(), true, idp.getAlias(), false, false); + + loginOrgIdp(bc.getUserEmail(), bc.getUserEmail(),true, true); + + assertIsMember(bc.getUserEmail(), organization); + UserRepresentation user = testRealm().users().search(bc.getUserEmail()).get(0); + List federatedIdentities = testRealm().users().get(user.getId()).getFederatedIdentity(); + assertEquals(1, federatedIdentities.size()); + assertEquals(bc.getIDPAlias(), federatedIdentities.get(0).getIdentityProvider()); + } + private ProtocolMapperRepresentation createGroupMapper() { ProtocolMapperRepresentation groupMapper = new ProtocolMapperRepresentation(); groupMapper.setName("groups");