Search in sources :

Example 11 with Issuer

use of org.opensaml.saml.saml2.core.Issuer in project cxf by apache.

the class SAMLSSOResponseValidator method validateSamlResponse.

/**
 * Validate a SAML 2 Protocol Response
 * @param samlResponse
 * @param postBinding
 * @return a SSOValidatorResponse object
 * @throws WSSecurityException
 */
public SSOValidatorResponse validateSamlResponse(org.opensaml.saml.saml2.core.Response samlResponse, boolean postBinding) throws WSSecurityException {
    // Check the Issuer
    validateIssuer(samlResponse.getIssuer());
    // The Response must contain at least one Assertion.
    if (samlResponse.getAssertions() == null || samlResponse.getAssertions().isEmpty()) {
        LOG.fine("The Response must contain at least one Assertion");
        throw new WSSecurityException(WSSecurityException.ErrorCode.FAILURE, "invalidSAMLsecurity");
    }
    // The Response must contain a Destination that matches the assertionConsumerURL if it is
    // signed
    String destination = samlResponse.getDestination();
    if (samlResponse.isSigned() && (destination == null || !destination.equals(assertionConsumerURL))) {
        LOG.fine("The Response must contain a destination that matches the assertion consumer URL");
        throw new WSSecurityException(WSSecurityException.ErrorCode.FAILURE, "invalidSAMLsecurity");
    }
    if (enforceResponseSigned && !samlResponse.isSigned()) {
        LOG.fine("The Response must be signed!");
        throw new WSSecurityException(WSSecurityException.ErrorCode.FAILURE, "invalidSAMLsecurity");
    }
    // Validate Assertions
    org.opensaml.saml.saml2.core.Assertion validAssertion = null;
    Instant sessionNotOnOrAfter = null;
    for (org.opensaml.saml.saml2.core.Assertion assertion : samlResponse.getAssertions()) {
        // Check the Issuer
        if (assertion.getIssuer() == null) {
            LOG.fine("Assertion Issuer must not be null");
            throw new WSSecurityException(WSSecurityException.ErrorCode.FAILURE, "invalidSAMLsecurity");
        }
        validateIssuer(assertion.getIssuer());
        if (!samlResponse.isSigned() && enforceAssertionsSigned && assertion.getSignature() == null) {
            LOG.fine("The enclosed assertions in the SAML Response must be signed");
            throw new WSSecurityException(WSSecurityException.ErrorCode.FAILURE, "invalidSAMLsecurity");
        }
        // Check for AuthnStatements and validate the Subject accordingly
        if (assertion.getAuthnStatements() != null && !assertion.getAuthnStatements().isEmpty()) {
            org.opensaml.saml.saml2.core.Subject subject = assertion.getSubject();
            org.opensaml.saml.saml2.core.SubjectConfirmation subjectConf = validateAuthenticationSubject(subject, assertion.getID(), postBinding);
            if (subjectConf != null) {
                validateAudienceRestrictionCondition(assertion.getConditions());
                validAssertion = assertion;
                // Store Session NotOnOrAfter
                for (AuthnStatement authnStatment : assertion.getAuthnStatements()) {
                    if (authnStatment.getSessionNotOnOrAfter() != null) {
                        sessionNotOnOrAfter = Instant.ofEpochMilli(authnStatment.getSessionNotOnOrAfter().toDate().getTime());
                    }
                }
                // Fall back to the SubjectConfirmationData NotOnOrAfter if we have no session NotOnOrAfter
                if (sessionNotOnOrAfter == null) {
                    sessionNotOnOrAfter = Instant.ofEpochMilli(subjectConf.getSubjectConfirmationData().getNotOnOrAfter().toDate().getTime());
                }
            }
        }
    }
    if (validAssertion == null) {
        LOG.fine("The Response did not contain any Authentication Statement that matched " + "the Subject Confirmation criteria");
        throw new WSSecurityException(WSSecurityException.ErrorCode.FAILURE, "invalidSAMLsecurity");
    }
    SSOValidatorResponse validatorResponse = new SSOValidatorResponse();
    validatorResponse.setResponseId(samlResponse.getID());
    validatorResponse.setSessionNotOnOrAfter(sessionNotOnOrAfter);
    if (samlResponse.getIssueInstant() != null) {
        validatorResponse.setCreated(Instant.ofEpochMilli(samlResponse.getIssueInstant().toDate().getTime()));
    }
    Element assertionElement = validAssertion.getDOM();
    Element clonedAssertionElement = (Element) assertionElement.cloneNode(true);
    validatorResponse.setAssertionElement(clonedAssertionElement);
    validatorResponse.setAssertion(DOM2Writer.nodeToString(clonedAssertionElement));
    validatorResponse.setOpensamlAssertion(validAssertion);
    return validatorResponse;
}
Also used : Instant(java.time.Instant) Element(org.w3c.dom.Element) AuthnStatement(org.opensaml.saml.saml2.core.AuthnStatement) WSSecurityException(org.apache.wss4j.common.ext.WSSecurityException)

Example 12 with Issuer

use of org.opensaml.saml.saml2.core.Issuer in project cxf by apache.

the class SamlpRequestComponentBuilder method createIssuer.

@SuppressWarnings("unchecked")
public static Issuer createIssuer(String issuerValue) {
    if (issuerBuilder == null) {
        issuerBuilder = (SAMLObjectBuilder<Issuer>) builderFactory.getBuilder(Issuer.DEFAULT_ELEMENT_NAME);
    }
    Issuer issuer = issuerBuilder.buildObject();
    issuer.setValue(issuerValue);
    return issuer;
}
Also used : Issuer(org.opensaml.saml.saml2.core.Issuer)

Example 13 with Issuer

use of org.opensaml.saml.saml2.core.Issuer in project cxf by apache.

the class CombinedValidatorTest method createResponse.

private Response createResponse(Document doc) throws Exception {
    Status status = SAML2PResponseComponentBuilder.createStatus(SAMLProtocolResponseValidator.SAML2_STATUSCODE_SUCCESS, null);
    Response response = SAML2PResponseComponentBuilder.createSAMLResponse("http://cxf.apache.org/saml", "http://cxf.apache.org/issuer", status);
    response.setDestination("http://recipient.apache.org");
    // Create an AuthenticationAssertion
    SAML2CallbackHandler callbackHandler = new SAML2CallbackHandler();
    callbackHandler.setStatement(SAML2CallbackHandler.Statement.AUTHN);
    callbackHandler.setIssuer("http://cxf.apache.org/issuer");
    callbackHandler.setConfirmationMethod(SAML2Constants.CONF_BEARER);
    callbackHandler.setSubjectName("alice");
    SubjectConfirmationDataBean subjectConfirmationData = new SubjectConfirmationDataBean();
    subjectConfirmationData.setAddress("http://apache.org");
    subjectConfirmationData.setInResponseTo("12345");
    subjectConfirmationData.setNotAfter(new DateTime().plusMinutes(5));
    subjectConfirmationData.setRecipient("http://recipient.apache.org");
    callbackHandler.setSubjectConfirmationData(subjectConfirmationData);
    ConditionsBean conditions = new ConditionsBean();
    conditions.setNotBefore(new DateTime());
    conditions.setNotAfter(new DateTime().plusMinutes(5));
    AudienceRestrictionBean audienceRestriction = new AudienceRestrictionBean();
    audienceRestriction.setAudienceURIs(Collections.singletonList("http://service.apache.org"));
    conditions.setAudienceRestrictions(Collections.singletonList(audienceRestriction));
    callbackHandler.setConditions(conditions);
    SAMLCallback samlCallback = new SAMLCallback();
    SAMLUtil.doSAMLCallback(callbackHandler, samlCallback);
    SamlAssertionWrapper assertion = new SamlAssertionWrapper(samlCallback);
    Crypto issuerCrypto = new Merlin();
    KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
    ClassLoader loader = Loader.getClassLoader(CombinedValidatorTest.class);
    InputStream input = Merlin.loadInputStream(loader, "alice.jks");
    keyStore.load(input, "password".toCharArray());
    ((Merlin) issuerCrypto).setKeyStore(keyStore);
    assertion.signAssertion("alice", "password", issuerCrypto, false);
    response.getAssertions().add(assertion.getSaml2());
    return response;
}
Also used : Status(org.opensaml.saml.saml2.core.Status) AudienceRestrictionBean(org.apache.wss4j.common.saml.bean.AudienceRestrictionBean) InputStream(java.io.InputStream) ConditionsBean(org.apache.wss4j.common.saml.bean.ConditionsBean) SamlAssertionWrapper(org.apache.wss4j.common.saml.SamlAssertionWrapper) KeyStore(java.security.KeyStore) DateTime(org.joda.time.DateTime) Response(org.opensaml.saml.saml2.core.Response) Crypto(org.apache.wss4j.common.crypto.Crypto) SubjectConfirmationDataBean(org.apache.wss4j.common.saml.bean.SubjectConfirmationDataBean) SAMLCallback(org.apache.wss4j.common.saml.SAMLCallback) Merlin(org.apache.wss4j.common.crypto.Merlin)

Example 14 with Issuer

use of org.opensaml.saml.saml2.core.Issuer in project cxf by apache.

the class CombinedValidatorTest method testWrappingAttack3.

@org.junit.Test
public void testWrappingAttack3() throws Exception {
    Document doc = DOMUtils.createDocument();
    Response response = createResponse(doc);
    Element responseElement = OpenSAMLUtil.toDom(response, doc);
    doc.appendChild(responseElement);
    assertNotNull(responseElement);
    // Get Assertion Element
    Element assertionElement = (Element) responseElement.getElementsByTagNameNS(SAMLConstants.SAML20_NS, "Assertion").item(0);
    assertNotNull(assertionElement);
    // Clone it, strip the Signature, modify the Subject, change Subj Conf
    Element clonedAssertion = (Element) assertionElement.cloneNode(true);
    clonedAssertion.setAttributeNS(null, "ID", "_12345623562");
    Element sigElement = (Element) clonedAssertion.getElementsByTagNameNS(WSS4JConstants.SIG_NS, "Signature").item(0);
    clonedAssertion.removeChild(sigElement);
    Element subjElement = (Element) clonedAssertion.getElementsByTagNameNS(SAMLConstants.SAML20_NS, "Subject").item(0);
    Element subjNameIdElement = (Element) subjElement.getElementsByTagNameNS(SAMLConstants.SAML20_NS, "NameID").item(0);
    subjNameIdElement.setTextContent("bob");
    Element subjConfElement = (Element) subjElement.getElementsByTagNameNS(SAMLConstants.SAML20_NS, "SubjectConfirmation").item(0);
    subjConfElement.setAttributeNS(null, "Method", SAML2Constants.CONF_SENDER_VOUCHES);
    // Now insert the modified cloned Assertion into the Response before actual assertion
    responseElement.insertBefore(clonedAssertion, assertionElement);
    // System.out.println(DOM2Writer.nodeToString(responseElement));
    Response marshalledResponse = (Response) OpenSAMLUtil.fromDom(responseElement);
    Crypto issuerCrypto = new Merlin();
    KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
    ClassLoader loader = Loader.getClassLoader(CombinedValidatorTest.class);
    InputStream input = Merlin.loadInputStream(loader, "alice.jks");
    keyStore.load(input, "password".toCharArray());
    ((Merlin) issuerCrypto).setKeyStore(keyStore);
    // Validate the Response
    SAMLProtocolResponseValidator validator = new SAMLProtocolResponseValidator();
    validator.validateSamlResponse(marshalledResponse, issuerCrypto, new KeystorePasswordCallback());
    // Test SSO validation
    SAMLSSOResponseValidator ssoValidator = new SAMLSSOResponseValidator();
    ssoValidator.setEnforceAssertionsSigned(false);
    ssoValidator.setIssuerIDP("http://cxf.apache.org/issuer");
    ssoValidator.setAssertionConsumerURL("http://recipient.apache.org");
    ssoValidator.setClientAddress("http://apache.org");
    ssoValidator.setRequestId("12345");
    ssoValidator.setSpIdentifier("http://service.apache.org");
    // Parse the response
    SSOValidatorResponse ssoResponse = ssoValidator.validateSamlResponse(marshalledResponse, false);
    SamlAssertionWrapper parsedAssertion = new SamlAssertionWrapper(ssoResponse.getAssertionElement());
    assertEquals("alice", parsedAssertion.getSubjectName());
}
Also used : InputStream(java.io.InputStream) Element(org.w3c.dom.Element) SamlAssertionWrapper(org.apache.wss4j.common.saml.SamlAssertionWrapper) Document(org.w3c.dom.Document) KeyStore(java.security.KeyStore) Response(org.opensaml.saml.saml2.core.Response) Crypto(org.apache.wss4j.common.crypto.Crypto) Merlin(org.apache.wss4j.common.crypto.Merlin)

Example 15 with Issuer

use of org.opensaml.saml.saml2.core.Issuer in project cxf by apache.

the class CombinedValidatorTest method testSuccessfulValidation.

@org.junit.Test
public void testSuccessfulValidation() throws Exception {
    Document doc = DOMUtils.createDocument();
    Response response = createResponse(doc);
    Element responseElement = OpenSAMLUtil.toDom(response, doc);
    doc.appendChild(responseElement);
    assertNotNull(responseElement);
    Response marshalledResponse = (Response) OpenSAMLUtil.fromDom(responseElement);
    Crypto issuerCrypto = new Merlin();
    KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
    ClassLoader loader = Loader.getClassLoader(CombinedValidatorTest.class);
    InputStream input = Merlin.loadInputStream(loader, "alice.jks");
    keyStore.load(input, "password".toCharArray());
    ((Merlin) issuerCrypto).setKeyStore(keyStore);
    // Validate the Response
    SAMLProtocolResponseValidator validator = new SAMLProtocolResponseValidator();
    validator.validateSamlResponse(marshalledResponse, issuerCrypto, new KeystorePasswordCallback());
    // Test SSO validation
    SAMLSSOResponseValidator ssoValidator = new SAMLSSOResponseValidator();
    ssoValidator.setIssuerIDP("http://cxf.apache.org/issuer");
    ssoValidator.setAssertionConsumerURL("http://recipient.apache.org");
    ssoValidator.setClientAddress("http://apache.org");
    ssoValidator.setRequestId("12345");
    ssoValidator.setSpIdentifier("http://service.apache.org");
    // Parse the response
    SSOValidatorResponse ssoResponse = ssoValidator.validateSamlResponse(marshalledResponse, false);
    SamlAssertionWrapper parsedAssertion = new SamlAssertionWrapper(ssoResponse.getAssertionElement());
    assertEquals("alice", parsedAssertion.getSubjectName());
}
Also used : InputStream(java.io.InputStream) Element(org.w3c.dom.Element) SamlAssertionWrapper(org.apache.wss4j.common.saml.SamlAssertionWrapper) Document(org.w3c.dom.Document) KeyStore(java.security.KeyStore) Response(org.opensaml.saml.saml2.core.Response) Crypto(org.apache.wss4j.common.crypto.Crypto) Merlin(org.apache.wss4j.common.crypto.Merlin)

Aggregations

Issuer (org.opensaml.saml.saml2.core.Issuer)79 Response (org.opensaml.saml.saml2.core.Response)59 DateTime (org.joda.time.DateTime)57 Test (org.junit.jupiter.api.Test)37 AuthnRequest (org.opensaml.saml.saml2.core.AuthnRequest)36 Element (org.w3c.dom.Element)34 WSSecurityException (org.apache.wss4j.common.ext.WSSecurityException)32 lombok.val (lombok.val)28 SamlAssertionWrapper (org.apache.wss4j.common.saml.SamlAssertionWrapper)26 Document (org.w3c.dom.Document)25 Status (org.opensaml.saml.saml2.core.Status)24 Assertion (org.opensaml.saml.saml2.core.Assertion)22 SAMLCallback (org.apache.wss4j.common.saml.SAMLCallback)20 SubjectConfirmationDataBean (org.apache.wss4j.common.saml.bean.SubjectConfirmationDataBean)20 SAMLObjectBuilder (org.opensaml.saml.common.SAMLObjectBuilder)17 LogoutRequest (org.opensaml.saml.saml2.core.LogoutRequest)16 InputStream (java.io.InputStream)15 IssuerBuilder (org.opensaml.saml.saml2.core.impl.IssuerBuilder)15 Crypto (org.apache.wss4j.common.crypto.Crypto)14 KeyStore (java.security.KeyStore)13