use of org.keycloak.saml.processing.core.saml.v2.writers.SAMLMetadataWriter in project keycloak by keycloak.
the class SamlSPDescriptorClientInstallation method getSPDescriptorForClient.
public static String getSPDescriptorForClient(ClientModel client) {
try {
SamlClient samlClient = new SamlClient(client);
String assertionUrl;
String logoutUrl;
URI loginBinding;
URI logoutBinding = null;
if (samlClient.forcePostBinding()) {
assertionUrl = client.getAttribute(SamlProtocol.SAML_ASSERTION_CONSUMER_URL_POST_ATTRIBUTE);
logoutUrl = client.getAttribute(SamlProtocol.SAML_SINGLE_LOGOUT_SERVICE_URL_POST_ATTRIBUTE);
loginBinding = JBossSAMLURIConstants.SAML_HTTP_POST_BINDING.getUri();
} else {
// redirect binding
assertionUrl = client.getAttribute(SamlProtocol.SAML_ASSERTION_CONSUMER_URL_REDIRECT_ATTRIBUTE);
logoutUrl = client.getAttribute(SamlProtocol.SAML_SINGLE_LOGOUT_SERVICE_URL_REDIRECT_ATTRIBUTE);
loginBinding = JBossSAMLURIConstants.SAML_HTTP_REDIRECT_BINDING.getUri();
}
if (samlClient.forceArtifactBinding()) {
if (client.getAttribute(SamlProtocol.SAML_SINGLE_LOGOUT_SERVICE_URL_ARTIFACT_ATTRIBUTE) != null) {
logoutBinding = JBossSAMLURIConstants.SAML_HTTP_ARTIFACT_BINDING.getUri();
logoutUrl = client.getAttribute(SamlProtocol.SAML_SINGLE_LOGOUT_SERVICE_URL_ARTIFACT_ATTRIBUTE);
} else {
logoutBinding = loginBinding;
}
assertionUrl = client.getAttribute(SamlProtocol.SAML_ASSERTION_CONSUMER_URL_ARTIFACT_ATTRIBUTE);
loginBinding = JBossSAMLURIConstants.SAML_HTTP_ARTIFACT_BINDING.getUri();
}
if (assertionUrl == null || assertionUrl.trim().isEmpty())
assertionUrl = client.getManagementUrl();
if (assertionUrl == null || assertionUrl.trim().isEmpty())
assertionUrl = FALLBACK_ERROR_URL_STRING;
if (logoutUrl == null || logoutUrl.trim().isEmpty())
logoutUrl = client.getManagementUrl();
if (logoutUrl == null || logoutUrl.trim().isEmpty())
logoutUrl = FALLBACK_ERROR_URL_STRING;
if (logoutBinding == null)
logoutBinding = loginBinding;
String nameIdFormat = samlClient.getNameIDFormat();
if (nameIdFormat == null)
nameIdFormat = SamlProtocol.SAML_DEFAULT_NAMEID_FORMAT;
Element spCertificate = SPMetadataDescriptor.buildKeyInfoElement(null, samlClient.getClientSigningCertificate());
Element encCertificate = SPMetadataDescriptor.buildKeyInfoElement(null, samlClient.getClientEncryptingCertificate());
StringWriter sw = new StringWriter();
XMLStreamWriter writer = StaxUtil.getXMLStreamWriter(sw);
SAMLMetadataWriter metadataWriter = new SAMLMetadataWriter(writer);
EntityDescriptorType entityDescriptor = SPMetadataDescriptor.buildSPdescriptor(loginBinding, logoutBinding, new URI(assertionUrl), new URI(logoutUrl), samlClient.requiresClientSignature(), samlClient.requiresAssertionSignature(), samlClient.requiresEncryption(), client.getClientId(), nameIdFormat, Arrays.asList(spCertificate), Arrays.asList(encCertificate));
metadataWriter.writeEntityDescriptor(entityDescriptor);
return sw.toString();
} catch (Exception ex) {
logger.error("Cannot generate SP metadata", ex);
return "";
}
}
use of org.keycloak.saml.processing.core.saml.v2.writers.SAMLMetadataWriter in project keycloak by keycloak.
the class IDPMetadataDescriptor method getIDPDescriptor.
public static String getIDPDescriptor(URI loginPostEndpoint, URI loginRedirectEndpoint, URI logoutEndpoint, URI artifactResolutionService, String entityId, boolean wantAuthnRequestsSigned, List<Element> signingCerts) throws ProcessingException {
StringWriter sw = new StringWriter();
XMLStreamWriter writer = StaxUtil.getXMLStreamWriter(sw);
SAMLMetadataWriter metadataWriter = new SAMLMetadataWriter(writer);
EntityDescriptorType entityDescriptor = new EntityDescriptorType(entityId);
IDPSSODescriptorType spIDPDescriptor = new IDPSSODescriptorType(Arrays.asList(PROTOCOL_NSURI.get()));
spIDPDescriptor.setWantAuthnRequestsSigned(wantAuthnRequestsSigned);
spIDPDescriptor.addNameIDFormat(NAMEID_FORMAT_PERSISTENT.get());
spIDPDescriptor.addNameIDFormat(NAMEID_FORMAT_TRANSIENT.get());
spIDPDescriptor.addNameIDFormat(NAMEID_FORMAT_UNSPECIFIED.get());
spIDPDescriptor.addNameIDFormat(NAMEID_FORMAT_EMAIL.get());
spIDPDescriptor.addSingleLogoutService(new EndpointType(SAML_HTTP_POST_BINDING.getUri(), logoutEndpoint));
spIDPDescriptor.addSingleLogoutService(new EndpointType(SAML_HTTP_REDIRECT_BINDING.getUri(), logoutEndpoint));
spIDPDescriptor.addSingleLogoutService(new EndpointType(SAML_HTTP_ARTIFACT_BINDING.getUri(), logoutEndpoint));
spIDPDescriptor.addSingleSignOnService(new EndpointType(SAML_HTTP_POST_BINDING.getUri(), loginPostEndpoint));
spIDPDescriptor.addSingleSignOnService(new EndpointType(SAML_HTTP_REDIRECT_BINDING.getUri(), loginRedirectEndpoint));
spIDPDescriptor.addSingleSignOnService(new EndpointType(SAML_SOAP_BINDING.getUri(), loginPostEndpoint));
spIDPDescriptor.addSingleSignOnService(new EndpointType(SAML_HTTP_ARTIFACT_BINDING.getUri(), loginPostEndpoint));
spIDPDescriptor.addArtifactResolutionService(new IndexedEndpointType(SAML_SOAP_BINDING.getUri(), artifactResolutionService));
if (wantAuthnRequestsSigned && signingCerts != null) {
for (Element key : signingCerts) {
KeyDescriptorType keyDescriptor = new KeyDescriptorType();
keyDescriptor.setUse(KeyTypes.SIGNING);
keyDescriptor.setKeyInfo(key);
spIDPDescriptor.addKeyDescriptor(keyDescriptor);
}
}
entityDescriptor.addChoiceType(new EntityDescriptorType.EDTChoiceType(Arrays.asList(new EntityDescriptorType.EDTDescriptorChoiceType(spIDPDescriptor))));
metadataWriter.writeEntityDescriptor(entityDescriptor);
return sw.toString();
}
use of org.keycloak.saml.processing.core.saml.v2.writers.SAMLMetadataWriter 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);
}
}
Aggregations