Adding lots of SAML SSO Negative tests
Conflicts:
rt/rs/security/sso/saml/src/test/java/org/apache/cxf/rs/security/saml/sso/AbstractSAMLCallbackHandler.java
rt/rs/security/sso/saml/src/test/java/org/apache/cxf/rs/security/saml/sso/SAMLResponseValidatorTest.java
rt/rs/security/sso/saml/src/test/java/org/apache/cxf/rs/security/saml/sso/SAMLSSOResponseValidatorTest.java
Project: http://git-wip-us.apache.org/repos/asf/cxf/repo
Commit: http://git-wip-us.apache.org/repos/asf/cxf/commit/32cb2436
Tree: http://git-wip-us.apache.org/repos/asf/cxf/tree/32cb2436
Diff: http://git-wip-us.apache.org/repos/asf/cxf/diff/32cb2436
Branch: refs/heads/2.7.x-fixes
Commit: 32cb243612b02974a2e48b790b8a61641288a22b
Parents: f4698f2
Author: Colm O hEigeartaigh <[email protected]>
Authored: Tue Jan 13 12:01:58 2015 +0000
Committer: Colm O hEigeartaigh <[email protected]>
Committed: Tue Jan 13 12:11:46 2015 +0000
----------------------------------------------------------------------
.../saml/sso/AbstractSAMLCallbackHandler.java | 38 ++
.../sso/SAML2PResponseComponentBuilder.java | 15 +
.../saml/sso/SAMLResponseValidatorTest.java | 357 ++++++++++++++
.../saml/sso/SAMLSSOResponseValidatorTest.java | 473 ++++++++++++++++++-
4 files changed, 880 insertions(+), 3 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/cxf/blob/32cb2436/rt/rs/security/sso/saml/src/test/java/org/apache/cxf/rs/security/saml/sso/AbstractSAMLCallbackHandler.java
----------------------------------------------------------------------
diff --git
a/rt/rs/security/sso/saml/src/test/java/org/apache/cxf/rs/security/saml/sso/AbstractSAMLCallbackHandler.java
b/rt/rs/security/sso/saml/src/test/java/org/apache/cxf/rs/security/saml/sso/AbstractSAMLCallbackHandler.java
index c09d2e3..55e64b2 100644
---
a/rt/rs/security/sso/saml/src/test/java/org/apache/cxf/rs/security/saml/sso/AbstractSAMLCallbackHandler.java
+++
b/rt/rs/security/sso/saml/src/test/java/org/apache/cxf/rs/security/saml/sso/AbstractSAMLCallbackHandler.java
@@ -29,6 +29,7 @@ import javax.xml.parsers.DocumentBuilderFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
+<<<<<<< HEAD
import org.apache.ws.security.WSConstants;
import org.apache.ws.security.message.WSSecEncryptedKey;
@@ -44,6 +45,23 @@ import
org.apache.ws.security.saml.ext.bean.KeyInfoBean.CERT_IDENTIFIER;
import org.apache.ws.security.saml.ext.bean.SubjectBean;
import org.apache.ws.security.saml.ext.bean.SubjectConfirmationDataBean;
import org.apache.ws.security.saml.ext.bean.SubjectLocalityBean;
+=======
+import org.apache.wss4j.common.saml.SAMLCallback;
+import org.apache.wss4j.common.saml.bean.ActionBean;
+import org.apache.wss4j.common.saml.bean.AttributeBean;
+import org.apache.wss4j.common.saml.bean.AttributeStatementBean;
+import org.apache.wss4j.common.saml.bean.AuthDecisionStatementBean;
+import org.apache.wss4j.common.saml.bean.AuthenticationStatementBean;
+import org.apache.wss4j.common.saml.bean.ConditionsBean;
+import org.apache.wss4j.common.saml.bean.KeyInfoBean;
+import org.apache.wss4j.common.saml.bean.KeyInfoBean.CERT_IDENTIFIER;
+import org.apache.wss4j.common.saml.bean.SubjectBean;
+import org.apache.wss4j.common.saml.bean.SubjectConfirmationDataBean;
+import org.apache.wss4j.common.saml.bean.SubjectLocalityBean;
+import org.apache.wss4j.dom.WSConstants;
+import org.apache.wss4j.dom.message.WSSecEncryptedKey;
+import org.joda.time.DateTime;
+>>>>>>> f825cb0... Adding lots of SAML SSO Negative tests
/**
* A base implementation of a Callback Handler for a SAML assertion. By
default it creates an
@@ -70,7 +88,25 @@ public abstract class AbstractSAMLCallbackHandler implements
CallbackHandler {
protected List<?> customAttributeValues;
protected ConditionsBean conditions;
protected SubjectConfirmationDataBean subjectConfirmationData;
+ protected DateTime authnInstant;
+ protected DateTime sessionNotOnOrAfter;
+ public DateTime getSessionNotOnOrAfter() {
+ return sessionNotOnOrAfter;
+ }
+
+ public void setSessionNotOnOrAfter(DateTime sessionNotOnOrAfter) {
+ this.sessionNotOnOrAfter = sessionNotOnOrAfter;
+ }
+
+ public DateTime getAuthnInstant() {
+ return authnInstant;
+ }
+
+ public void setAuthnInstant(DateTime authnInstant) {
+ this.authnInstant = authnInstant;
+ }
+
public void setSubjectConfirmationData(SubjectConfirmationDataBean
subjectConfirmationData) {
this.subjectConfirmationData = subjectConfirmationData;
}
@@ -135,6 +171,8 @@ public abstract class AbstractSAMLCallbackHandler
implements CallbackHandler {
subjectLocality.setDnsAddress(subjectLocalityDnsAddress);
authBean.setSubjectLocality(subjectLocality);
}
+ authBean.setAuthenticationInstant(authnInstant);
+ authBean.setSessionNotOnOrAfter(sessionNotOnOrAfter);
authBean.setAuthenticationMethod("Password");
callback.setAuthenticationStatementData(Collections.singletonList(authBean));
} else if (statement == Statement.ATTR) {
http://git-wip-us.apache.org/repos/asf/cxf/blob/32cb2436/rt/rs/security/sso/saml/src/test/java/org/apache/cxf/rs/security/saml/sso/SAML2PResponseComponentBuilder.java
----------------------------------------------------------------------
diff --git
a/rt/rs/security/sso/saml/src/test/java/org/apache/cxf/rs/security/saml/sso/SAML2PResponseComponentBuilder.java
b/rt/rs/security/sso/saml/src/test/java/org/apache/cxf/rs/security/saml/sso/SAML2PResponseComponentBuilder.java
index ddadecf..a902cbc 100644
---
a/rt/rs/security/sso/saml/src/test/java/org/apache/cxf/rs/security/saml/sso/SAML2PResponseComponentBuilder.java
+++
b/rt/rs/security/sso/saml/src/test/java/org/apache/cxf/rs/security/saml/sso/SAML2PResponseComponentBuilder.java
@@ -25,6 +25,7 @@ import org.joda.time.DateTime;
import org.opensaml.Configuration;
import org.opensaml.common.SAMLObjectBuilder;
import org.opensaml.common.SAMLVersion;
+import org.opensaml.saml2.core.AuthnContextClassRef;
import org.opensaml.saml2.core.Issuer;
import org.opensaml.saml2.core.Response;
import org.opensaml.saml2.core.Status;
@@ -47,6 +48,8 @@ public final class SAML2PResponseComponentBuilder {
private static SAMLObjectBuilder<StatusMessage> statusMessageBuilder;
+ private static SAMLObjectBuilder<AuthnContextClassRef>
authnContextClassRefBuilder;
+
private static XMLObjectBuilderFactory builderFactory =
Configuration.getBuilderFactory();
private SAML2PResponseComponentBuilder() {
@@ -122,5 +125,17 @@ public final class SAML2PResponseComponentBuilder {
return status;
}
+ @SuppressWarnings("unchecked")
+ public static AuthnContextClassRef createAuthnContextClassRef(String
newAuthnContextClassRef) {
+ if (authnContextClassRefBuilder == null) {
+ authnContextClassRefBuilder =
(SAMLObjectBuilder<AuthnContextClassRef>)
+
builderFactory.getBuilder(AuthnContextClassRef.DEFAULT_ELEMENT_NAME);
+ }
+
+ AuthnContextClassRef authnContextClassRef =
authnContextClassRefBuilder.buildObject();
+ authnContextClassRef.setAuthnContextClassRef(newAuthnContextClassRef);
+
+ return authnContextClassRef;
+ }
}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/cxf/blob/32cb2436/rt/rs/security/sso/saml/src/test/java/org/apache/cxf/rs/security/saml/sso/SAMLResponseValidatorTest.java
----------------------------------------------------------------------
diff --git
a/rt/rs/security/sso/saml/src/test/java/org/apache/cxf/rs/security/saml/sso/SAMLResponseValidatorTest.java
b/rt/rs/security/sso/saml/src/test/java/org/apache/cxf/rs/security/saml/sso/SAMLResponseValidatorTest.java
index d3d9107..5bb59ae 100644
---
a/rt/rs/security/sso/saml/src/test/java/org/apache/cxf/rs/security/saml/sso/SAMLResponseValidatorTest.java
+++
b/rt/rs/security/sso/saml/src/test/java/org/apache/cxf/rs/security/saml/sso/SAMLResponseValidatorTest.java
@@ -23,12 +23,15 @@ import java.io.InputStream;
import java.security.KeyStore;
import java.security.PrivateKey;
import java.security.cert.X509Certificate;
+import java.util.Collections;
+import java.util.List;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
+<<<<<<< HEAD
import org.apache.ws.security.WSSecurityException;
import org.apache.ws.security.components.crypto.Crypto;
@@ -39,7 +42,27 @@ import org.apache.ws.security.saml.ext.OpenSAMLUtil;
import org.apache.ws.security.saml.ext.SAMLParms;
import org.apache.ws.security.saml.ext.builder.SAML2Constants;
import org.apache.ws.security.util.Loader;
+=======
+import org.apache.cxf.helpers.DOMUtils;
+import org.apache.wss4j.common.crypto.Crypto;
+import org.apache.wss4j.common.crypto.CryptoType;
+import org.apache.wss4j.common.crypto.Merlin;
+import org.apache.wss4j.common.ext.WSSecurityException;
+import org.apache.wss4j.common.saml.OpenSAMLUtil;
+import org.apache.wss4j.common.saml.SAMLCallback;
+import org.apache.wss4j.common.saml.SAMLUtil;
+import org.apache.wss4j.common.saml.SamlAssertionWrapper;
+import org.apache.wss4j.common.saml.bean.AudienceRestrictionBean;
+import org.apache.wss4j.common.saml.bean.ConditionsBean;
+import org.apache.wss4j.common.saml.bean.SubjectConfirmationDataBean;
+import org.apache.wss4j.common.saml.builder.SAML2Constants;
+import org.apache.wss4j.common.util.Loader;
+import org.apache.wss4j.dom.WSSConfig;
+import org.joda.time.DateTime;
+import org.opensaml.common.SAMLVersion;
+>>>>>>> f825cb0... Adding lots of SAML SSO Negative tests
import org.opensaml.common.SignableSAMLObject;
+import org.opensaml.common.xml.SAMLConstants;
import org.opensaml.saml2.core.Response;
import org.opensaml.saml2.core.Status;
import org.opensaml.xml.security.x509.BasicX509Credential;
@@ -141,6 +164,50 @@ public class SAMLResponseValidatorTest extends
org.junit.Assert {
}
@org.junit.Test
+ public void testRequestDeniedStatusCode() throws Exception {
+ DocumentBuilderFactory docBuilderFactory =
DocumentBuilderFactory.newInstance();
+ docBuilderFactory.setNamespaceAware(true);
+ DocumentBuilder docBuilder = docBuilderFactory.newDocumentBuilder();
+ Document doc = docBuilder.newDocument();
+
+ Status status =
+ SAML2PResponseComponentBuilder.createStatus(
+ "urn:oasis:names:tc:SAML:2.0:status:RequestDenied", null
+ );
+ Response response =
+ SAML2PResponseComponentBuilder.createSAMLResponse(
+ "http://cxf.apache.org/saml", "http://cxf.apache.org/issuer",
status
+ );
+
+ // Create an AuthenticationAssertion
+ SAML2CallbackHandler callbackHandler = new SAML2CallbackHandler();
+ callbackHandler.setStatement(SAML2CallbackHandler.Statement.AUTHN);
+ callbackHandler.setIssuer("http://cxf.apache.org/issuer");
+
callbackHandler.setConfirmationMethod(SAML2Constants.CONF_SENDER_VOUCHES);
+
+ SAMLCallback samlCallback = new SAMLCallback();
+ SAMLUtil.doSAMLCallback(callbackHandler, samlCallback);
+ SamlAssertionWrapper assertion = new
SamlAssertionWrapper(samlCallback);
+
+ response.getAssertions().add(assertion.getSaml2());
+
+ Element policyElement = OpenSAMLUtil.toDom(response, doc);
+ doc.appendChild(policyElement);
+ assertNotNull(policyElement);
+
+ Response marshalledResponse =
(Response)OpenSAMLUtil.fromDom(policyElement);
+
+ // Validate the Response
+ SAMLProtocolResponseValidator validator = new
SAMLProtocolResponseValidator();
+ try {
+ validator.validateSamlResponse(marshalledResponse, null, null);
+ fail("Expected failure on an invalid SAML code");
+ } catch (WSSecurityException ex) {
+ // expected
+ }
+ }
+
+ @org.junit.Test
public void testResponseSignedAssertion() throws Exception {
DocumentBuilderFactory docBuilderFactory =
DocumentBuilderFactory.newInstance();
docBuilderFactory.setNamespaceAware(true);
@@ -199,6 +266,69 @@ public class SAMLResponseValidatorTest extends
org.junit.Assert {
}
@org.junit.Test
+ public void testResponseModifiedSignedAssertion() throws Exception {
+ DocumentBuilderFactory docBuilderFactory =
DocumentBuilderFactory.newInstance();
+ docBuilderFactory.setNamespaceAware(true);
+ DocumentBuilder docBuilder = docBuilderFactory.newDocumentBuilder();
+ Document doc = docBuilder.newDocument();
+
+ Status status =
+ SAML2PResponseComponentBuilder.createStatus(
+ SAMLProtocolResponseValidator.SAML2_STATUSCODE_SUCCESS, null
+ );
+ Response response =
+ SAML2PResponseComponentBuilder.createSAMLResponse(
+ "http://cxf.apache.org/saml", "http://cxf.apache.org/issuer",
status
+ );
+
+ // Create an AuthenticationAssertion
+ SAML2CallbackHandler callbackHandler = new SAML2CallbackHandler();
+ callbackHandler.setStatement(SAML2CallbackHandler.Statement.AUTHN);
+ callbackHandler.setIssuer("http://cxf.apache.org/issuer");
+
callbackHandler.setConfirmationMethod(SAML2Constants.CONF_SENDER_VOUCHES);
+
+ 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(SAMLResponseValidatorTest.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());
+
+ Element policyElement = OpenSAMLUtil.toDom(response, doc);
+ doc.appendChild(policyElement);
+ assertNotNull(policyElement);
+
+ List<Element> assertions =
+ DOMUtils.findAllElementsByTagNameNS(policyElement,
SAMLConstants.SAML20_NS, "Assertion");
+ assertNotNull(assertions);
+ assertTrue(assertions.size() == 1);
+ assertions.get(0).setAttributeNS(null, "newattr", "http://apache.org");
+
+ Response marshalledResponse =
(Response)OpenSAMLUtil.fromDom(policyElement);
+
+ // Validate the Response
+ SAMLProtocolResponseValidator validator = new
SAMLProtocolResponseValidator();
+ try {
+ // Validate the Response
+ validator.validateSamlResponse(
+ marshalledResponse, issuerCrypto, new
KeystorePasswordCallback()
+ );
+ fail("Expected failure on a bad signature");
+ } catch (WSSecurityException ex) {
+ // expected
+ }
+
+ }
+
+ @org.junit.Test
public void testSignedResponse() throws Exception {
DocumentBuilderFactory docBuilderFactory =
DocumentBuilderFactory.newInstance();
docBuilderFactory.setNamespaceAware(true);
@@ -255,6 +385,202 @@ public class SAMLResponseValidatorTest extends
org.junit.Assert {
);
}
+<<<<<<< HEAD
+=======
+ @org.junit.Test
+ public void testModifiedSignedResponse() throws Exception {
+ DocumentBuilderFactory docBuilderFactory =
DocumentBuilderFactory.newInstance();
+ docBuilderFactory.setNamespaceAware(true);
+ DocumentBuilder docBuilder = docBuilderFactory.newDocumentBuilder();
+ Document doc = docBuilder.newDocument();
+
+ Status status =
+ SAML2PResponseComponentBuilder.createStatus(
+ SAMLProtocolResponseValidator.SAML2_STATUSCODE_SUCCESS, null
+ );
+ Response response =
+ SAML2PResponseComponentBuilder.createSAMLResponse(
+ "http://cxf.apache.org/saml", "http://cxf.apache.org/issuer",
status
+ );
+
+ // Create an AuthenticationAssertion
+ SAML2CallbackHandler callbackHandler = new SAML2CallbackHandler();
+ callbackHandler.setStatement(SAML2CallbackHandler.Statement.AUTHN);
+ callbackHandler.setIssuer("http://cxf.apache.org/issuer");
+
callbackHandler.setConfirmationMethod(SAML2Constants.CONF_SENDER_VOUCHES);
+
+ 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(SAMLResponseValidatorTest.class);
+ InputStream input = Merlin.loadInputStream(loader, "alice.jks");
+ keyStore.load(input, "password".toCharArray());
+ ((Merlin)issuerCrypto).setKeyStore(keyStore);
+
+ response.getAssertions().add(assertion.getSaml2());
+ signResponse(response, "alice", "password", issuerCrypto, true);
+
+ Element policyElement = OpenSAMLUtil.toDom(response, doc);
+ doc.appendChild(policyElement);
+ assertNotNull(policyElement);
+
+ policyElement.setAttributeNS(null, "newattr", "http://apache.org");
+
+ Response marshalledResponse =
(Response)OpenSAMLUtil.fromDom(policyElement);
+
+ // Validate the Response
+ SAMLProtocolResponseValidator validator = new
SAMLProtocolResponseValidator();
+ try {
+ // Validate the Response
+ validator.validateSamlResponse(
+ marshalledResponse, issuerCrypto, new
KeystorePasswordCallback()
+ );
+ fail("Expected failure on a bad signature");
+ } catch (WSSecurityException ex) {
+ // expected
+ }
+ }
+
+ @org.junit.Test
+ public void testSignedResponseNoKeyInfo() throws Exception {
+ DocumentBuilderFactory docBuilderFactory =
DocumentBuilderFactory.newInstance();
+ docBuilderFactory.setNamespaceAware(true);
+ DocumentBuilder docBuilder = docBuilderFactory.newDocumentBuilder();
+ Document doc = docBuilder.newDocument();
+
+ Status status =
+ SAML2PResponseComponentBuilder.createStatus(
+ SAMLProtocolResponseValidator.SAML2_STATUSCODE_SUCCESS, null
+ );
+ Response response =
+ SAML2PResponseComponentBuilder.createSAMLResponse(
+ "http://cxf.apache.org/saml", "http://cxf.apache.org/issuer",
status
+ );
+
+ // Create an AuthenticationAssertion
+ SAML2CallbackHandler callbackHandler = new SAML2CallbackHandler();
+ callbackHandler.setStatement(SAML2CallbackHandler.Statement.AUTHN);
+ callbackHandler.setIssuer("http://cxf.apache.org/issuer");
+
callbackHandler.setConfirmationMethod(SAML2Constants.CONF_SENDER_VOUCHES);
+
+ 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(SAMLResponseValidatorTest.class);
+ InputStream input = Merlin.loadInputStream(loader, "alice.jks");
+ keyStore.load(input, "password".toCharArray());
+ ((Merlin)issuerCrypto).setKeyStore(keyStore);
+
+ response.getAssertions().add(assertion.getSaml2());
+ signResponse(response, "alice", "password", issuerCrypto, false);
+
+ Element policyElement = OpenSAMLUtil.toDom(response, doc);
+ doc.appendChild(policyElement);
+ assertNotNull(policyElement);
+
+ Response marshalledResponse =
(Response)OpenSAMLUtil.fromDom(policyElement);
+
+ // Validate the Response
+ SAMLProtocolResponseValidator validator = new
SAMLProtocolResponseValidator();
+ validator.setKeyInfoMustBeAvailable(false);
+ try {
+ validator.validateSamlResponse(marshalledResponse, null, new
KeystorePasswordCallback());
+ fail("Expected failure on no Signature Crypto");
+ } catch (WSSecurityException ex) {
+ // expected
+ }
+
+ // Validate the Response
+ validator.validateSamlResponse(
+ marshalledResponse, issuerCrypto, new KeystorePasswordCallback()
+ );
+ }
+
+ @org.junit.Test
+ public void testResponseInvalidVersion() throws Exception {
+ SubjectConfirmationDataBean subjectConfirmationData = new
SubjectConfirmationDataBean();
+ subjectConfirmationData.setAddress("http://apache.org");
+ subjectConfirmationData.setInResponseTo("12345");
+ subjectConfirmationData.setNotAfter(new DateTime().plusMinutes(5));
+ subjectConfirmationData.setRecipient("http://recipient.apache.org");
+
+ // Create a AuthenticationAssertion
+ SAML2CallbackHandler callbackHandler = new SAML2CallbackHandler();
+ callbackHandler.setStatement(SAML2CallbackHandler.Statement.AUTHN);
+ callbackHandler.setIssuer("http://cxf.apache.org/issuer");
+
callbackHandler.setConfirmationMethod(SAML2Constants.CONF_SENDER_VOUCHES);
+
+ 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);
+
+ Response response = createResponse(subjectConfirmationData,
callbackHandler);
+ response.setVersion(SAMLVersion.VERSION_10);
+
+ // Validate the Response
+ SAMLProtocolResponseValidator protocolValidator = new
SAMLProtocolResponseValidator();
+
+ try {
+ protocolValidator.validateSamlResponse(response, null, null);
+ fail("Expected failure on bad response");
+ } catch (WSSecurityException ex) {
+ // expected
+ }
+ }
+
+ @org.junit.Test
+ public void testAssertionBadSubjectConfirmationMethod() throws Exception {
+ SubjectConfirmationDataBean subjectConfirmationData = new
SubjectConfirmationDataBean();
+ subjectConfirmationData.setAddress("http://apache.org");
+ subjectConfirmationData.setInResponseTo("12345");
+ subjectConfirmationData.setNotAfter(new DateTime().plusMinutes(5));
+ subjectConfirmationData.setRecipient("http://recipient.apache.org");
+
+ // Create a AuthenticationAssertion
+ SAML2CallbackHandler callbackHandler = new SAML2CallbackHandler();
+ callbackHandler.setStatement(SAML2CallbackHandler.Statement.AUTHN);
+ callbackHandler.setIssuer("http://cxf.apache.org/issuer");
+ callbackHandler.setConfirmationMethod("xyz");
+
+ 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);
+
+ Response response = createResponse(subjectConfirmationData,
callbackHandler);
+
+ // Validate the Response
+ SAMLProtocolResponseValidator protocolValidator = new
SAMLProtocolResponseValidator();
+
+ try {
+ protocolValidator.validateSamlResponse(response, null, null);
+ fail("Expected failure on bad response");
+ } catch (WSSecurityException ex) {
+ // expected
+ }
+ }
+
+
+>>>>>>> f825cb0... Adding lots of SAML SSO Negative tests
/**
* Sign a SAML Response
*/
@@ -320,4 +646,35 @@ public class SAMLResponseValidatorTest extends
org.junit.Assert {
signableObject.releaseChildrenDOM(true);
}
+ private Response createResponse(
+ SubjectConfirmationDataBean subjectConfirmationData,
+ SAML2CallbackHandler callbackHandler
+ ) throws Exception {
+ DocumentBuilderFactory docBuilderFactory =
DocumentBuilderFactory.newInstance();
+ docBuilderFactory.setNamespaceAware(true);
+ DocumentBuilder docBuilder = docBuilderFactory.newDocumentBuilder();
+ Document doc = docBuilder.newDocument();
+
+ Status status =
+ SAML2PResponseComponentBuilder.createStatus(
+ SAMLProtocolResponseValidator.SAML2_STATUSCODE_SUCCESS, null
+ );
+ Response response =
+ SAML2PResponseComponentBuilder.createSAMLResponse(
+ "http://cxf.apache.org/saml", "http://cxf.apache.org/issuer",
status
+ );
+
+ // Create an AuthenticationAssertion
+ SAMLCallback samlCallback = new SAMLCallback();
+ SAMLUtil.doSAMLCallback(callbackHandler, samlCallback);
+ SamlAssertionWrapper assertion = new
SamlAssertionWrapper(samlCallback);
+
+ response.getAssertions().add(assertion.getSaml2());
+
+ Element policyElement = OpenSAMLUtil.toDom(response, doc);
+ doc.appendChild(policyElement);
+ assertNotNull(policyElement);
+
+ return (Response)OpenSAMLUtil.fromDom(policyElement);
+ }
}
http://git-wip-us.apache.org/repos/asf/cxf/blob/32cb2436/rt/rs/security/sso/saml/src/test/java/org/apache/cxf/rs/security/saml/sso/SAMLSSOResponseValidatorTest.java
----------------------------------------------------------------------
diff --git
a/rt/rs/security/sso/saml/src/test/java/org/apache/cxf/rs/security/saml/sso/SAMLSSOResponseValidatorTest.java
b/rt/rs/security/sso/saml/src/test/java/org/apache/cxf/rs/security/saml/sso/SAMLSSOResponseValidatorTest.java
index 75102ed..cc57c49 100644
---
a/rt/rs/security/sso/saml/src/test/java/org/apache/cxf/rs/security/saml/sso/SAMLSSOResponseValidatorTest.java
+++
b/rt/rs/security/sso/saml/src/test/java/org/apache/cxf/rs/security/saml/sso/SAMLSSOResponseValidatorTest.java
@@ -19,11 +19,23 @@
package org.apache.cxf.rs.security.saml.sso;
+<<<<<<< HEAD
+=======
+import java.io.InputStream;
+import java.security.KeyStore;
+import java.security.PrivateKey;
+import java.security.cert.X509Certificate;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+>>>>>>> f825cb0... Adding lots of SAML SSO Negative tests
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
+<<<<<<< HEAD
import org.apache.ws.security.WSSecurityException;
import org.apache.ws.security.saml.ext.AssertionWrapper;
@@ -32,9 +44,31 @@ import org.apache.ws.security.saml.ext.SAMLParms;
import org.apache.ws.security.saml.ext.bean.ConditionsBean;
import org.apache.ws.security.saml.ext.bean.SubjectConfirmationDataBean;
import org.apache.ws.security.saml.ext.builder.SAML2Constants;
+=======
+import org.apache.wss4j.common.crypto.Crypto;
+import org.apache.wss4j.common.crypto.CryptoType;
+import org.apache.wss4j.common.crypto.Merlin;
+import org.apache.wss4j.common.ext.WSSecurityException;
+import org.apache.wss4j.common.saml.OpenSAMLUtil;
+import org.apache.wss4j.common.saml.SAMLCallback;
+import org.apache.wss4j.common.saml.SAMLUtil;
+import org.apache.wss4j.common.saml.SamlAssertionWrapper;
+import org.apache.wss4j.common.saml.bean.AudienceRestrictionBean;
+import org.apache.wss4j.common.saml.bean.ConditionsBean;
+import org.apache.wss4j.common.saml.bean.SubjectConfirmationDataBean;
+import org.apache.wss4j.common.saml.builder.SAML2Constants;
+import org.apache.wss4j.common.util.Loader;
+>>>>>>> f825cb0... Adding lots of SAML SSO Negative tests
import org.joda.time.DateTime;
+import org.opensaml.common.SignableSAMLObject;
+import org.opensaml.saml2.core.AuthnStatement;
import org.opensaml.saml2.core.Response;
import org.opensaml.saml2.core.Status;
+import org.opensaml.xml.security.x509.BasicX509Credential;
+import org.opensaml.xml.security.x509.X509KeyInfoGeneratorFactory;
+import org.opensaml.xml.signature.KeyInfo;
+import org.opensaml.xml.signature.Signature;
+import org.opensaml.xml.signature.SignatureConstants;
/**
* Some unit tests for the SAMLSSOResponseValidator.
@@ -191,9 +225,8 @@ public class SAMLSSOResponseValidatorTest extends
org.junit.Assert {
}
}
- private Response createResponse(
- SubjectConfirmationDataBean subjectConfirmationData
- ) throws Exception {
+ @org.junit.Test
+ public void testSignedResponseInvalidDestination() throws Exception {
DocumentBuilderFactory docBuilderFactory =
DocumentBuilderFactory.newInstance();
docBuilderFactory.setNamespaceAware(true);
DocumentBuilder docBuilder = docBuilderFactory.newDocumentBuilder();
@@ -214,6 +247,268 @@ public class SAMLSSOResponseValidatorTest extends
org.junit.Assert {
callbackHandler.setIssuer("http://cxf.apache.org/issuer");
callbackHandler.setConfirmationMethod(SAML2Constants.CONF_BEARER);
+ 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);
+
+ 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);
+
+ SAMLCallback samlCallback = new SAMLCallback();
+ SAMLUtil.doSAMLCallback(callbackHandler, samlCallback);
+ SamlAssertionWrapper assertion = new
SamlAssertionWrapper(samlCallback);
+
+ response.getAssertions().add(assertion.getSaml2());
+ response.setDestination("xyz");
+
+ Crypto issuerCrypto = new Merlin();
+ KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
+ ClassLoader loader =
Loader.getClassLoader(SAMLResponseValidatorTest.class);
+ InputStream input = Merlin.loadInputStream(loader, "alice.jks");
+ keyStore.load(input, "password".toCharArray());
+ ((Merlin)issuerCrypto).setKeyStore(keyStore);
+
+ signResponse(response, "alice", "password", issuerCrypto, true);
+
+ Element policyElement = OpenSAMLUtil.toDom(response, doc);
+ doc.appendChild(policyElement);
+ assertNotNull(policyElement);
+
+ Response marshalledResponse =
(Response)OpenSAMLUtil.fromDom(policyElement);
+
+ // Validate the Response
+ SAMLSSOResponseValidator validator = new SAMLSSOResponseValidator();
+ validator.setIssuerIDP("http://cxf.apache.org/issuer");
+ validator.setAssertionConsumerURL("http://recipient.apache.org");
+ validator.setClientAddress("http://apache.org");
+ validator.setRequestId("12345");
+ validator.setSpIdentifier("http://service.apache.org");
+ try {
+ validator.validateSamlResponse(marshalledResponse, false);
+ fail("Expected failure on bad response");
+ } catch (WSSecurityException ex) {
+ // expected
+ }
+ }
+
+ @org.junit.Test
+ public void testResponseInvalidIssuer() throws Exception {
+ SubjectConfirmationDataBean subjectConfirmationData = new
SubjectConfirmationDataBean();
+ subjectConfirmationData.setAddress("http://apache.org");
+ subjectConfirmationData.setInResponseTo("12345");
+ subjectConfirmationData.setNotAfter(new DateTime().plusMinutes(5));
+ subjectConfirmationData.setRecipient("http://recipient.apache.org");
+
+ Response response = createResponse(subjectConfirmationData);
+ response.setIssuer(SAML2PResponseComponentBuilder.createIssuer("xyz"));
+
+ // Validate the Response
+ SAMLSSOResponseValidator validator = new SAMLSSOResponseValidator();
+ validator.setIssuerIDP("http://cxf.apache.org/issuer");
+ validator.setAssertionConsumerURL("http://recipient.apache.org");
+ validator.setClientAddress("http://apache.org");
+ validator.setRequestId("12345");
+ validator.setSpIdentifier("http://service.apache.org");
+ try {
+ validator.validateSamlResponse(response, false);
+ fail("Expected failure on bad response");
+ } catch (WSSecurityException ex) {
+ // expected
+ }
+ }
+
+ @org.junit.Test
+ public void testMissingAuthnStatement() throws Exception {
+ SubjectConfirmationDataBean subjectConfirmationData = new
SubjectConfirmationDataBean();
+ subjectConfirmationData.setAddress("http://apache.org");
+ subjectConfirmationData.setInResponseTo("12345");
+ subjectConfirmationData.setNotAfter(new DateTime().plusMinutes(5));
+ subjectConfirmationData.setRecipient("http://recipient.apache.org");
+
+ Response response = createResponse(subjectConfirmationData);
+ response.getAssertions().get(0).getAuthnStatements().clear();
+
+ // Validate the Response
+ SAMLSSOResponseValidator validator = new SAMLSSOResponseValidator();
+ validator.setIssuerIDP("http://cxf.apache.org/issuer");
+ validator.setAssertionConsumerURL("http://recipient.apache.org");
+ validator.setClientAddress("http://apache.org");
+ validator.setRequestId("12345");
+ validator.setSpIdentifier("http://service.apache.org");
+ try {
+ validator.validateSamlResponse(response, false);
+ fail("Expected failure on bad response");
+ } catch (WSSecurityException ex) {
+ // expected
+ }
+ }
+
+ @org.junit.Test
+ public void testNoSubjectConfirmationData() throws Exception {
+ Response response = createResponse(null);
+
+ // Validate the Response
+ SAMLSSOResponseValidator validator = new SAMLSSOResponseValidator();
+ validator.setIssuerIDP("http://cxf.apache.org/issuer");
+ validator.setAssertionConsumerURL("http://recipient.apache.org");
+ validator.setClientAddress("http://apache.org");
+ validator.setRequestId("12345");
+ validator.setSpIdentifier("http://service.apache.org");
+ try {
+ validator.validateSamlResponse(response, false);
+ fail("Expected failure on bad response");
+ } catch (WSSecurityException ex) {
+ // expected
+ }
+ }
+
+ @org.junit.Test
+ public void testEmptyAudienceRestriction() throws Exception {
+ SubjectConfirmationDataBean subjectConfirmationData = new
SubjectConfirmationDataBean();
+ subjectConfirmationData.setAddress("http://apache.org");
+ subjectConfirmationData.setInResponseTo("12345");
+ subjectConfirmationData.setNotAfter(new DateTime().plusMinutes(5));
+ subjectConfirmationData.setRecipient("http://recipient.apache.org");
+
+ AudienceRestrictionBean audienceRestriction = new
AudienceRestrictionBean();
+ Response response =
+ createResponse(subjectConfirmationData,
+ Collections.singletonList(audienceRestriction),
+ null);
+
+ // Validate the Response
+ SAMLSSOResponseValidator validator = new SAMLSSOResponseValidator();
+ validator.setIssuerIDP("http://cxf.apache.org/issuer");
+ validator.setAssertionConsumerURL("http://recipient.apache.org");
+ validator.setClientAddress("http://apache.org");
+ validator.setRequestId("12345");
+ validator.setSpIdentifier("http://service.apache.org");
+ try {
+ validator.validateSamlResponse(response, false);
+ fail("Expected failure on bad response");
+ } catch (WSSecurityException ex) {
+ // expected
+ }
+ }
+
+ @org.junit.Test
+ public void testBadAudienceRestriction() throws Exception {
+ SubjectConfirmationDataBean subjectConfirmationData = new
SubjectConfirmationDataBean();
+ subjectConfirmationData.setAddress("http://apache.org");
+ subjectConfirmationData.setInResponseTo("12345");
+ subjectConfirmationData.setNotAfter(new DateTime().plusMinutes(5));
+ subjectConfirmationData.setRecipient("http://recipient.apache.org");
+
+ AudienceRestrictionBean audienceRestriction = new
AudienceRestrictionBean();
+ audienceRestriction.setAudienceURIs(
+ Collections.singletonList("http://unknown-service.apache.org"));
+ Response response =
+ createResponse(subjectConfirmationData,
+ Collections.singletonList(audienceRestriction),
+ null);
+
+ // Validate the Response
+ SAMLSSOResponseValidator validator = new SAMLSSOResponseValidator();
+ validator.setIssuerIDP("http://cxf.apache.org/issuer");
+ validator.setAssertionConsumerURL("http://recipient.apache.org");
+ validator.setClientAddress("http://apache.org");
+ validator.setRequestId("12345");
+ validator.setSpIdentifier("http://service.apache.org");
+ try {
+ validator.validateSamlResponse(response, false);
+ fail("Expected failure on bad response");
+ } catch (WSSecurityException ex) {
+ // expected
+ }
+ }
+
+ @org.junit.Test
+ public void testAudienceRestrictionMultipleValues() throws Exception {
+ SubjectConfirmationDataBean subjectConfirmationData = new
SubjectConfirmationDataBean();
+ subjectConfirmationData.setAddress("http://apache.org");
+ subjectConfirmationData.setInResponseTo("12345");
+ subjectConfirmationData.setNotAfter(new DateTime().plusMinutes(5));
+ subjectConfirmationData.setRecipient("http://recipient.apache.org");
+
+ List<String> values = new ArrayList<String>();
+ values.add("http://unknown-service.apache.org");
+ values.add("http://service.apache.org");
+
+ AudienceRestrictionBean audienceRestriction = new
AudienceRestrictionBean();
+ audienceRestriction.setAudienceURIs(values);
+ Response response =
+ createResponse(subjectConfirmationData,
+ Collections.singletonList(audienceRestriction),
+ null);
+
+ // Validate the Response
+ SAMLSSOResponseValidator validator = new SAMLSSOResponseValidator();
+ validator.setIssuerIDP("http://cxf.apache.org/issuer");
+ validator.setAssertionConsumerURL("http://recipient.apache.org");
+ validator.setClientAddress("http://apache.org");
+ validator.setRequestId("12345");
+ validator.setSpIdentifier("http://service.apache.org");
+
+ validator.validateSamlResponse(response, false);
+ }
+
+ @org.junit.Test
+ public void testMultipleAudienceRestrictions() throws Exception {
+ SubjectConfirmationDataBean subjectConfirmationData = new
SubjectConfirmationDataBean();
+ subjectConfirmationData.setAddress("http://apache.org");
+ subjectConfirmationData.setInResponseTo("12345");
+ subjectConfirmationData.setNotAfter(new DateTime().plusMinutes(5));
+ subjectConfirmationData.setRecipient("http://recipient.apache.org");
+
+ List<AudienceRestrictionBean> audienceRestrictions =
+ new ArrayList<AudienceRestrictionBean>();
+
+ AudienceRestrictionBean audienceRestriction = new
AudienceRestrictionBean();
+ audienceRestriction.setAudienceURIs(
+ Collections.singletonList("http://unknown-service.apache.org"));
+ audienceRestrictions.add(audienceRestriction);
+
+ audienceRestriction = new AudienceRestrictionBean();
+ audienceRestriction.setAudienceURIs(
+ Collections.singletonList("http://service.apache.org"));
+ audienceRestrictions.add(audienceRestriction);
+
+ Response response =
+ createResponse(subjectConfirmationData, audienceRestrictions,
null);
+
+ // Validate the Response
+ SAMLSSOResponseValidator validator = new SAMLSSOResponseValidator();
+ validator.setIssuerIDP("http://cxf.apache.org/issuer");
+ validator.setAssertionConsumerURL("http://recipient.apache.org");
+ validator.setClientAddress("http://apache.org");
+ validator.setRequestId("12345");
+ validator.setSpIdentifier("http://service.apache.org");
+
+ validator.validateSamlResponse(response, false);
+ }
+
+ @org.junit.Test
+ public void testAssertionBadIssuer() throws Exception {
+ SubjectConfirmationDataBean subjectConfirmationData = new
SubjectConfirmationDataBean();
+ subjectConfirmationData.setAddress("http://apache.org");
+ subjectConfirmationData.setInResponseTo("12345");
+ subjectConfirmationData.setNotAfter(new DateTime().plusMinutes(5));
+ subjectConfirmationData.setRecipient("http://recipient.apache.org");
+
+ // Create a AuthenticationAssertion
+ SAML2CallbackHandler callbackHandler = new SAML2CallbackHandler();
+ callbackHandler.setStatement(SAML2CallbackHandler.Statement.AUTHN);
+ callbackHandler.setIssuer("http://cxf.apache.org/bad-issuer");
+ callbackHandler.setConfirmationMethod(SAML2Constants.CONF_BEARER);
+
callbackHandler.setSubjectConfirmationData(subjectConfirmationData);
ConditionsBean conditions = new ConditionsBean();
@@ -222,17 +517,189 @@ public class SAMLSSOResponseValidatorTest extends
org.junit.Assert {
conditions.setAudienceURI("http://service.apache.org");
callbackHandler.setConditions(conditions);
+<<<<<<< HEAD
SAMLParms samlParms = new SAMLParms();
samlParms.setCallbackHandler(callbackHandler);
AssertionWrapper assertion = new AssertionWrapper(samlParms);
+=======
+ Response response = createResponse(subjectConfirmationData,
callbackHandler);
+
+ // Validate the Response
+ SAMLSSOResponseValidator validator = new SAMLSSOResponseValidator();
+ validator.setIssuerIDP("http://cxf.apache.org/issuer");
+ validator.setAssertionConsumerURL("http://recipient.apache.org");
+ validator.setClientAddress("http://apache.org");
+ validator.setRequestId("12345");
+ validator.setSpIdentifier("http://service.apache.org");
+
+ try {
+ validator.validateSamlResponse(response, false);
+ fail("Expected failure on bad response");
+ } catch (WSSecurityException ex) {
+ // expected
+ }
+ }
+
+ private Response createResponse(
+ SubjectConfirmationDataBean subjectConfirmationData
+ ) throws Exception {
+ return createResponse(subjectConfirmationData, null, null);
+ }
+
+ private Response createResponse(
+ SubjectConfirmationDataBean subjectConfirmationData,
+ List<AudienceRestrictionBean> audienceRestrictions,
+ String authnClassRef
+ ) throws Exception {
+ DocumentBuilderFactory docBuilderFactory =
DocumentBuilderFactory.newInstance();
+ docBuilderFactory.setNamespaceAware(true);
+ DocumentBuilder docBuilder = docBuilderFactory.newDocumentBuilder();
+ Document doc = docBuilder.newDocument();
+
+ Status status =
+ SAML2PResponseComponentBuilder.createStatus(
+ SAMLProtocolResponseValidator.SAML2_STATUSCODE_SUCCESS, null
+ );
+ Response response =
+ SAML2PResponseComponentBuilder.createSAMLResponse(
+ "http://cxf.apache.org/saml", "http://cxf.apache.org/issuer",
status
+ );
+
+ // 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.setSubjectConfirmationData(subjectConfirmationData);
+
+ ConditionsBean conditions = new ConditionsBean();
+ conditions.setNotBefore(new DateTime());
+ conditions.setNotAfter(new DateTime().plusMinutes(5));
+
+ if (audienceRestrictions == null) {
+ AudienceRestrictionBean audienceRestriction = new
AudienceRestrictionBean();
+
audienceRestriction.setAudienceURIs(Collections.singletonList("http://service.apache.org"));
+
conditions.setAudienceRestrictions(Collections.singletonList(audienceRestriction));
+ } else {
+ conditions.setAudienceRestrictions(audienceRestrictions);
+ }
+ callbackHandler.setConditions(conditions);
+
+ SAMLCallback samlCallback = new SAMLCallback();
+ SAMLUtil.doSAMLCallback(callbackHandler, samlCallback);
+ SamlAssertionWrapper assertion = new
SamlAssertionWrapper(samlCallback);
+>>>>>>> f825cb0... Adding lots of SAML SSO Negative tests
response.getAssertions().add(assertion.getSaml2());
+ if (authnClassRef != null) {
+ AuthnStatement authnStatement =
+ response.getAssertions().get(0).getAuthnStatements().get(0);
+ authnStatement.getAuthnContext().setAuthnContextClassRef(
+
SAML2PResponseComponentBuilder.createAuthnContextClassRef(authnClassRef));
+ }
+
Element policyElement = OpenSAMLUtil.toDom(response, doc);
doc.appendChild(policyElement);
assertNotNull(policyElement);
return (Response)OpenSAMLUtil.fromDom(policyElement);
}
+
+ private Response createResponse(
+ SubjectConfirmationDataBean subjectConfirmationData,
+ SAML2CallbackHandler callbackHandler
+ ) throws Exception {
+ DocumentBuilderFactory docBuilderFactory =
DocumentBuilderFactory.newInstance();
+ docBuilderFactory.setNamespaceAware(true);
+ DocumentBuilder docBuilder = docBuilderFactory.newDocumentBuilder();
+ Document doc = docBuilder.newDocument();
+
+ Status status =
+ SAML2PResponseComponentBuilder.createStatus(
+ SAMLProtocolResponseValidator.SAML2_STATUSCODE_SUCCESS, null
+ );
+ Response response =
+ SAML2PResponseComponentBuilder.createSAMLResponse(
+ "http://cxf.apache.org/saml", "http://cxf.apache.org/issuer",
status
+ );
+
+ // Create an AuthenticationAssertion
+ SAMLCallback samlCallback = new SAMLCallback();
+ SAMLUtil.doSAMLCallback(callbackHandler, samlCallback);
+ SamlAssertionWrapper assertion = new
SamlAssertionWrapper(samlCallback);
+
+ response.getAssertions().add(assertion.getSaml2());
+
+ Element policyElement = OpenSAMLUtil.toDom(response, doc);
+ doc.appendChild(policyElement);
+ assertNotNull(policyElement);
+
+ return (Response)OpenSAMLUtil.fromDom(policyElement);
+ }
+ /**
+ * Sign a SAML Response
+ * @throws Exception
+ */
+ private void signResponse(
+ Response response,
+ String issuerKeyName,
+ String issuerKeyPassword,
+ Crypto issuerCrypto,
+ boolean useKeyInfo
+ ) throws Exception {
+ //
+ // Create the signature
+ //
+ Signature signature = OpenSAMLUtil.buildSignature();
+
signature.setCanonicalizationAlgorithm(SignatureConstants.ALGO_ID_C14N_EXCL_OMIT_COMMENTS);
+
+ // prepare to sign the SAML token
+ CryptoType cryptoType = new CryptoType(CryptoType.TYPE.ALIAS);
+ cryptoType.setAlias(issuerKeyName);
+ X509Certificate[] issuerCerts =
issuerCrypto.getX509Certificates(cryptoType);
+ if (issuerCerts == null) {
+ throw new Exception(
+ "No issuer certs were found to sign the SAML Assertion
using issuer name: "
+ + issuerKeyName);
+ }
+
+ String sigAlgo = SignatureConstants.ALGO_ID_SIGNATURE_RSA_SHA1;
+ String pubKeyAlgo = issuerCerts[0].getPublicKey().getAlgorithm();
+
+ if (pubKeyAlgo.equalsIgnoreCase("DSA")) {
+ sigAlgo = SignatureConstants.ALGO_ID_SIGNATURE_DSA;
+ }
+
+ PrivateKey privateKey = issuerCrypto.getPrivateKey(issuerKeyName,
issuerKeyPassword);
+
+ signature.setSignatureAlgorithm(sigAlgo);
+
+ BasicX509Credential signingCredential = new BasicX509Credential();
+ signingCredential.setEntityCertificate(issuerCerts[0]);
+ signingCredential.setPrivateKey(privateKey);
+
+ signature.setSigningCredential(signingCredential);
+
+ if (useKeyInfo) {
+ X509KeyInfoGeneratorFactory kiFactory = new
X509KeyInfoGeneratorFactory();
+ kiFactory.setEmitEntityCertificate(true);
+
+ try {
+ KeyInfo keyInfo =
kiFactory.newInstance().generate(signingCredential);
+ signature.setKeyInfo(keyInfo);
+ } catch (org.opensaml.xml.security.SecurityException ex) {
+ throw new Exception(
+ "Error generating KeyInfo from signing credential",
ex);
+ }
+ }
+
+ // add the signature to the assertion
+ SignableSAMLObject signableObject = (SignableSAMLObject) response;
+ signableObject.setSignature(signature);
+ signableObject.releaseDOM();
+ signableObject.releaseChildrenDOM(true);
+ }
}