Search in sources :

Example 1 with SAMLMetadataWriter

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 "";
    }
}
Also used : SAMLMetadataWriter(org.keycloak.saml.processing.core.saml.v2.writers.SAMLMetadataWriter) StringWriter(java.io.StringWriter) XMLStreamWriter(javax.xml.stream.XMLStreamWriter) Element(org.w3c.dom.Element) EntityDescriptorType(org.keycloak.dom.saml.v2.metadata.EntityDescriptorType) URI(java.net.URI) SamlClient(org.keycloak.protocol.saml.SamlClient)

Example 2 with SAMLMetadataWriter

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();
}
Also used : SAMLMetadataWriter(org.keycloak.saml.processing.core.saml.v2.writers.SAMLMetadataWriter) IDPSSODescriptorType(org.keycloak.dom.saml.v2.metadata.IDPSSODescriptorType) StringWriter(java.io.StringWriter) XMLStreamWriter(javax.xml.stream.XMLStreamWriter) Element(org.w3c.dom.Element) EndpointType(org.keycloak.dom.saml.v2.metadata.EndpointType) IndexedEndpointType(org.keycloak.dom.saml.v2.metadata.IndexedEndpointType) EntityDescriptorType(org.keycloak.dom.saml.v2.metadata.EntityDescriptorType) IndexedEndpointType(org.keycloak.dom.saml.v2.metadata.IndexedEndpointType) KeyDescriptorType(org.keycloak.dom.saml.v2.metadata.KeyDescriptorType)

Example 3 with SAMLMetadataWriter

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);
    }
}
Also used : SAMLMetadataWriter(org.keycloak.saml.processing.core.saml.v2.writers.SAMLMetadataWriter) Element(org.w3c.dom.Element) Node(org.w3c.dom.Node) ArrayList(java.util.ArrayList) Document(org.w3c.dom.Document) URI(java.net.URI) Entry(java.util.Map.Entry) StringWriter(java.io.StringWriter) LocalizedNameType(org.keycloak.dom.saml.v2.metadata.LocalizedNameType) XMLStreamWriter(javax.xml.stream.XMLStreamWriter) IdentityProviderMapper(org.keycloak.broker.provider.IdentityProviderMapper) ParserConfigurationException(javax.xml.parsers.ParserConfigurationException) EntityDescriptorType(org.keycloak.dom.saml.v2.metadata.EntityDescriptorType) SAML2Signature(org.keycloak.saml.processing.api.saml.v2.sig.SAML2Signature) KeyManager(org.keycloak.models.KeyManager) KeyPair(java.security.KeyPair) LinkedList(java.util.LinkedList) ConfigurationException(org.keycloak.saml.common.exceptions.ConfigurationException) IdentityBrokerException(org.keycloak.broker.provider.IdentityBrokerException) ParserConfigurationException(javax.xml.parsers.ParserConfigurationException) SamlMetadataDescriptorUpdater(org.keycloak.protocol.saml.mappers.SamlMetadataDescriptorUpdater) AttributeConsumingServiceType(org.keycloak.dom.saml.v2.metadata.AttributeConsumingServiceType)

Aggregations

StringWriter (java.io.StringWriter)3 XMLStreamWriter (javax.xml.stream.XMLStreamWriter)3 EntityDescriptorType (org.keycloak.dom.saml.v2.metadata.EntityDescriptorType)3 SAMLMetadataWriter (org.keycloak.saml.processing.core.saml.v2.writers.SAMLMetadataWriter)3 Element (org.w3c.dom.Element)3 URI (java.net.URI)2 KeyPair (java.security.KeyPair)1 ArrayList (java.util.ArrayList)1 LinkedList (java.util.LinkedList)1 Entry (java.util.Map.Entry)1 ParserConfigurationException (javax.xml.parsers.ParserConfigurationException)1 IdentityBrokerException (org.keycloak.broker.provider.IdentityBrokerException)1 IdentityProviderMapper (org.keycloak.broker.provider.IdentityProviderMapper)1 AttributeConsumingServiceType (org.keycloak.dom.saml.v2.metadata.AttributeConsumingServiceType)1 EndpointType (org.keycloak.dom.saml.v2.metadata.EndpointType)1 IDPSSODescriptorType (org.keycloak.dom.saml.v2.metadata.IDPSSODescriptorType)1 IndexedEndpointType (org.keycloak.dom.saml.v2.metadata.IndexedEndpointType)1 KeyDescriptorType (org.keycloak.dom.saml.v2.metadata.KeyDescriptorType)1 LocalizedNameType (org.keycloak.dom.saml.v2.metadata.LocalizedNameType)1 KeyManager (org.keycloak.models.KeyManager)1