diff --git a/services/src/main/java/org/keycloak/protocol/saml/EntityDescriptorDescriptionConverter.java b/services/src/main/java/org/keycloak/protocol/saml/EntityDescriptorDescriptionConverter.java index 7db9f2e3d4..c1dd4e8ca5 100755 --- a/services/src/main/java/org/keycloak/protocol/saml/EntityDescriptorDescriptionConverter.java +++ b/services/src/main/java/org/keycloak/protocol/saml/EntityDescriptorDescriptionConverter.java @@ -31,7 +31,10 @@ import org.keycloak.exportimport.ClientDescriptionConverterFactory; import org.keycloak.models.KeycloakSession; import org.keycloak.models.KeycloakSessionFactory; import org.keycloak.models.utils.KeycloakModelUtils; +import org.keycloak.protocol.saml.mappers.AttributeStatementHelper; +import org.keycloak.protocol.saml.mappers.UserAttributeStatementMapper; import org.keycloak.representations.idm.ClientRepresentation; +import org.keycloak.representations.idm.ProtocolMapperRepresentation; import org.keycloak.saml.SignatureAlgorithm; import org.keycloak.saml.common.constants.JBossSAMLURIConstants; import org.keycloak.saml.common.exceptions.ConfigurationException; @@ -48,6 +51,7 @@ import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Objects; +import java.util.stream.Collectors; /** * @author Bill Burke @@ -177,6 +181,22 @@ public class EntityDescriptorDescriptionConverter implements ClientDescriptionCo } } } + + app.setProtocolMappers(spDescriptorType.getAttributeConsumingService().stream().flatMap(att -> att.getRequestedAttribute().stream()) + .map(attr -> { + ProtocolMapperRepresentation mapper = new ProtocolMapperRepresentation(); + mapper.setName(attr.getName()); + mapper.setProtocol("saml"); + mapper.setProtocolMapper(UserAttributeStatementMapper.PROVIDER_ID); + Map config = new HashMap<>(); + config.put(AttributeStatementHelper.SAML_ATTRIBUTE_NAME, attr.getName()); + if (attr.getFriendlyName() != null) + config.put(AttributeStatementHelper.FRIENDLY_NAME, attr.getFriendlyName()); + if (attr.getNameFormat() != null) + config.put(AttributeStatementHelper.SAML_ATTRIBUTE_NAMEFORMAT, getSAMLNameFormat(attr.getNameFormat())); + mapper.setConfig(config); + return mapper; + }).collect(Collectors.toList())); for (KeyDescriptorType keyDescriptor : spDescriptorType.getKeyDescriptor()) { X509Certificate cert = null; @@ -199,6 +219,20 @@ public class EntityDescriptorDescriptionConverter implements ClientDescriptionCo return app; } + + private static String getSAMLNameFormat(String xmlValue) { + String value =null; + if (JBossSAMLURIConstants.ATTRIBUTE_FORMAT_URI.getUri().toString().equals(xmlValue)) { + value = AttributeStatementHelper.URI_REFERENCE; + } else if (JBossSAMLURIConstants.ATTRIBUTE_FORMAT_BASIC.getUri().toString().equals(xmlValue)) { + value = AttributeStatementHelper.BASIC; + } else if (JBossSAMLURIConstants.ATTRIBUTE_FORMAT_UNSPECIFIED.getUri().toString().equals(xmlValue)) { + value = AttributeStatementHelper.UNSPECIFIED; + } + + return value; + + } private static String getLogoutLocation(SPSSODescriptorType idp, String bindingURI) { String logoutResponseLocation = null; diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/client/SAMLClientRegistrationTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/client/SAMLClientRegistrationTest.java index e76425883e..947a3b1604 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/client/SAMLClientRegistrationTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/client/SAMLClientRegistrationTest.java @@ -25,11 +25,14 @@ import org.keycloak.client.registration.Auth; import org.keycloak.client.registration.ClientRegistrationException; import org.keycloak.client.registration.HttpErrorException; import org.keycloak.events.Errors; +import org.keycloak.protocol.saml.mappers.AttributeStatementHelper; import org.keycloak.representations.idm.ClientInitialAccessCreatePresentation; import org.keycloak.representations.idm.ClientInitialAccessPresentation; import org.keycloak.representations.idm.ClientRepresentation; +import org.keycloak.representations.idm.ProtocolMapperRepresentation; import org.keycloak.representations.idm.RealmRepresentation; import org.keycloak.representations.idm.RoleRepresentation; +import org.keycloak.saml.common.constants.JBossSAMLURIConstants; import org.keycloak.testsuite.Assert; import org.keycloak.testsuite.util.KeycloakModelUtils; @@ -81,6 +84,14 @@ public class SAMLClientRegistrationTest extends AbstractClientRegistrationTest { )); // No redirect URI for ARTIFACT binding which is unsupported assertThat(response.getAttributes().get("saml_single_logout_service_url_redirect"), is("https://LoadBalancer-9.siroe.com:3443/federation/SPSloRedirect/metaAlias/sp")); + + Assert.assertNotNull(response.getProtocolMappers()); + Assert.assertEquals(1,response.getProtocolMappers().size()); + ProtocolMapperRepresentation mapper = response.getProtocolMappers().get(0); + Assert.assertEquals("saml-user-attribute-mapper",mapper.getProtocolMapper()); + Assert.assertEquals("urn:oid:2.5.4.42",mapper.getConfig().get(AttributeStatementHelper.SAML_ATTRIBUTE_NAME)); + Assert.assertEquals("givenName",mapper.getConfig().get(AttributeStatementHelper.FRIENDLY_NAME)); + Assert.assertEquals(AttributeStatementHelper.URI_REFERENCE,mapper.getConfig().get(AttributeStatementHelper.SAML_ATTRIBUTE_NAMEFORMAT)); } @Test diff --git a/testsuite/integration-arquillian/tests/base/src/test/resources/clientreg-test/saml-entity-descriptor.xml b/testsuite/integration-arquillian/tests/base/src/test/resources/clientreg-test/saml-entity-descriptor.xml index 694bb82281..753444459e 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/resources/clientreg-test/saml-entity-descriptor.xml +++ b/testsuite/integration-arquillian/tests/base/src/test/resources/clientreg-test/saml-entity-descriptor.xml @@ -107,5 +107,8 @@ x5Ql0ejivIJAYcMGUyA+/YwJg2FGoA== index="4" Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect" Location="https://LoadBalancer-9.siroe.com:3443/federation/Consumer/metaAlias/sp/redirect"/> + + +