From 743bb696d9d513d3fa06cced35a13aa951e86674 Mon Sep 17 00:00:00 2001 From: rmartinc Date: Mon, 11 Sep 2023 15:45:31 +0200 Subject: [PATCH] Allow duplicated keys in advanced claim mappers Closes https://github.com/keycloak/keycloak/issues/22638 --- .../models/IdentityProviderMapperModel.java | 9 ++++- .../mappers/AdvancedClaimToGroupMapper.java | 15 ++++---- .../mappers/AdvancedClaimToRoleMapper.java | 17 +++++---- .../mappers/ClaimToUserSessionNoteMapper.java | 37 ++++++++++--------- .../AdvancedAttributeToGroupMapper.java | 30 ++++++++------- .../AdvancedAttributeToRoleMapper.java | 30 ++++++++------- .../AbstractAdvancedRoleMapperTest.java | 8 +++- .../broker/AbstractGroupBrokerMapperTest.java | 8 +++- ...amlAdvancedAttributeToGroupMapperTest.java | 5 ++- ...SamlAdvancedAttributeToRoleMapperTest.java | 6 ++- .../OidcClaimToUserSessionNoteMapperTest.java | 17 +++++++-- 11 files changed, 109 insertions(+), 73 deletions(-) diff --git a/server-spi/src/main/java/org/keycloak/models/IdentityProviderMapperModel.java b/server-spi/src/main/java/org/keycloak/models/IdentityProviderMapperModel.java index dde4ee8cb4..d49a5373e0 100755 --- a/server-spi/src/main/java/org/keycloak/models/IdentityProviderMapperModel.java +++ b/server-spi/src/main/java/org/keycloak/models/IdentityProviderMapperModel.java @@ -22,6 +22,7 @@ import org.keycloak.util.JsonSerialization; import java.io.IOException; import java.io.Serializable; +import java.util.Collections; import java.util.List; import java.util.Map; import java.util.stream.Collectors; @@ -93,12 +94,16 @@ public class IdentityProviderMapperModel implements Serializable { this.config = config; } - public Map getConfigMap(String configKey) { + public Map> getConfigMap(String configKey) { String configMap = config.get(configKey); try { List map = JsonSerialization.readValue(configMap, MAP_TYPE_REPRESENTATION); - return map.stream().collect(Collectors.toMap(StringPair::getKey, StringPair::getValue)); + return map.stream().collect( + Collectors.collectingAndThen( + Collectors.groupingBy(StringPair::getKey, + Collectors.mapping(StringPair::getValue, Collectors.toUnmodifiableList())), + Collections::unmodifiableMap)); } catch (IOException e) { throw new RuntimeException("Could not deserialize json: " + configMap, e); } diff --git a/services/src/main/java/org/keycloak/broker/oidc/mappers/AdvancedClaimToGroupMapper.java b/services/src/main/java/org/keycloak/broker/oidc/mappers/AdvancedClaimToGroupMapper.java index b90f9dfa4a..2c37c25bec 100644 --- a/services/src/main/java/org/keycloak/broker/oidc/mappers/AdvancedClaimToGroupMapper.java +++ b/services/src/main/java/org/keycloak/broker/oidc/mappers/AdvancedClaimToGroupMapper.java @@ -100,15 +100,16 @@ public class AdvancedClaimToGroupMapper extends AbstractClaimToGroupMapper { @Override protected boolean applies(IdentityProviderMapperModel mapperModel, BrokeredIdentityContext context) { - Map claims = mapperModel.getConfigMap(CLAIM_PROPERTY_NAME); + Map> claims = mapperModel.getConfigMap(CLAIM_PROPERTY_NAME); boolean areClaimValuesRegex = Boolean.parseBoolean(mapperModel.getConfig().get(ARE_CLAIM_VALUES_REGEX_PROPERTY_NAME)); - for (Map.Entry claim : claims.entrySet()) { - Object value = getClaimValue(context, claim.getKey()); - - boolean claimValuesMismatch = !(areClaimValuesRegex ? valueMatchesRegex(claim.getValue(), value) : valueEquals(claim.getValue(), value)); - if (claimValuesMismatch) { - return false; + for (Map.Entry> claim : claims.entrySet()) { + Object claimValue = getClaimValue(context, claim.getKey()); + for (String value : claim.getValue()) { + boolean claimValuesMismatch = !(areClaimValuesRegex ? valueMatchesRegex(value, claimValue) : valueEquals(value, claimValue)); + if (claimValuesMismatch) { + return false; + } } } diff --git a/services/src/main/java/org/keycloak/broker/oidc/mappers/AdvancedClaimToRoleMapper.java b/services/src/main/java/org/keycloak/broker/oidc/mappers/AdvancedClaimToRoleMapper.java index 09c93b421c..361a565330 100755 --- a/services/src/main/java/org/keycloak/broker/oidc/mappers/AdvancedClaimToRoleMapper.java +++ b/services/src/main/java/org/keycloak/broker/oidc/mappers/AdvancedClaimToRoleMapper.java @@ -46,7 +46,7 @@ public class AdvancedClaimToRoleMapper extends AbstractClaimToRoleMapper { public static final String[] COMPATIBLE_PROVIDERS = {KeycloakOIDCIdentityProviderFactory.PROVIDER_ID, OIDCIdentityProviderFactory.PROVIDER_ID}; private static final Set IDENTITY_PROVIDER_SYNC_MODES = new HashSet<>(Arrays.asList(IdentityProviderSyncMode.values())); - private static final List configProperties = new ArrayList(); + private static final List configProperties = new ArrayList<>(); static { ProviderConfigProperty claimsProperty = new ProviderConfigProperty(); @@ -108,15 +108,16 @@ public class AdvancedClaimToRoleMapper extends AbstractClaimToRoleMapper { @Override protected boolean applies(IdentityProviderMapperModel mapperModel, BrokeredIdentityContext context) { - Map claims = mapperModel.getConfigMap(CLAIM_PROPERTY_NAME); + Map> claims = mapperModel.getConfigMap(CLAIM_PROPERTY_NAME); boolean areClaimValuesRegex = Boolean.parseBoolean(mapperModel.getConfig().get(ARE_CLAIM_VALUES_REGEX_PROPERTY_NAME)); - for (Map.Entry claim : claims.entrySet()) { - Object value = getClaimValue(context, claim.getKey()); - - boolean claimValuesMismatch = !(areClaimValuesRegex ? valueMatchesRegex(claim.getValue(), value) : valueEquals(claim.getValue(), value)); - if (claimValuesMismatch) { - return false; + for (Map.Entry> claim : claims.entrySet()) { + Object claimValue = getClaimValue(context, claim.getKey()); + for (String value : claim.getValue()) { + boolean claimValuesMismatch = !(areClaimValuesRegex ? valueMatchesRegex(value, claimValue) : valueEquals(value, claimValue)); + if (claimValuesMismatch) { + return false; + } } } diff --git a/services/src/main/java/org/keycloak/broker/oidc/mappers/ClaimToUserSessionNoteMapper.java b/services/src/main/java/org/keycloak/broker/oidc/mappers/ClaimToUserSessionNoteMapper.java index 814d10378b..d75f012c3b 100644 --- a/services/src/main/java/org/keycloak/broker/oidc/mappers/ClaimToUserSessionNoteMapper.java +++ b/services/src/main/java/org/keycloak/broker/oidc/mappers/ClaimToUserSessionNoteMapper.java @@ -104,30 +104,31 @@ public class ClaimToUserSessionNoteMapper extends AbstractClaimMapper { } private void addClaimsToSessionNote(IdentityProviderMapperModel mapperModel, BrokeredIdentityContext context) { - Map claims = mapperModel.getConfigMap(CLAIMS_PROPERTY_NAME); + Map> claims = mapperModel.getConfigMap(CLAIMS_PROPERTY_NAME); boolean areClaimValuesRegex = Boolean.parseBoolean(mapperModel.getConfig().get(ARE_CLAIM_VALUES_REGEX_PROPERTY_NAME)); - for (Map.Entry claim : claims.entrySet()) { - Object valueObj = getClaimValue(context, claim.getKey()); + for (Map.Entry> claim : claims.entrySet()) { + Object claimValueObj = getClaimValue(context, claim.getKey()); + for (String value : claim.getValue()) { + if (claimValueObj != null) { + if (!(claimValueObj instanceof String)) { + LOG.warnf( + "Claim '%s' does not contain a string value for user with brokerUserId '%s'. " + + "Actual value is of type '%s': %s", + claim.getKey(), + context.getBrokerUserId(), claimValueObj.getClass(), claimValueObj); + continue; + } - if (valueObj != null) { - if (!(valueObj instanceof String)) { - LOG.warnf( - "Claim '%s' does not contain a string value for user with brokerUserId '%s'. " + - "Actual value is of type '%s': %s", - claim.getKey(), - context.getBrokerUserId(), valueObj.getClass(), valueObj); - continue; - } + String claimValue = (String) claimValueObj; - String value = (String) valueObj; + boolean claimValuesMatch = areClaimValuesRegex ? valueMatchesRegex(value, claimValue) + : valueEquals(value, claimValue); - boolean claimValuesMatch = areClaimValuesRegex ? valueMatchesRegex(claim.getValue(), value) - : valueEquals(claim.getValue(), value); - - if (claimValuesMatch) { - context.getAuthenticationSession().setUserSessionNote(claim.getKey(), value); + if (claimValuesMatch) { + context.getAuthenticationSession().setUserSessionNote(claim.getKey(), claimValue); + } } } } diff --git a/services/src/main/java/org/keycloak/broker/saml/mappers/AdvancedAttributeToGroupMapper.java b/services/src/main/java/org/keycloak/broker/saml/mappers/AdvancedAttributeToGroupMapper.java index a8e10ab4b2..f75aeacf9e 100644 --- a/services/src/main/java/org/keycloak/broker/saml/mappers/AdvancedAttributeToGroupMapper.java +++ b/services/src/main/java/org/keycloak/broker/saml/mappers/AdvancedAttributeToGroupMapper.java @@ -17,7 +17,6 @@ package org.keycloak.broker.saml.mappers; - import org.keycloak.broker.provider.BrokeredIdentityContext; import org.keycloak.broker.provider.ConfigConstants; import org.keycloak.broker.saml.SAMLEndpoint; @@ -114,8 +113,9 @@ public class AdvancedAttributeToGroupMapper extends AbstractAttributeToGroupMapp return "If all attributes exists, assign the user to the specified group."; } + @Override protected boolean applies(final IdentityProviderMapperModel mapperModel, final BrokeredIdentityContext context) { - Map attributes = mapperModel.getConfigMap(ATTRIBUTE_PROPERTY_NAME); + Map> attributes = mapperModel.getConfigMap(ATTRIBUTE_PROPERTY_NAME); boolean areAttributeValuesRegexes = Boolean.parseBoolean(mapperModel.getConfig().get(ARE_ATTRIBUTE_VALUES_REGEX_PROPERTY_NAME)); AssertionType assertion = (AssertionType) context.getContextData().get(SAMLEndpoint.SAML_ASSERTION); @@ -124,19 +124,21 @@ public class AdvancedAttributeToGroupMapper extends AbstractAttributeToGroupMapp return false; } - for (Map.Entry attribute : attributes.entrySet()) { - String attributeKey = attribute.getKey(); - List attributeValues = attributeAssertions.stream() - .flatMap(statements -> statements.getAttributes().stream()) - .filter(choiceType -> attributeKey.equals(choiceType.getAttribute().getName()) - || attributeKey.equals(choiceType.getAttribute().getFriendlyName())) - // Several statements with same name are treated like one with several values - .flatMap(choiceType -> choiceType.getAttribute().getAttributeValue().stream()) - .collect(Collectors.toList()); + for (Map.Entry> entry : attributes.entrySet()) { + String attributeKey = entry.getKey(); + for (String value : entry.getValue()) { + List attributeValues = attributeAssertions.stream() + .flatMap(statements -> statements.getAttributes().stream()) + .filter(choiceType -> attributeKey.equals(choiceType.getAttribute().getName()) + || attributeKey.equals(choiceType.getAttribute().getFriendlyName())) + // Several statements with same name are treated like one with several values + .flatMap(choiceType -> choiceType.getAttribute().getAttributeValue().stream()) + .collect(Collectors.toList()); - boolean attributeValueMatch = areAttributeValuesRegexes ? valueMatchesRegex(attribute.getValue(), attributeValues) : attributeValues.contains(attribute.getValue()); - if (!attributeValueMatch) { - return false; + boolean attributeValueMatch = areAttributeValuesRegexes ? valueMatchesRegex(value, attributeValues) : attributeValues.contains(value); + if (!attributeValueMatch) { + return false; + } } } diff --git a/services/src/main/java/org/keycloak/broker/saml/mappers/AdvancedAttributeToRoleMapper.java b/services/src/main/java/org/keycloak/broker/saml/mappers/AdvancedAttributeToRoleMapper.java index 2d4d514f75..a5354540ab 100644 --- a/services/src/main/java/org/keycloak/broker/saml/mappers/AdvancedAttributeToRoleMapper.java +++ b/services/src/main/java/org/keycloak/broker/saml/mappers/AdvancedAttributeToRoleMapper.java @@ -17,7 +17,6 @@ package org.keycloak.broker.saml.mappers; - import org.keycloak.broker.provider.BrokeredIdentityContext; import org.keycloak.broker.provider.ConfigConstants; import org.keycloak.broker.saml.SAMLEndpoint; @@ -122,8 +121,9 @@ public class AdvancedAttributeToRoleMapper extends AbstractAttributeToRoleMapper return "If the set of attributes exists and can be matched, grant the user the specified realm or client role."; } + @Override protected boolean applies(final IdentityProviderMapperModel mapperModel, final BrokeredIdentityContext context) { - Map attributes = mapperModel.getConfigMap(ATTRIBUTE_PROPERTY_NAME); + Map> attributes = mapperModel.getConfigMap(ATTRIBUTE_PROPERTY_NAME); boolean areAttributeValuesRegexes = Boolean.parseBoolean(mapperModel.getConfig().get(ARE_ATTRIBUTE_VALUES_REGEX_PROPERTY_NAME)); AssertionType assertion = (AssertionType) context.getContextData().get(SAMLEndpoint.SAML_ASSERTION); @@ -132,19 +132,21 @@ public class AdvancedAttributeToRoleMapper extends AbstractAttributeToRoleMapper return false; } - for (Map.Entry attribute : attributes.entrySet()) { - String attributeKey = attribute.getKey(); - List attributeValues = attributeAssertions.stream() - .flatMap(statements -> statements.getAttributes().stream()) - .filter(choiceType -> attributeKey.equals(choiceType.getAttribute().getName()) - || attributeKey.equals(choiceType.getAttribute().getFriendlyName())) - // Several statements with same name are treated like one with several values - .flatMap(choiceType -> choiceType.getAttribute().getAttributeValue().stream()) - .collect(Collectors.toList()); + for (Map.Entry> entry : attributes.entrySet()) { + String attributeKey = entry.getKey(); + for (String value : entry.getValue()) { + List attributeValues = attributeAssertions.stream() + .flatMap(statements -> statements.getAttributes().stream()) + .filter(choiceType -> attributeKey.equals(choiceType.getAttribute().getName()) + || attributeKey.equals(choiceType.getAttribute().getFriendlyName())) + // Several statements with same name are treated like one with several values + .flatMap(choiceType -> choiceType.getAttribute().getAttributeValue().stream()) + .collect(Collectors.toList()); - boolean attributeValueMatch = areAttributeValuesRegexes ? valueMatchesRegex(attribute.getValue(), attributeValues) : attributeValues.contains(attribute.getValue()); - if (!attributeValueMatch) { - return false; + boolean attributeValueMatch = areAttributeValuesRegexes ? valueMatchesRegex(value, attributeValues) : attributeValues.contains(value); + if (!attributeValueMatch) { + return false; + } } } diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/broker/AbstractAdvancedRoleMapperTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/broker/AbstractAdvancedRoleMapperTest.java index 879a31319e..531bc3f173 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/broker/AbstractAdvancedRoleMapperTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/broker/AbstractAdvancedRoleMapperTest.java @@ -27,6 +27,10 @@ public abstract class AbstractAdvancedRoleMapperTest extends AbstractRoleMapperT " \"value\": \"value 1\"\n" + " },\n" + " {\n" + + " \"key\": \"" + KcOidcBrokerConfiguration.ATTRIBUTE_TO_MAP_NAME + "\",\n" + + " \"value\": \"value 2\"\n" + + " },\n" + + " {\n" + " \"key\": \"" + KcOidcBrokerConfiguration.ATTRIBUTE_TO_MAP_NAME_2 + "\",\n" + " \"value\": \"value 2\"\n" + " }\n" + @@ -152,7 +156,7 @@ public abstract class AbstractAdvancedRoleMapperTest extends AbstractRoleMapperT UserRepresentation user = findUser(bc.providerRealmName(), bc.getUserLogin(), bc.getUserEmail()); ImmutableMap> matchingAttributes = ImmutableMap.> builder() .put(KcOidcBrokerConfiguration.ATTRIBUTE_TO_MAP_NAME, - ImmutableList. builder().add("value 1").build()) + ImmutableList. builder().add("value 1").add("value 2").build()) .put(KcOidcBrokerConfiguration.ATTRIBUTE_TO_MAP_NAME_2, ImmutableList. builder().add(newValueForAttribute2).build()) .put("some.other.attribute", ImmutableList. builder().add("some value").build()) @@ -174,7 +178,7 @@ public abstract class AbstractAdvancedRoleMapperTest extends AbstractRoleMapperT private static Map> createMatchingUserConfig() { return ImmutableMap.> builder() .put(KcOidcBrokerConfiguration.ATTRIBUTE_TO_MAP_NAME, - ImmutableList. builder().add("value 1").build()) + ImmutableList. builder().add("value 1").add("value 2").build()) .put(KcOidcBrokerConfiguration.ATTRIBUTE_TO_MAP_NAME_2, ImmutableList. builder().add("value 2").build()) .build(); diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/broker/AbstractGroupBrokerMapperTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/broker/AbstractGroupBrokerMapperTest.java index 525642e9ef..d82bfd9dc8 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/broker/AbstractGroupBrokerMapperTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/broker/AbstractGroupBrokerMapperTest.java @@ -36,6 +36,10 @@ public abstract class AbstractGroupBrokerMapperTest extends AbstractGroupMapperT " \"value\": \"value 1\"\n" + " },\n" + " {\n" + + " \"key\": \"" + KcOidcBrokerConfiguration.ATTRIBUTE_TO_MAP_NAME + "\",\n" + + " \"value\": \"value 2\"\n" + + " },\n" + + " {\n" + " \"key\": \"" + KcOidcBrokerConfiguration.ATTRIBUTE_TO_MAP_NAME_2 + "\",\n" + " \"value\": \"value 2\"\n" + " }\n" + @@ -69,7 +73,7 @@ public abstract class AbstractGroupBrokerMapperTest extends AbstractGroupMapperT protected void updateUser() { UserRepresentation user = findUser(bc.providerRealmName(), bc.getUserLogin(), bc.getUserEmail()); ImmutableMap> matchingAttributes = ImmutableMap.>builder() - .put(KcOidcBrokerConfiguration.ATTRIBUTE_TO_MAP_NAME, ImmutableList.builder().add("value 1").build()) + .put(KcOidcBrokerConfiguration.ATTRIBUTE_TO_MAP_NAME, ImmutableList.builder().add("value 1").add("value 2").build()) .put(KcOidcBrokerConfiguration.ATTRIBUTE_TO_MAP_NAME_2, ImmutableList.builder().add(newValueForAttribute2).build()) .put("some.other.attribute", ImmutableList.builder().add("some value").build()) .build(); @@ -112,7 +116,7 @@ public abstract class AbstractGroupBrokerMapperTest extends AbstractGroupMapperT protected static Map> createMatchingAttributes() { return ImmutableMap.> builder() .put(KcOidcBrokerConfiguration.ATTRIBUTE_TO_MAP_NAME, - ImmutableList. builder().add("value 1").build()) + ImmutableList. builder().add("value 1").add("value 2").build()) .put(KcOidcBrokerConfiguration.ATTRIBUTE_TO_MAP_NAME_2, ImmutableList. builder().add("value 2").build()) .build(); diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/broker/KcSamlAdvancedAttributeToGroupMapperTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/broker/KcSamlAdvancedAttributeToGroupMapperTest.java index 1de261214a..fdde47115d 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/broker/KcSamlAdvancedAttributeToGroupMapperTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/broker/KcSamlAdvancedAttributeToGroupMapperTest.java @@ -28,6 +28,9 @@ public class KcSamlAdvancedAttributeToGroupMapperTest extends AbstractGroupBroke " {\n" + " \"key\": \"" + ATTRIBUTE_TO_MAP_FRIENDLY_NAME + "\",\n" + " \"value\": \"value 1\"\n" + + " },\n" +" {\n" + + " \"key\": \"" + ATTRIBUTE_TO_MAP_FRIENDLY_NAME + "\",\n" + + " \"value\": \"value 2\"\n" + " },\n" + " {\n" + " \"key\": \"" + KcOidcBrokerConfiguration.ATTRIBUTE_TO_MAP_NAME_2 + "\",\n" + @@ -65,7 +68,7 @@ public class KcSamlAdvancedAttributeToGroupMapperTest extends AbstractGroupBroke public void attributeFriendlyNameGetsConsideredAndMatchedToGroup() { createAdvancedGroupMapper(ATTRIBUTES, false,KcOidcBrokerConfiguration.ATTRIBUTE_TO_MAP_NAME_2); createUserInProviderRealm(ImmutableMap.> builder() - .put(ATTRIBUTE_TO_MAP_FRIENDLY_NAME, ImmutableList. builder().add("value 1").build()) + .put(ATTRIBUTE_TO_MAP_FRIENDLY_NAME, ImmutableList. builder().add("value 1").add("value 2").build()) .put(KcOidcBrokerConfiguration.ATTRIBUTE_TO_MAP_NAME_2, ImmutableList. builder().add("value 2").build()) .build()); diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/broker/KcSamlAdvancedAttributeToRoleMapperTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/broker/KcSamlAdvancedAttributeToRoleMapperTest.java index d0ca3e5254..1713410446 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/broker/KcSamlAdvancedAttributeToRoleMapperTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/broker/KcSamlAdvancedAttributeToRoleMapperTest.java @@ -26,6 +26,10 @@ public class KcSamlAdvancedAttributeToRoleMapperTest extends AbstractAdvancedRol " \"value\": \"value 1\"\n" + " },\n" + " {\n" + + " \"key\": \"" + ATTRIBUTE_TO_MAP_FRIENDLY_NAME + "\",\n" + + " \"value\": \"value 2\"\n" + + " },\n" + + " {\n" + " \"key\": \"" + KcOidcBrokerConfiguration.ATTRIBUTE_TO_MAP_NAME_2 + "\",\n" + " \"value\": \"value 2\"\n" + " }\n" + @@ -58,7 +62,7 @@ public class KcSamlAdvancedAttributeToRoleMapperTest extends AbstractAdvancedRol public void attributeFriendlyNameGetsConsideredAndMatchedToRole() { createAdvancedRoleMapper(ATTRIBUTES, false); createUserInProviderRealm(ImmutableMap.> builder() - .put(ATTRIBUTE_TO_MAP_FRIENDLY_NAME, ImmutableList. builder().add("value 1").build()) + .put(ATTRIBUTE_TO_MAP_FRIENDLY_NAME, ImmutableList. builder().add("value 1").add("value 2").build()) .put(KcOidcBrokerConfiguration.ATTRIBUTE_TO_MAP_NAME_2, ImmutableList. builder().add("value 2").build()) .build()); diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/broker/OidcClaimToUserSessionNoteMapperTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/broker/OidcClaimToUserSessionNoteMapperTest.java index 7adbea3eb6..9440b8976d 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/broker/OidcClaimToUserSessionNoteMapperTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/broker/OidcClaimToUserSessionNoteMapperTest.java @@ -123,7 +123,7 @@ public class OidcClaimToUserSessionNoteMapperTest extends AbstractIdentityProvid @Test public void claimIsNotPropagatedWhenNameDoesNotMatch() { - createUserSessionNoteIdpMapper(IdentityProviderMapperSyncMode.IMPORT, "something-unexpected"); + createUserSessionNoteIdpMapper(IdentityProviderMapperSyncMode.IMPORT, "something-unexpected-1", "something-unexpected-2"); AccessToken accessToken = login(); @@ -157,7 +157,7 @@ public class OidcClaimToUserSessionNoteMapperTest extends AbstractIdentityProvid } private IdentityProviderMapperRepresentation createUserSessionNoteIdpMapper(IdentityProviderMapperSyncMode syncMode, - String matchingValue) { + String... matchingValue) { IdentityProviderMapperRepresentation mapper = new IdentityProviderMapperRepresentation(); mapper.setName("User Session Note Idp Mapper"); mapper.setIdentityProviderMapper(ClaimToUserSessionNoteMapper.PROVIDER_ID); @@ -170,8 +170,17 @@ public class OidcClaimToUserSessionNoteMapperTest extends AbstractIdentityProvid return persistMapper(mapper); } - private String createClaimsConfig(String matchingValue) { - return "[{\"key\":\"" + CLAIM_NAME + "\",\"value\":\"" + matchingValue + "\"}]"; + private String createClaimsConfig(String... matchingValue) { + StringBuilder sb = new StringBuilder(); + sb.append("["); + if (matchingValue != null) { + for (String value : matchingValue) { + sb.append("{\"key\":\"").append(CLAIM_NAME).append("\",\"value\":\"").append(value).append("\"},"); + } + sb.setLength(sb.length() - 1); + } + sb.append("]"); + return sb.toString(); } private void updateProviderHardcodedClaimMapper(String value) {