use of org.keycloak.dom.saml.v2.metadata.EntityDescriptorType in project keycloak by keycloak.
the class FixedHostnameTest method assertSamlIdPDescriptor.
private void assertSamlIdPDescriptor(String realm, String expectedBaseUrl) throws Exception {
final String realmUrl = expectedBaseUrl + "/auth/realms/" + realm;
final String baseSamlEndpointUrl = realmUrl + "/protocol/saml";
String entityDescriptor = null;
try (CloseableHttpClient client = HttpClientBuilder.create().build();
CloseableHttpResponse resp = client.execute(new HttpGet(baseSamlEndpointUrl + "/descriptor"))) {
entityDescriptor = EntityUtils.toString(resp.getEntity(), GeneralConstants.SAML_CHARSET);
Object metadataO = SAMLParser.getInstance().parse(new ByteArrayInputStream(entityDescriptor.getBytes(GeneralConstants.SAML_CHARSET)));
assertThat(metadataO, instanceOf(EntityDescriptorType.class));
EntityDescriptorType ed = (EntityDescriptorType) metadataO;
assertThat(ed.getEntityID(), is(realmUrl));
IDPSSODescriptorType idpDescriptor = ed.getChoiceType().get(0).getDescriptors().get(0).getIdpDescriptor();
assertThat(idpDescriptor, notNullValue());
final List<String> locations = idpDescriptor.getSingleSignOnService().stream().map(EndpointType::getLocation).map(URI::toString).collect(Collectors.toList());
assertThat(locations, Matchers.everyItem(is(baseSamlEndpointUrl)));
} catch (Exception e) {
log.errorf("Caught exception while parsing SAML descriptor %s", entityDescriptor);
}
}
use of org.keycloak.dom.saml.v2.metadata.EntityDescriptorType in project keycloak by keycloak.
the class SAMLIdentityProvider method export.
@Override
public Response export(UriInfo uriInfo, RealmModel realm, String format) {
try {
URI authnBinding = JBossSAMLURIConstants.SAML_HTTP_REDIRECT_BINDING.getUri();
if (getConfig().isPostBindingAuthnRequest()) {
authnBinding = JBossSAMLURIConstants.SAML_HTTP_POST_BINDING.getUri();
}
URI endpoint = uriInfo.getBaseUriBuilder().path("realms").path(realm.getName()).path("broker").path(getConfig().getAlias()).path("endpoint").build();
boolean wantAuthnRequestsSigned = getConfig().isWantAuthnRequestsSigned();
boolean wantAssertionsSigned = getConfig().isWantAssertionsSigned();
boolean wantAssertionsEncrypted = getConfig().isWantAssertionsEncrypted();
String entityId = getEntityId(uriInfo, realm);
String nameIDPolicyFormat = getConfig().getNameIDPolicyFormat();
List<Element> signingKeys = new LinkedList<>();
List<Element> encryptionKeys = new LinkedList<>();
session.keys().getKeysStream(realm, KeyUse.SIG, Algorithm.RS256).filter(Objects::nonNull).filter(key -> key.getCertificate() != null).sorted(SamlService::compareKeys).forEach(key -> {
try {
Element element = SPMetadataDescriptor.buildKeyInfoElement(key.getKid(), PemUtils.encodeCertificate(key.getCertificate()));
signingKeys.add(element);
if (key.getStatus() == KeyStatus.ACTIVE) {
encryptionKeys.add(element);
}
} catch (ParserConfigurationException e) {
logger.warn("Failed to export SAML SP Metadata!", e);
throw new RuntimeException(e);
}
});
// Prepare the metadata descriptor model
StringWriter sw = new StringWriter();
XMLStreamWriter writer = StaxUtil.getXMLStreamWriter(sw);
SAMLMetadataWriter metadataWriter = new SAMLMetadataWriter(writer);
EntityDescriptorType entityDescriptor = SPMetadataDescriptor.buildSPdescriptor(authnBinding, authnBinding, endpoint, endpoint, wantAuthnRequestsSigned, wantAssertionsSigned, wantAssertionsEncrypted, entityId, nameIDPolicyFormat, signingKeys, encryptionKeys);
// Create the AttributeConsumingService if at least one attribute importer mapper exists
List<Entry<IdentityProviderMapperModel, SamlMetadataDescriptorUpdater>> metadataAttrProviders = new ArrayList<>();
realm.getIdentityProviderMappersByAliasStream(getConfig().getAlias()).forEach(mapper -> {
IdentityProviderMapper target = (IdentityProviderMapper) session.getKeycloakSessionFactory().getProviderFactory(IdentityProviderMapper.class, mapper.getIdentityProviderMapper());
if (target instanceof SamlMetadataDescriptorUpdater)
metadataAttrProviders.add(new java.util.AbstractMap.SimpleEntry<>(mapper, (SamlMetadataDescriptorUpdater) target));
});
if (!metadataAttrProviders.isEmpty()) {
int attributeConsumingServiceIndex = getConfig().getAttributeConsumingServiceIndex() != null ? getConfig().getAttributeConsumingServiceIndex() : 1;
String attributeConsumingServiceName = getConfig().getAttributeConsumingServiceName();
// default value for attributeConsumingServiceName
if (attributeConsumingServiceName == null)
attributeConsumingServiceName = realm.getDisplayName() != null ? realm.getDisplayName() : realm.getName();
AttributeConsumingServiceType attributeConsumingService = new AttributeConsumingServiceType(attributeConsumingServiceIndex);
attributeConsumingService.setIsDefault(true);
String currentLocale = realm.getDefaultLocale() == null ? "en" : realm.getDefaultLocale();
LocalizedNameType attributeConsumingServiceNameElement = new LocalizedNameType(currentLocale);
attributeConsumingServiceNameElement.setValue(attributeConsumingServiceName);
attributeConsumingService.addServiceName(attributeConsumingServiceNameElement);
// Look for the SP descriptor and add the attribute consuming service
for (EntityDescriptorType.EDTChoiceType choiceType : entityDescriptor.getChoiceType()) {
List<EntityDescriptorType.EDTDescriptorChoiceType> descriptors = choiceType.getDescriptors();
for (EntityDescriptorType.EDTDescriptorChoiceType descriptor : descriptors) {
descriptor.getSpDescriptor().addAttributeConsumerService(attributeConsumingService);
}
}
// Add the attribute mappers
metadataAttrProviders.forEach(mapper -> {
SamlMetadataDescriptorUpdater metadataAttrProvider = mapper.getValue();
metadataAttrProvider.updateMetadata(mapper.getKey(), entityDescriptor);
});
}
// Write the metadata and export it to a string
metadataWriter.writeEntityDescriptor(entityDescriptor);
String descriptor = sw.toString();
// Metadata signing
if (getConfig().isSignSpMetadata()) {
KeyManager.ActiveRsaKey activeKey = session.keys().getActiveRsaKey(realm);
String keyName = getConfig().getXmlSigKeyInfoKeyNameTransformer().getKeyName(activeKey.getKid(), activeKey.getCertificate());
KeyPair keyPair = new KeyPair(activeKey.getPublicKey(), activeKey.getPrivateKey());
Document metadataDocument = DocumentUtil.getDocument(descriptor);
SAML2Signature signatureHelper = new SAML2Signature();
signatureHelper.setSignatureMethod(getSignatureAlgorithm().getXmlSignatureMethod());
signatureHelper.setDigestMethod(getSignatureAlgorithm().getXmlSignatureDigestMethod());
Node nextSibling = metadataDocument.getDocumentElement().getFirstChild();
signatureHelper.setNextSibling(nextSibling);
signatureHelper.signSAMLDocument(metadataDocument, keyName, keyPair, CanonicalizationMethod.EXCLUSIVE);
descriptor = DocumentUtil.getDocumentAsString(metadataDocument);
}
return Response.ok(descriptor, MediaType.APPLICATION_XML_TYPE).build();
} catch (Exception e) {
logger.warn("Failed to export SAML SP Metadata!", e);
throw new RuntimeException(e);
}
}
use of org.keycloak.dom.saml.v2.metadata.EntityDescriptorType in project keycloak by keycloak.
the class SPMetadataDescriptor method buildSPdescriptor.
public static EntityDescriptorType buildSPdescriptor(URI loginBinding, URI logoutBinding, URI assertionEndpoint, URI logoutEndpoint, boolean wantAuthnRequestsSigned, boolean wantAssertionsSigned, boolean wantAssertionsEncrypted, String entityId, String nameIDPolicyFormat, List<Element> signingCerts, List<Element> encryptionCerts) {
EntityDescriptorType entityDescriptor = new EntityDescriptorType(entityId);
entityDescriptor.setID(IDGenerator.create("ID_"));
SPSSODescriptorType spSSODescriptor = new SPSSODescriptorType(Arrays.asList(PROTOCOL_NSURI.get()));
spSSODescriptor.setAuthnRequestsSigned(wantAuthnRequestsSigned);
spSSODescriptor.setWantAssertionsSigned(wantAssertionsSigned);
spSSODescriptor.addNameIDFormat(nameIDPolicyFormat);
spSSODescriptor.addSingleLogoutService(new EndpointType(logoutBinding, logoutEndpoint));
if (wantAuthnRequestsSigned && signingCerts != null) {
for (Element key : signingCerts) {
KeyDescriptorType keyDescriptor = new KeyDescriptorType();
keyDescriptor.setUse(KeyTypes.SIGNING);
keyDescriptor.setKeyInfo(key);
spSSODescriptor.addKeyDescriptor(keyDescriptor);
}
}
if (wantAssertionsEncrypted && encryptionCerts != null) {
for (Element key : encryptionCerts) {
KeyDescriptorType keyDescriptor = new KeyDescriptorType();
keyDescriptor.setUse(KeyTypes.ENCRYPTION);
keyDescriptor.setKeyInfo(key);
spSSODescriptor.addKeyDescriptor(keyDescriptor);
}
}
IndexedEndpointType assertionConsumerEndpoint = new IndexedEndpointType(loginBinding, assertionEndpoint);
assertionConsumerEndpoint.setIsDefault(true);
assertionConsumerEndpoint.setIndex(1);
spSSODescriptor.addAssertionConsumerService(assertionConsumerEndpoint);
entityDescriptor.addChoiceType(new EntityDescriptorType.EDTChoiceType(Arrays.asList(new EntityDescriptorType.EDTDescriptorChoiceType(spSSODescriptor))));
return entityDescriptor;
}
use of org.keycloak.dom.saml.v2.metadata.EntityDescriptorType in project keycloak by keycloak.
the class SAMLParserTest method testSaml20MetadataEntityDescriptorIdP.
@Test
public void testSaml20MetadataEntityDescriptorIdP() throws Exception {
EntityDescriptorType entityDescriptor = assertParsed("saml20-entity-descriptor-idp.xml", EntityDescriptorType.class);
List<EntityDescriptorType.EDTChoiceType> descriptors = entityDescriptor.getChoiceType();
assertThat(descriptors, hasSize(2));
// IDPSSO descriptor
IDPSSODescriptorType idpDescriptor = descriptors.get(0).getDescriptors().get(0).getIdpDescriptor();
assertThat(idpDescriptor, is(notNullValue()));
assertThat(idpDescriptor.isWantAuthnRequestsSigned(), is(true));
assertThat(idpDescriptor.getProtocolSupportEnumeration(), contains("urn:oasis:names:tc:SAML:2.0:protocol"));
// Key descriptor
List<KeyDescriptorType> keyDescriptors = idpDescriptor.getKeyDescriptor();
assertThat(keyDescriptors, hasSize(1));
KeyDescriptorType signingKey = keyDescriptors.get(0);
assertThat(signingKey.getUse(), is(KeyTypes.SIGNING));
assertThat(signingKey.getEncryptionMethod(), is(emptyCollectionOf(EncryptionMethodType.class)));
assertThat(signingKey.getKeyInfo().getElementsByTagName("ds:KeyName").item(0).getTextContent(), is("IdentityProvider.com SSO Key"));
// Single logout services
assertThat(idpDescriptor.getSingleLogoutService(), hasSize(2));
EndpointType singleLS1 = idpDescriptor.getSingleLogoutService().get(0);
assertThat(singleLS1.getBinding(), is(URI.create("urn:oasis:names:tc:SAML:2.0:bindings:SOAP")));
assertThat(singleLS1.getLocation(), is(URI.create("https://IdentityProvider.com/SAML/SLO/SOAP")));
assertThat(singleLS1.getResponseLocation(), is(nullValue()));
assertThat(singleLS1.getAny(), is(emptyCollectionOf(Object.class)));
assertThat(singleLS1.getOtherAttributes(), is(Collections.<QName, String>emptyMap()));
EndpointType singleLS2 = idpDescriptor.getSingleLogoutService().get(1);
assertThat(singleLS2.getBinding(), is(URI.create("urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect")));
assertThat(singleLS2.getLocation(), is(URI.create("https://IdentityProvider.com/SAML/SLO/Browser")));
assertThat(singleLS2.getResponseLocation(), is(URI.create("https://IdentityProvider.com/SAML/SLO/Response")));
assertThat(singleLS2.getAny(), is(emptyCollectionOf(Object.class)));
assertThat(singleLS2.getOtherAttributes(), is(Collections.<QName, String>emptyMap()));
// NameID
assertThat(idpDescriptor.getNameIDFormat(), containsInAnyOrder("urn:oasis:names:tc:SAML:1.1:nameid-format:X509SubjectName", "urn:oasis:names:tc:SAML:2.0:nameid-format:persistent", "urn:oasis:names:tc:SAML:2.0:nameid-format:transient"));
// Single sign on services
assertThat(idpDescriptor.getSingleSignOnService(), hasSize(2));
EndpointType singleSO1 = idpDescriptor.getSingleSignOnService().get(0);
assertThat(singleSO1.getBinding(), is(URI.create("urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect")));
assertThat(singleSO1.getLocation(), is(URI.create("https://IdentityProvider.com/SAML/SSO/Browser")));
assertThat(singleSO1.getResponseLocation(), is(nullValue()));
assertThat(singleSO1.getAny(), is(emptyCollectionOf(Object.class)));
assertThat(singleSO1.getOtherAttributes(), is(Collections.<QName, String>emptyMap()));
EndpointType singleSO2 = idpDescriptor.getSingleSignOnService().get(1);
assertThat(singleSO2.getBinding(), is(URI.create("urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST")));
assertThat(singleSO2.getLocation(), is(URI.create("https://IdentityProvider.com/SAML/SSO/Browser")));
assertThat(singleSO2.getResponseLocation(), is(nullValue()));
assertThat(singleSO2.getAny(), is(emptyCollectionOf(Object.class)));
assertThat(singleSO2.getOtherAttributes(), is(Collections.<QName, String>emptyMap()));
// Attributes
assertThat(idpDescriptor.getAttribute(), hasSize(2));
AttributeType attr1 = idpDescriptor.getAttribute().get(0);
assertThat(attr1.getNameFormat(), is("urn:oasis:names:tc:SAML:2.0:attrname-format:uri"));
assertThat(attr1.getName(), is("urn:oid:1.3.6.1.4.1.5923.1.1.1.6"));
assertThat(attr1.getFriendlyName(), is("eduPersonPrincipalName"));
assertThat(attr1.getOtherAttributes(), is(Collections.<QName, String>emptyMap()));
assertThat(attr1.getAttributeValue(), is(emptyCollectionOf(Object.class)));
AttributeType attr2 = idpDescriptor.getAttribute().get(1);
assertThat(attr2.getNameFormat(), is("urn:oasis:names:tc:SAML:2.0:attrname-format:uri"));
assertThat(attr2.getName(), is("urn:oid:1.3.6.1.4.1.5923.1.1.1.1"));
assertThat(attr2.getFriendlyName(), is("eduPersonAffiliation"));
assertThat(attr2.getOtherAttributes(), is(Collections.<QName, String>emptyMap()));
assertThat(attr2.getAttributeValue(), containsInAnyOrder((Object) "member", "student", "faculty", "employee", "staff"));
// Organization
assertThat(entityDescriptor.getOrganization().getOrganizationName(), hasSize(1));
LocalizedNameType orgName = entityDescriptor.getOrganization().getOrganizationName().get(0);
assertThat(orgName.getLang(), is("en"));
assertThat(orgName.getValue(), is("Identity Providers R\n US"));
assertThat(entityDescriptor.getOrganization().getOrganizationDisplayName(), hasSize(1));
LocalizedNameType orgDispName = entityDescriptor.getOrganization().getOrganizationDisplayName().get(0);
assertThat(orgDispName.getLang(), is("en"));
assertThat(orgDispName.getValue(), is("Identity Providers R US, a Division of Lerxst Corp."));
assertThat(entityDescriptor.getOrganization().getOrganizationURL(), hasSize(1));
LocalizedURIType orgURL = entityDescriptor.getOrganization().getOrganizationURL().get(0);
assertThat(orgURL.getLang(), is("en"));
assertThat(orgURL.getValue(), is(URI.create("https://IdentityProvider.com")));
}
use of org.keycloak.dom.saml.v2.metadata.EntityDescriptorType in project keycloak by keycloak.
the class SAMLMetadataWriter method writeEntitiesDescriptor.
public void writeEntitiesDescriptor(EntitiesDescriptorType entities) throws ProcessingException {
StaxUtil.writeStartElement(writer, METADATA_PREFIX, JBossSAMLConstants.ENTITIES_DESCRIPTOR.get(), JBossSAMLURIConstants.METADATA_NSURI.get());
StaxUtil.writeDefaultNameSpace(writer, JBossSAMLURIConstants.METADATA_NSURI.get());
StaxUtil.writeNameSpace(writer, "md", JBossSAMLURIConstants.METADATA_NSURI.get());
StaxUtil.writeNameSpace(writer, "saml", JBossSAMLURIConstants.ASSERTION_NSURI.get());
StaxUtil.writeNameSpace(writer, "ds", JBossSAMLURIConstants.XMLDSIG_NSURI.get());
if (entities.getValidUntil() != null) {
StaxUtil.writeAttribute(writer, JBossSAMLConstants.VALID_UNTIL.get(), entities.getValidUntil().toString());
}
if (entities.getID() != null) {
StaxUtil.writeAttribute(writer, JBossSAMLConstants.ID.get(), entities.getID());
}
if (entities.getName() != null) {
StaxUtil.writeAttribute(writer, JBossSAMLConstants.NAME.get(), entities.getName());
}
Element signature = entities.getSignature();
if (signature != null) {
StaxUtil.writeDOMElement(writer, signature);
}
ExtensionsType extensions = entities.getExtensions();
if (extensions != null) {
write(extensions);
}
List<Object> entityDescriptors = entities.getEntityDescriptor();
for (Object ed : entityDescriptors) {
if (ed instanceof EntityDescriptorType) {
writeEntityDescriptor((EntityDescriptorType) ed);
} else
writeEntitiesDescriptor((EntitiesDescriptorType) ed);
}
StaxUtil.writeEndElement(writer);
StaxUtil.flush(writer);
}
Aggregations