Search in sources :

Example 16 with ConfigurationException

use of org.keycloak.saml.common.exceptions.ConfigurationException in project keycloak by keycloak.

the class SAML2Response method createResponseType.

/**
 * Create a ResponseType
 *
 * <b>NOTE:</b>: The PicketLink STS is used to issue/update the assertion
 *
 * If you want to control over the assertion being issued, then use
 * {@link #createResponseType(String, SPInfoHolder, IDPInfoHolder, IssuerInfoHolder, AssertionType)}
 *
 * @param ID id of the response
 * @param sp holder with the information about the Service Provider
 * @param idp holder with the information on the Identity Provider
 * @param issuerInfo holder with information on the issuer
 *
 * @return
 *
 * @throws ConfigurationException
 * @throws ProcessingException
 */
public ResponseType createResponseType(String ID, SPInfoHolder sp, IDPInfoHolder idp, IssuerInfoHolder issuerInfo) throws ProcessingException {
    String responseDestinationURI = sp.getResponseDestinationURI();
    XMLGregorianCalendar issueInstant = XMLTimeUtil.getIssueInstant();
    // Create assertion -> subject
    SubjectType subjectType = new SubjectType();
    // subject -> nameid
    NameIDType nameIDType = new NameIDType();
    nameIDType.setFormat(idp.getNameIDFormat() == null ? null : URI.create(idp.getNameIDFormat()));
    nameIDType.setValue(idp.getNameIDFormatValue());
    SubjectType.STSubType subType = new SubjectType.STSubType();
    subType.addBaseID(nameIDType);
    subjectType.setSubType(subType);
    SubjectConfirmationType subjectConfirmation = new SubjectConfirmationType();
    subjectConfirmation.setMethod(idp.getSubjectConfirmationMethod());
    SubjectConfirmationDataType subjectConfirmationData = new SubjectConfirmationDataType();
    subjectConfirmationData.setInResponseTo(sp.getRequestID());
    subjectConfirmationData.setRecipient(responseDestinationURI);
    // subjectConfirmationData.setNotBefore(issueInstant);
    subjectConfirmationData.setNotOnOrAfter(issueInstant);
    subjectConfirmation.setSubjectConfirmationData(subjectConfirmationData);
    subjectType.addConfirmation(subjectConfirmation);
    AssertionType assertionType;
    NameIDType issuerID = issuerInfo.getIssuer();
    issueInstant = XMLTimeUtil.getIssueInstant();
    ConditionsType conditions = null;
    List<StatementAbstractType> statements = new LinkedList<>();
    // generate an id for the new assertion.
    String assertionID = IDGenerator.create("ID_");
    assertionType = SAMLAssertionFactory.createAssertion(assertionID, issuerID, issueInstant, conditions, subjectType, statements);
    try {
        AssertionUtil.createTimedConditions(assertionType, ASSERTION_VALIDITY, CLOCK_SKEW);
    } catch (ConfigurationException e) {
        throw logger.processingError(e);
    } catch (IssueInstantMissingException e) {
        throw logger.processingError(e);
    }
    ResponseType responseType = createResponseType(ID, issuerInfo, assertionType);
    // InResponseTo ID
    responseType.setInResponseTo(sp.getRequestID());
    // Destination
    responseType.setDestination(responseDestinationURI);
    return responseType;
}
Also used : EncryptedAssertionType(org.keycloak.dom.saml.v2.assertion.EncryptedAssertionType) AssertionType(org.keycloak.dom.saml.v2.assertion.AssertionType) LinkedList(java.util.LinkedList) IssueInstantMissingException(org.keycloak.saml.common.exceptions.fed.IssueInstantMissingException) ResponseType(org.keycloak.dom.saml.v2.protocol.ResponseType) StatusResponseType(org.keycloak.dom.saml.v2.protocol.StatusResponseType) XMLGregorianCalendar(javax.xml.datatype.XMLGregorianCalendar) SubjectType(org.keycloak.dom.saml.v2.assertion.SubjectType) SubjectConfirmationDataType(org.keycloak.dom.saml.v2.assertion.SubjectConfirmationDataType) SubjectConfirmationType(org.keycloak.dom.saml.v2.assertion.SubjectConfirmationType) ConfigurationException(org.keycloak.saml.common.exceptions.ConfigurationException) ConditionsType(org.keycloak.dom.saml.v2.assertion.ConditionsType) NameIDType(org.keycloak.dom.saml.v2.assertion.NameIDType) StatementAbstractType(org.keycloak.dom.saml.v2.assertion.StatementAbstractType)

Example 17 with ConfigurationException

use of org.keycloak.saml.common.exceptions.ConfigurationException in project keycloak by keycloak.

the class StaxParserUtil method getDOMElement.

/**
 * Given that the {@code XMLEventReader} is in {@code XMLStreamConstants.START_ELEMENT} mode, we parse into a DOM
 * Element
 *
 * @param xmlEventReader
 *
 * @return
 *
 * @throws ParsingException
 */
public static Element getDOMElement(XMLEventReader xmlEventReader) throws ParsingException {
    Transformer transformer;
    boolean useJDKTransformer = Boolean.parseBoolean(SecurityActions.getSystemProperty(JDK_TRANSFORMER_PROPERTY, "false"));
    try {
        if (useJDKTransformer) {
            transformer = TransformerUtil.getTransformer();
        } else {
            transformer = TransformerUtil.getStaxSourceToDomResultTransformer();
        }
        Document resultDocument = DocumentUtil.createDocument();
        DOMResult domResult = new DOMResult(resultDocument);
        Source source = new StAXSource(xmlEventReader);
        TransformerUtil.transform(transformer, source, domResult);
        Document doc = (Document) domResult.getNode();
        return doc.getDocumentElement();
    } catch (ConfigurationException e) {
        throw logger.parserException(e);
    } catch (XMLStreamException e) {
        throw logger.parserException(e);
    }
}
Also used : Transformer(javax.xml.transform.Transformer) DOMResult(javax.xml.transform.dom.DOMResult) XMLStreamException(javax.xml.stream.XMLStreamException) ConfigurationException(org.keycloak.saml.common.exceptions.ConfigurationException) StAXSource(javax.xml.transform.stax.StAXSource) Document(org.w3c.dom.Document) StreamSource(javax.xml.transform.stream.StreamSource) Source(javax.xml.transform.Source) StAXSource(javax.xml.transform.stax.StAXSource)

Example 18 with ConfigurationException

use of org.keycloak.saml.common.exceptions.ConfigurationException in project keycloak by keycloak.

the class SamlService method artifactResponseMessage.

private Response artifactResponseMessage(ArtifactResolveType artifactResolveMessage, Document artifactResponseDocument, ClientModel clientModel) throws ProcessingException, ConfigurationException {
    // Add "inResponseTo" to artifactResponse
    if (artifactResolveMessage.getID() != null && !artifactResolveMessage.getID().trim().isEmpty()) {
        Element artifactResponseElement = artifactResponseDocument.getDocumentElement();
        artifactResponseElement.setAttribute("InResponseTo", artifactResolveMessage.getID());
    }
    JaxrsSAML2BindingBuilder bindingBuilder = new JaxrsSAML2BindingBuilder(session);
    if (clientModel != null) {
        SamlClient samlClient = new SamlClient(clientModel);
        // Sign document/assertion if necessary, necessary to do this here, as the "inResponseTo" can only be set at this point
        if (samlClient.requiresRealmSignature() || samlClient.requiresAssertionSignature()) {
            KeyManager keyManager = session.keys();
            KeyManager.ActiveRsaKey keys = keyManager.getActiveRsaKey(realm);
            String keyName = samlClient.getXmlSigKeyInfoKeyNameTransformer().getKeyName(keys.getKid(), keys.getCertificate());
            String canonicalization = samlClient.getCanonicalizationMethod();
            if (canonicalization != null) {
                bindingBuilder.canonicalizationMethod(canonicalization);
            }
            bindingBuilder.signatureAlgorithm(samlClient.getSignatureAlgorithm()).signWith(keyName, keys.getPrivateKey(), keys.getPublicKey(), keys.getCertificate());
            if (samlClient.requiresRealmSignature())
                bindingBuilder.signDocument();
            if (samlClient.requiresAssertionSignature())
                bindingBuilder.signAssertions();
        }
        // Encrypt assertion if client requires it
        if (samlClient.requiresEncryption()) {
            PublicKey publicKey = null;
            try {
                publicKey = SamlProtocolUtils.getEncryptionKey(clientModel);
            } catch (Exception e) {
                logger.error("Failed to obtain encryption key for client", e);
                return emptyArtifactResponseMessage(artifactResolveMessage, null);
            }
            bindingBuilder.encrypt(publicKey);
        }
    }
    bindingBuilder.postBinding(artifactResponseDocument);
    Soap.SoapMessageBuilder messageBuilder = Soap.createMessage();
    messageBuilder.addToBody(artifactResponseDocument);
    if (logger.isDebugEnabled()) {
        String artifactResponse = DocumentUtil.asString(artifactResponseDocument);
        logger.debugf("Sending artifactResponse message for artifact %s. Message: \n %s", artifactResolveMessage.getArtifact(), artifactResponse);
    }
    return messageBuilder.build();
}
Also used : PublicKey(java.security.PublicKey) Element(org.w3c.dom.Element) Soap(org.keycloak.protocol.saml.profile.util.Soap) KeyManager(org.keycloak.models.KeyManager) ParsingException(org.keycloak.saml.common.exceptions.ParsingException) IOException(java.io.IOException) URISyntaxException(java.net.URISyntaxException) VerificationException(org.keycloak.common.VerificationException) NotFoundException(javax.ws.rs.NotFoundException) ProcessingException(org.keycloak.saml.common.exceptions.ProcessingException) ConfigurationException(org.keycloak.saml.common.exceptions.ConfigurationException) ParserConfigurationException(javax.xml.parsers.ParserConfigurationException)

Example 19 with ConfigurationException

use of org.keycloak.saml.common.exceptions.ConfigurationException in project keycloak by keycloak.

the class XMLEncryptionUtil method encryptElementInDocument.

/**
 * Encrypt the root document element inside a Document. <b>NOTE:</b> The document root element will be replaced by
 * the
 * wrapping element.
 *
 * @param document Document that contains an element to encrypt
 * @param publicKey The Public Key used to encrypt the secret encryption key
 * @param secretKey The secret encryption key
 * @param keySize Length of key
 * @param wrappingElementQName QName of the element to be used to wrap around the cipher data.
 * @param addEncryptedKeyInKeyInfo Should the encrypted key be inside a KeyInfo or added as a peer of Cipher Data
 *
 * @return An element that has the wrappingElementQName
 *
 * @throws ProcessingException
 * @throws org.keycloak.saml.common.exceptions.ConfigurationException
 */
public static Element encryptElementInDocument(Document document, PublicKey publicKey, SecretKey secretKey, int keySize, QName wrappingElementQName, boolean addEncryptedKeyInKeyInfo) throws ProcessingException, ConfigurationException {
    String wrappingElementPrefix = wrappingElementQName.getPrefix();
    if (wrappingElementPrefix == null || "".equals(wrappingElementPrefix))
        throw logger.wrongTypeError("Wrapping element prefix invalid");
    XMLCipher cipher = null;
    EncryptedKey encryptedKey = encryptKey(document, secretKey, publicKey, keySize);
    String encryptionAlgorithm = getXMLEncryptionURL(secretKey.getAlgorithm(), keySize);
    // Encrypt the Document
    try {
        cipher = XMLCipher.getInstance(encryptionAlgorithm);
        cipher.init(XMLCipher.ENCRYPT_MODE, secretKey);
    } catch (XMLEncryptionException e1) {
        throw logger.configurationError(e1);
    }
    Document encryptedDoc;
    try {
        encryptedDoc = cipher.doFinal(document, document.getDocumentElement());
    } catch (Exception e) {
        throw logger.processingError(e);
    }
    // The EncryptedKey element is added
    Element encryptedKeyElement = cipher.martial(document, encryptedKey);
    final String wrappingElementName;
    if (StringUtil.isNullOrEmpty(wrappingElementPrefix)) {
        wrappingElementName = wrappingElementQName.getLocalPart();
    } else {
        wrappingElementName = wrappingElementPrefix + ":" + wrappingElementQName.getLocalPart();
    }
    // Create the wrapping element and set its attribute NS
    Element wrappingElement = encryptedDoc.createElementNS(wrappingElementQName.getNamespaceURI(), wrappingElementName);
    if (!StringUtil.isNullOrEmpty(wrappingElementPrefix)) {
        wrappingElement.setAttributeNS(XMLConstants.XMLNS_ATTRIBUTE_NS_URI, "xmlns:" + wrappingElementPrefix, wrappingElementQName.getNamespaceURI());
    }
    Element encryptedDocRootElement = encryptedDoc.getDocumentElement();
    // Bring in the encrypted wrapping element to wrap the root node
    encryptedDoc.replaceChild(wrappingElement, encryptedDocRootElement);
    wrappingElement.appendChild(encryptedDocRootElement);
    if (addEncryptedKeyInKeyInfo) {
        // Outer ds:KeyInfo Element to hold the EncryptionKey
        Element sigElement = encryptedDoc.createElementNS(XMLSignature.XMLNS, DS_KEY_INFO);
        sigElement.setAttributeNS(XMLConstants.XMLNS_ATTRIBUTE_NS_URI, "xmlns:ds", XMLSignature.XMLNS);
        sigElement.appendChild(encryptedKeyElement);
        // Insert the Encrypted key before the CipherData element
        NodeList nodeList = encryptedDocRootElement.getElementsByTagNameNS(EncryptionConstants.EncryptionSpecNS, EncryptionConstants._TAG_CIPHERDATA);
        if (nodeList == null || nodeList.getLength() == 0)
            throw logger.domMissingElementError("xenc:CipherData");
        Element cipherDataElement = (Element) nodeList.item(0);
        encryptedDocRootElement.insertBefore(sigElement, cipherDataElement);
    } else {
        // Add the encrypted key as a child of the wrapping element
        wrappingElement.appendChild(encryptedKeyElement);
    }
    return encryptedDoc.getDocumentElement();
}
Also used : EncryptedKey(org.apache.xml.security.encryption.EncryptedKey) Element(org.w3c.dom.Element) NodeList(org.w3c.dom.NodeList) XMLCipher(org.apache.xml.security.encryption.XMLCipher) Document(org.w3c.dom.Document) ProcessingException(org.keycloak.saml.common.exceptions.ProcessingException) XMLEncryptionException(org.apache.xml.security.encryption.XMLEncryptionException) ConfigurationException(org.keycloak.saml.common.exceptions.ConfigurationException) XMLEncryptionException(org.apache.xml.security.encryption.XMLEncryptionException)

Example 20 with ConfigurationException

use of org.keycloak.saml.common.exceptions.ConfigurationException in project keycloak by keycloak.

the class SamlClient method createLoginRequestDocument.

/**
 * Creates a SAML login request document with the given parameters. See SAML &lt;AuthnRequest&gt; description for more details.
 *
 * @param issuer
 * @param assertionConsumerURL
 * @param destination
 * @return
 */
public static AuthnRequestType createLoginRequestDocument(String issuer, String assertionConsumerURL, URI destination) {
    try {
        SAML2Request samlReq = new SAML2Request();
        AuthnRequestType loginReq = samlReq.createAuthnRequestType(UUID.randomUUID().toString(), assertionConsumerURL, destination == null ? null : destination.toString(), issuer);
        return loginReq;
    } catch (ConfigurationException ex) {
        throw new RuntimeException(ex);
    }
}
Also used : AuthnRequestType(org.keycloak.dom.saml.v2.protocol.AuthnRequestType) ConfigurationException(org.keycloak.saml.common.exceptions.ConfigurationException) SAML2Request(org.keycloak.saml.processing.api.saml.v2.request.SAML2Request)

Aggregations

ConfigurationException (org.keycloak.saml.common.exceptions.ConfigurationException)24 ProcessingException (org.keycloak.saml.common.exceptions.ProcessingException)20 ParsingException (org.keycloak.saml.common.exceptions.ParsingException)14 Document (org.w3c.dom.Document)14 AuthnRequestType (org.keycloak.dom.saml.v2.protocol.AuthnRequestType)8 IOException (java.io.IOException)7 Element (org.w3c.dom.Element)6 ResponseType (org.keycloak.dom.saml.v2.protocol.ResponseType)5 StatusResponseType (org.keycloak.dom.saml.v2.protocol.StatusResponseType)5 SAML2Request (org.keycloak.saml.processing.api.saml.v2.request.SAML2Request)5 SAMLDocumentHolder (org.keycloak.saml.processing.core.saml.v2.common.SAMLDocumentHolder)5 ParserConfigurationException (javax.xml.parsers.ParserConfigurationException)4 Response (javax.ws.rs.core.Response)3 Test (org.junit.Test)3 VerificationException (org.keycloak.common.VerificationException)3 ClientModel (org.keycloak.models.ClientModel)3 SignatureAlgorithm (org.keycloak.saml.SignatureAlgorithm)3 JBossSAMLURIConstants (org.keycloak.saml.common.constants.JBossSAMLURIConstants)3 SAML2Response (org.keycloak.saml.processing.api.saml.v2.response.SAML2Response)3 ByteArrayInputStream (java.io.ByteArrayInputStream)2