You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cxf.apache.org by co...@apache.org on 2014/07/25 14:30:24 UTC
git commit: Added some more unit tests for SAML SSO
Repository: cxf-fediz
Updated Branches:
refs/heads/master 0f3a5b4f7 -> 1cb119ea7
Added some more unit tests for SAML SSO
Project: http://git-wip-us.apache.org/repos/asf/cxf-fediz/repo
Commit: http://git-wip-us.apache.org/repos/asf/cxf-fediz/commit/1cb119ea
Tree: http://git-wip-us.apache.org/repos/asf/cxf-fediz/tree/1cb119ea
Diff: http://git-wip-us.apache.org/repos/asf/cxf-fediz/diff/1cb119ea
Branch: refs/heads/master
Commit: 1cb119ea7bda75240a05127573662f0c3a9f834d
Parents: 0f3a5b4
Author: Colm O hEigeartaigh <co...@apache.org>
Authored: Fri Jul 25 13:18:16 2014 +0100
Committer: Colm O hEigeartaigh <co...@apache.org>
Committed: Fri Jul 25 13:18:16 2014 +0100
----------------------------------------------------------------------
.../core/samlsso/SAMLSSOResponseValidator.java | 5 +-
.../samlsso/SAML2PResponseComponentBuilder.java | 28 +-
.../samlsso/SAMLResponseConformanceTest.java | 1084 ++++++++++++++++++
3 files changed, 1114 insertions(+), 3 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/cxf-fediz/blob/1cb119ea/plugins/core/src/main/java/org/apache/cxf/fediz/core/samlsso/SAMLSSOResponseValidator.java
----------------------------------------------------------------------
diff --git a/plugins/core/src/main/java/org/apache/cxf/fediz/core/samlsso/SAMLSSOResponseValidator.java b/plugins/core/src/main/java/org/apache/cxf/fediz/core/samlsso/SAMLSSOResponseValidator.java
index 4d75027..92cf01d 100644
--- a/plugins/core/src/main/java/org/apache/cxf/fediz/core/samlsso/SAMLSSOResponseValidator.java
+++ b/plugins/core/src/main/java/org/apache/cxf/fediz/core/samlsso/SAMLSSOResponseValidator.java
@@ -176,15 +176,18 @@ public class SAMLSSOResponseValidator {
if (subject.getSubjectConfirmations() == null) {
return false;
}
+
+ boolean foundBearerSubjectConf = false;
// We need to find a Bearer Subject Confirmation method
for (org.opensaml.saml2.core.SubjectConfirmation subjectConf
: subject.getSubjectConfirmations()) {
if (SAML2Constants.CONF_BEARER.equals(subjectConf.getMethod())) {
+ foundBearerSubjectConf = true;
validateSubjectConfirmation(subjectConf.getSubjectConfirmationData(), id, postBinding);
}
}
- return true;
+ return foundBearerSubjectConf;
}
/**
http://git-wip-us.apache.org/repos/asf/cxf-fediz/blob/1cb119ea/plugins/core/src/test/java/org/apache/cxf/fediz/core/samlsso/SAML2PResponseComponentBuilder.java
----------------------------------------------------------------------
diff --git a/plugins/core/src/test/java/org/apache/cxf/fediz/core/samlsso/SAML2PResponseComponentBuilder.java b/plugins/core/src/test/java/org/apache/cxf/fediz/core/samlsso/SAML2PResponseComponentBuilder.java
index ffaade7..29f03d2 100644
--- a/plugins/core/src/test/java/org/apache/cxf/fediz/core/samlsso/SAML2PResponseComponentBuilder.java
+++ b/plugins/core/src/test/java/org/apache/cxf/fediz/core/samlsso/SAML2PResponseComponentBuilder.java
@@ -53,12 +53,20 @@ public final class SAML2PResponseComponentBuilder {
}
- @SuppressWarnings("unchecked")
public static Response createSAMLResponse(
String inResponseTo,
String issuer,
Status status
) {
+ return createSAMLResponse(inResponseTo, createIssuer(issuer), status);
+ }
+
+ @SuppressWarnings("unchecked")
+ public static Response createSAMLResponse(
+ String inResponseTo,
+ Issuer issuer,
+ Status status
+ ) {
if (responseBuilder == null) {
responseBuilder = (SAMLObjectBuilder<Response>)
builderFactory.getBuilder(Response.DEFAULT_ELEMENT_NAME);
@@ -68,7 +76,7 @@ public final class SAML2PResponseComponentBuilder {
response.setID(UUID.randomUUID().toString());
response.setIssueInstant(new DateTime());
response.setInResponseTo(inResponseTo);
- response.setIssuer(createIssuer(issuer));
+ response.setIssuer(issuer);
response.setStatus(status);
response.setVersion(SAMLVersion.VERSION_20);
@@ -90,6 +98,22 @@ public final class SAML2PResponseComponentBuilder {
}
@SuppressWarnings("unchecked")
+ public static Issuer createIssuer(
+ String issuerValue,
+ String issuerFormat
+ ) {
+ if (issuerBuilder == null) {
+ issuerBuilder = (SAMLObjectBuilder<Issuer>)
+ builderFactory.getBuilder(Issuer.DEFAULT_ELEMENT_NAME);
+ }
+ Issuer issuer = issuerBuilder.buildObject();
+ issuer.setValue(issuerValue);
+ issuer.setFormat(issuerFormat);
+
+ return issuer;
+ }
+
+ @SuppressWarnings("unchecked")
public static Status createStatus(
String statusCodeValue,
String statusMessage
http://git-wip-us.apache.org/repos/asf/cxf-fediz/blob/1cb119ea/plugins/core/src/test/java/org/apache/cxf/fediz/core/samlsso/SAMLResponseConformanceTest.java
----------------------------------------------------------------------
diff --git a/plugins/core/src/test/java/org/apache/cxf/fediz/core/samlsso/SAMLResponseConformanceTest.java b/plugins/core/src/test/java/org/apache/cxf/fediz/core/samlsso/SAMLResponseConformanceTest.java
new file mode 100644
index 0000000..f1028c3
--- /dev/null
+++ b/plugins/core/src/test/java/org/apache/cxf/fediz/core/samlsso/SAMLResponseConformanceTest.java
@@ -0,0 +1,1084 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.cxf.fediz.core.samlsso;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.URL;
+import java.net.URLEncoder;
+import java.util.Collections;
+import java.util.UUID;
+
+import javax.security.auth.callback.CallbackHandler;
+import javax.security.auth.callback.UnsupportedCallbackException;
+import javax.servlet.http.HttpServletRequest;
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.apache.cxf.fediz.common.SecurityTestUtil;
+import org.apache.cxf.fediz.core.KeystoreCallbackHandler;
+import org.apache.cxf.fediz.core.SAML2CallbackHandler;
+import org.apache.cxf.fediz.core.config.FedizConfigurator;
+import org.apache.cxf.fediz.core.config.FedizContext;
+import org.apache.cxf.fediz.core.config.SAMLProtocol;
+import org.apache.cxf.fediz.core.exception.ProcessingException;
+import org.apache.cxf.fediz.core.exception.ProcessingException.TYPE;
+import org.apache.cxf.fediz.core.processor.FedizProcessor;
+import org.apache.cxf.fediz.core.processor.FedizRequest;
+import org.apache.cxf.fediz.core.processor.FedizResponse;
+import org.apache.cxf.fediz.core.processor.SAMLProcessorImpl;
+import org.apache.wss4j.common.crypto.Crypto;
+import org.apache.wss4j.common.crypto.CryptoFactory;
+import org.apache.wss4j.common.ext.WSPasswordCallback;
+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.DOM2Writer;
+import org.apache.xml.security.utils.Base64;
+import org.easymock.EasyMock;
+import org.joda.time.DateTime;
+import org.junit.AfterClass;
+import org.junit.Assert;
+import org.junit.BeforeClass;
+import org.opensaml.saml2.core.Issuer;
+import org.opensaml.saml2.core.Response;
+import org.opensaml.saml2.core.Status;
+
+import static org.junit.Assert.fail;
+
+/**
+ * Some tests for processing SAMLResponses using the SAMLProcessorImpl, where the SAML Response
+ * fails some requirement in the Web SSO profile spec.
+ */
+public class SAMLResponseConformanceTest {
+ static final String TEST_USER = "alice";
+ static final String TEST_REQUEST_URL = "https://localhost/fedizhelloworld/";
+ static final String TEST_REQUEST_URI = "/fedizhelloworld";
+ static final String TEST_IDP_ISSUER = "http://url_to_the_issuer";
+ static final String TEST_CLIENT_ADDRESS = "https://127.0.0.1";
+
+ private static final String CONFIG_FILE = "fediz_test_config_saml.xml";
+
+ private static Crypto crypto;
+ private static CallbackHandler cbPasswordHandler;
+ private static FedizConfigurator configurator;
+ private static DocumentBuilderFactory docBuilderFactory;
+
+ static {
+ docBuilderFactory = DocumentBuilderFactory.newInstance();
+ docBuilderFactory.setNamespaceAware(true);
+ }
+
+
+ @BeforeClass
+ public static void init() {
+ try {
+ crypto = CryptoFactory.getInstance("signature.properties");
+ cbPasswordHandler = new KeystoreCallbackHandler();
+ getFederationConfigurator();
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ Assert.assertNotNull(configurator);
+
+ }
+
+ @AfterClass
+ public static void cleanup() {
+ SecurityTestUtil.cleanup();
+ }
+
+
+ private static FedizConfigurator getFederationConfigurator() {
+ if (configurator != null) {
+ return configurator;
+ }
+ try {
+ configurator = new FedizConfigurator();
+ final URL resource = Thread.currentThread().getContextClassLoader()
+ .getResource(CONFIG_FILE);
+ File f = new File(resource.toURI());
+ configurator.loadConfig(f);
+ return configurator;
+ } catch (Exception e) {
+ e.printStackTrace();
+ return null;
+ }
+ }
+
+ @org.junit.Test
+ public void testWrongIssuerFormat() throws Exception {
+ // Mock up a Request
+ FedizContext config = getFederationConfigurator().getFedizContext("ROOT");
+
+ String requestId = URLEncoder.encode(UUID.randomUUID().toString(), "UTF-8");
+
+ RequestState requestState = new RequestState(TEST_REQUEST_URL,
+ TEST_IDP_ISSUER,
+ requestId,
+ TEST_REQUEST_URL,
+ (String)config.getProtocol().getIssuer(),
+ null,
+ System.currentTimeMillis());
+
+ String relayState = URLEncoder.encode(UUID.randomUUID().toString(), "UTF-8");
+ ((SAMLProtocol)config.getProtocol()).getStateManager().setRequestState(relayState, requestState);
+
+ // Create SAML Response
+ SAML2CallbackHandler callbackHandler = new SAML2CallbackHandler();
+ callbackHandler.setAlsoAddAuthnStatement(true);
+ callbackHandler.setStatement(SAML2CallbackHandler.Statement.ATTR);
+ callbackHandler.setConfirmationMethod(SAML2Constants.CONF_BEARER);
+ callbackHandler.setIssuer(TEST_IDP_ISSUER);
+ callbackHandler.setSubjectName(TEST_USER);
+
+ ConditionsBean cp = new ConditionsBean();
+ AudienceRestrictionBean audienceRestriction = new AudienceRestrictionBean();
+ audienceRestriction.getAudienceURIs().add(TEST_REQUEST_URL);
+ cp.setAudienceRestrictions(Collections.singletonList(audienceRestriction));
+ callbackHandler.setConditions(cp);
+
+ // Subject Confirmation Data
+ SubjectConfirmationDataBean subjectConfirmationData = new SubjectConfirmationDataBean();
+ subjectConfirmationData.setAddress(TEST_CLIENT_ADDRESS);
+ subjectConfirmationData.setInResponseTo(requestId);
+ subjectConfirmationData.setNotAfter(new DateTime().plusMinutes(5));
+ subjectConfirmationData.setRecipient(TEST_REQUEST_URL);
+ callbackHandler.setSubjectConfirmationData(subjectConfirmationData);
+
+ SAMLCallback samlCallback = new SAMLCallback();
+ SAMLUtil.doSAMLCallback(callbackHandler, samlCallback);
+ SamlAssertionWrapper assertion = new SamlAssertionWrapper(samlCallback);
+
+ // The Issuer NameFormat must be "entity" if it is used at all
+ String issuerNameFormat = "urn:oasis:names:tc:SAML:2.0:nameid-format:kerberos";
+ Issuer issuer =
+ SAML2PResponseComponentBuilder.createIssuer(assertion.getIssuerString(),
+ issuerNameFormat);
+
+ Element response = createSamlResponse(assertion, "mystskey", true, requestId, issuer);
+ String responseStr = encodeResponse(response);
+
+ HttpServletRequest req = EasyMock.createMock(HttpServletRequest.class);
+ EasyMock.expect(req.getRequestURL()).andReturn(new StringBuffer(TEST_REQUEST_URL));
+ EasyMock.expect(req.getRemoteAddr()).andReturn(TEST_CLIENT_ADDRESS);
+ EasyMock.replay(req);
+
+ FedizRequest wfReq = new FedizRequest();
+ wfReq.setResponseToken(responseStr);
+ wfReq.setState(relayState);
+ wfReq.setRequest(req);
+
+ FedizProcessor wfProc = new SAMLProcessorImpl();
+ try {
+ wfProc.processRequest(wfReq, config);
+ fail("Failure expected");
+ } catch (ProcessingException ex) {
+ if (!TYPE.INVALID_REQUEST.equals(ex.getType())) {
+ fail("Expected ProcessingException with INVALID_REQUEST type");
+ }
+ }
+ }
+
+ @org.junit.Test
+ public void testRightIssuerFormat() throws Exception {
+ // Mock up a Request
+ FedizContext config = getFederationConfigurator().getFedizContext("ROOT");
+
+ String requestId = URLEncoder.encode(UUID.randomUUID().toString(), "UTF-8");
+
+ RequestState requestState = new RequestState(TEST_REQUEST_URL,
+ TEST_IDP_ISSUER,
+ requestId,
+ TEST_REQUEST_URL,
+ (String)config.getProtocol().getIssuer(),
+ null,
+ System.currentTimeMillis());
+
+ String relayState = URLEncoder.encode(UUID.randomUUID().toString(), "UTF-8");
+ ((SAMLProtocol)config.getProtocol()).getStateManager().setRequestState(relayState, requestState);
+
+ // Create SAML Response
+ SAML2CallbackHandler callbackHandler = new SAML2CallbackHandler();
+ callbackHandler.setAlsoAddAuthnStatement(true);
+ callbackHandler.setStatement(SAML2CallbackHandler.Statement.ATTR);
+ callbackHandler.setConfirmationMethod(SAML2Constants.CONF_BEARER);
+ callbackHandler.setIssuer(TEST_IDP_ISSUER);
+ callbackHandler.setSubjectName(TEST_USER);
+
+ ConditionsBean cp = new ConditionsBean();
+ AudienceRestrictionBean audienceRestriction = new AudienceRestrictionBean();
+ audienceRestriction.getAudienceURIs().add(TEST_REQUEST_URL);
+ cp.setAudienceRestrictions(Collections.singletonList(audienceRestriction));
+ callbackHandler.setConditions(cp);
+
+ // Subject Confirmation Data
+ SubjectConfirmationDataBean subjectConfirmationData = new SubjectConfirmationDataBean();
+ subjectConfirmationData.setAddress(TEST_CLIENT_ADDRESS);
+ subjectConfirmationData.setInResponseTo(requestId);
+ subjectConfirmationData.setNotAfter(new DateTime().plusMinutes(5));
+ subjectConfirmationData.setRecipient(TEST_REQUEST_URL);
+ callbackHandler.setSubjectConfirmationData(subjectConfirmationData);
+
+ SAMLCallback samlCallback = new SAMLCallback();
+ SAMLUtil.doSAMLCallback(callbackHandler, samlCallback);
+ SamlAssertionWrapper assertion = new SamlAssertionWrapper(samlCallback);
+
+ // The Issuer NameFormat must be "entity" if it is used at all
+ String issuerNameFormat = "urn:oasis:names:tc:SAML:2.0:nameid-format:entity";
+ Issuer issuer =
+ SAML2PResponseComponentBuilder.createIssuer(assertion.getIssuerString(),
+ issuerNameFormat);
+
+ Element response = createSamlResponse(assertion, "mystskey", true, requestId, issuer);
+ String responseStr = encodeResponse(response);
+
+ HttpServletRequest req = EasyMock.createMock(HttpServletRequest.class);
+ EasyMock.expect(req.getRequestURL()).andReturn(new StringBuffer(TEST_REQUEST_URL));
+ EasyMock.expect(req.getRemoteAddr()).andReturn(TEST_CLIENT_ADDRESS);
+ EasyMock.replay(req);
+
+ FedizRequest wfReq = new FedizRequest();
+ wfReq.setResponseToken(responseStr);
+ wfReq.setState(relayState);
+ wfReq.setRequest(req);
+
+ FedizProcessor wfProc = new SAMLProcessorImpl();
+ FedizResponse wfRes = wfProc.processRequest(wfReq, config);
+
+ Assert.assertEquals("Principal name wrong", TEST_USER,
+ wfRes.getUsername());
+ Assert.assertEquals("Issuer wrong", TEST_IDP_ISSUER, wfRes.getIssuer());
+ Assert.assertEquals("Two roles must be found", 2, wfRes.getRoles()
+ .size());
+ Assert.assertEquals("Audience wrong", TEST_REQUEST_URL, wfRes.getAudience());
+ }
+
+ @org.junit.Test
+ public void testNoAuthnStatement() throws Exception {
+ // Mock up a Request
+ FedizContext config = getFederationConfigurator().getFedizContext("ROOT");
+
+ String requestId = URLEncoder.encode(UUID.randomUUID().toString(), "UTF-8");
+
+ RequestState requestState = new RequestState(TEST_REQUEST_URL,
+ TEST_IDP_ISSUER,
+ requestId,
+ TEST_REQUEST_URL,
+ (String)config.getProtocol().getIssuer(),
+ null,
+ System.currentTimeMillis());
+
+ String relayState = URLEncoder.encode(UUID.randomUUID().toString(), "UTF-8");
+ ((SAMLProtocol)config.getProtocol()).getStateManager().setRequestState(relayState, requestState);
+
+ // Create SAML Response
+ SAML2CallbackHandler callbackHandler = new SAML2CallbackHandler();
+ callbackHandler.setStatement(SAML2CallbackHandler.Statement.ATTR);
+ callbackHandler.setConfirmationMethod(SAML2Constants.CONF_BEARER);
+ callbackHandler.setIssuer(TEST_IDP_ISSUER);
+ callbackHandler.setSubjectName(TEST_USER);
+
+ ConditionsBean cp = new ConditionsBean();
+ AudienceRestrictionBean audienceRestriction = new AudienceRestrictionBean();
+ audienceRestriction.getAudienceURIs().add(TEST_REQUEST_URL);
+ cp.setAudienceRestrictions(Collections.singletonList(audienceRestriction));
+ callbackHandler.setConditions(cp);
+
+ // Subject Confirmation Data
+ SubjectConfirmationDataBean subjectConfirmationData = new SubjectConfirmationDataBean();
+ subjectConfirmationData.setAddress(TEST_CLIENT_ADDRESS);
+ subjectConfirmationData.setInResponseTo(requestId);
+ subjectConfirmationData.setNotAfter(new DateTime().plusMinutes(5));
+ subjectConfirmationData.setRecipient(TEST_REQUEST_URL);
+ callbackHandler.setSubjectConfirmationData(subjectConfirmationData);
+
+ SAMLCallback samlCallback = new SAMLCallback();
+ SAMLUtil.doSAMLCallback(callbackHandler, samlCallback);
+ SamlAssertionWrapper assertion = new SamlAssertionWrapper(samlCallback);
+ Element response = createSamlResponse(assertion, "mystskey", true, requestId, null);
+ String responseStr = encodeResponse(response);
+
+ HttpServletRequest req = EasyMock.createMock(HttpServletRequest.class);
+ EasyMock.expect(req.getRequestURL()).andReturn(new StringBuffer(TEST_REQUEST_URL));
+ EasyMock.expect(req.getRemoteAddr()).andReturn(TEST_CLIENT_ADDRESS);
+ EasyMock.replay(req);
+
+ FedizRequest wfReq = new FedizRequest();
+ wfReq.setResponseToken(responseStr);
+ wfReq.setState(relayState);
+ wfReq.setRequest(req);
+
+ FedizProcessor wfProc = new SAMLProcessorImpl();
+ try {
+ wfProc.processRequest(wfReq, config);
+ fail("Failure expected");
+ } catch (ProcessingException ex) {
+ if (!TYPE.INVALID_REQUEST.equals(ex.getType())) {
+ fail("Expected ProcessingException with INVALID_REQUEST type");
+ }
+ }
+ }
+
+ @org.junit.Test
+ public void testAudienceRestriction() throws Exception {
+ // Mock up a Request
+ FedizContext config = getFederationConfigurator().getFedizContext("ROOT");
+
+ String requestId = URLEncoder.encode(UUID.randomUUID().toString(), "UTF-8");
+
+ RequestState requestState = new RequestState(TEST_REQUEST_URL,
+ TEST_IDP_ISSUER,
+ requestId,
+ TEST_REQUEST_URL,
+ (String)config.getProtocol().getIssuer(),
+ null,
+ System.currentTimeMillis());
+
+ String relayState = URLEncoder.encode(UUID.randomUUID().toString(), "UTF-8");
+ ((SAMLProtocol)config.getProtocol()).getStateManager().setRequestState(relayState, requestState);
+
+ // Create SAML Response
+ SAML2CallbackHandler callbackHandler = new SAML2CallbackHandler();
+ callbackHandler.setAlsoAddAuthnStatement(true);
+ callbackHandler.setStatement(SAML2CallbackHandler.Statement.ATTR);
+ callbackHandler.setConfirmationMethod(SAML2Constants.CONF_BEARER);
+ callbackHandler.setIssuer(TEST_IDP_ISSUER);
+ callbackHandler.setSubjectName(TEST_USER);
+
+ ConditionsBean cp = new ConditionsBean();
+ callbackHandler.setConditions(cp);
+
+ // Subject Confirmation Data
+ SubjectConfirmationDataBean subjectConfirmationData = new SubjectConfirmationDataBean();
+ subjectConfirmationData.setAddress(TEST_CLIENT_ADDRESS);
+ subjectConfirmationData.setInResponseTo(requestId);
+ subjectConfirmationData.setNotAfter(new DateTime().plusMinutes(5));
+ subjectConfirmationData.setRecipient(TEST_REQUEST_URL);
+ callbackHandler.setSubjectConfirmationData(subjectConfirmationData);
+
+ SAMLCallback samlCallback = new SAMLCallback();
+ SAMLUtil.doSAMLCallback(callbackHandler, samlCallback);
+ SamlAssertionWrapper assertion = new SamlAssertionWrapper(samlCallback);
+ Element response = createSamlResponse(assertion, "mystskey", true, requestId, null);
+ String responseStr = encodeResponse(response);
+
+ HttpServletRequest req = EasyMock.createMock(HttpServletRequest.class);
+ EasyMock.expect(req.getRequestURL()).andReturn(new StringBuffer(TEST_REQUEST_URL));
+ EasyMock.expect(req.getRemoteAddr()).andReturn(TEST_CLIENT_ADDRESS);
+ EasyMock.replay(req);
+
+ FedizRequest wfReq = new FedizRequest();
+ wfReq.setResponseToken(responseStr);
+ wfReq.setState(relayState);
+ wfReq.setRequest(req);
+
+ FedizProcessor wfProc = new SAMLProcessorImpl();
+ try {
+ wfProc.processRequest(wfReq, config);
+ fail("Failure expected");
+ } catch (ProcessingException ex) {
+ if (!TYPE.INVALID_REQUEST.equals(ex.getType())) {
+ fail("Expected ProcessingException with INVALID_REQUEST type");
+ }
+ }
+ }
+
+ @org.junit.Test
+ public void testNonMatchingAudienceRestriction() throws Exception {
+ // Mock up a Request
+ FedizContext config = getFederationConfigurator().getFedizContext("ROOT");
+
+ String requestId = URLEncoder.encode(UUID.randomUUID().toString(), "UTF-8");
+
+ RequestState requestState = new RequestState(TEST_REQUEST_URL,
+ TEST_IDP_ISSUER,
+ requestId,
+ TEST_REQUEST_URL,
+ (String)config.getProtocol().getIssuer(),
+ null,
+ System.currentTimeMillis());
+
+ String relayState = URLEncoder.encode(UUID.randomUUID().toString(), "UTF-8");
+ ((SAMLProtocol)config.getProtocol()).getStateManager().setRequestState(relayState, requestState);
+
+ // Create SAML Response
+ SAML2CallbackHandler callbackHandler = new SAML2CallbackHandler();
+ callbackHandler.setAlsoAddAuthnStatement(true);
+ callbackHandler.setStatement(SAML2CallbackHandler.Statement.ATTR);
+ callbackHandler.setConfirmationMethod(SAML2Constants.CONF_BEARER);
+ callbackHandler.setIssuer(TEST_IDP_ISSUER);
+ callbackHandler.setSubjectName(TEST_USER);
+
+ ConditionsBean cp = new ConditionsBean();
+ AudienceRestrictionBean audienceRestriction = new AudienceRestrictionBean();
+ audienceRestriction.getAudienceURIs().add(TEST_REQUEST_URL + "asf");
+ cp.setAudienceRestrictions(Collections.singletonList(audienceRestriction));
+ callbackHandler.setConditions(cp);
+
+ // Subject Confirmation Data
+ SubjectConfirmationDataBean subjectConfirmationData = new SubjectConfirmationDataBean();
+ subjectConfirmationData.setAddress(TEST_CLIENT_ADDRESS);
+ subjectConfirmationData.setInResponseTo(requestId);
+ subjectConfirmationData.setNotAfter(new DateTime().plusMinutes(5));
+ subjectConfirmationData.setRecipient(TEST_REQUEST_URL);
+ callbackHandler.setSubjectConfirmationData(subjectConfirmationData);
+
+ SAMLCallback samlCallback = new SAMLCallback();
+ SAMLUtil.doSAMLCallback(callbackHandler, samlCallback);
+ SamlAssertionWrapper assertion = new SamlAssertionWrapper(samlCallback);
+ Element response = createSamlResponse(assertion, "mystskey", true, requestId, null);
+ String responseStr = encodeResponse(response);
+
+ HttpServletRequest req = EasyMock.createMock(HttpServletRequest.class);
+ EasyMock.expect(req.getRequestURL()).andReturn(new StringBuffer(TEST_REQUEST_URL));
+ EasyMock.expect(req.getRemoteAddr()).andReturn(TEST_CLIENT_ADDRESS);
+ EasyMock.replay(req);
+
+ FedizRequest wfReq = new FedizRequest();
+ wfReq.setResponseToken(responseStr);
+ wfReq.setState(relayState);
+ wfReq.setRequest(req);
+
+ FedizProcessor wfProc = new SAMLProcessorImpl();
+ try {
+ wfProc.processRequest(wfReq, config);
+ fail("Failure expected");
+ } catch (ProcessingException ex) {
+ if (!TYPE.INVALID_REQUEST.equals(ex.getType())) {
+ fail("Expected ProcessingException with INVALID_REQUEST type");
+ }
+ }
+ }
+
+ @org.junit.Test
+ public void testNoBearerSubjectConfirmation() throws Exception {
+ // Mock up a Request
+ FedizContext config = getFederationConfigurator().getFedizContext("ROOT");
+
+ String requestId = URLEncoder.encode(UUID.randomUUID().toString(), "UTF-8");
+
+ RequestState requestState = new RequestState(TEST_REQUEST_URL,
+ TEST_IDP_ISSUER,
+ requestId,
+ TEST_REQUEST_URL,
+ (String)config.getProtocol().getIssuer(),
+ null,
+ System.currentTimeMillis());
+
+ String relayState = URLEncoder.encode(UUID.randomUUID().toString(), "UTF-8");
+ ((SAMLProtocol)config.getProtocol()).getStateManager().setRequestState(relayState, requestState);
+
+ // Create SAML Response
+ SAML2CallbackHandler callbackHandler = new SAML2CallbackHandler();
+ callbackHandler.setAlsoAddAuthnStatement(true);
+ callbackHandler.setStatement(SAML2CallbackHandler.Statement.ATTR);
+ callbackHandler.setConfirmationMethod(SAML2Constants.CONF_SENDER_VOUCHES);
+ callbackHandler.setIssuer(TEST_IDP_ISSUER);
+ callbackHandler.setSubjectName(TEST_USER);
+
+ ConditionsBean cp = new ConditionsBean();
+ AudienceRestrictionBean audienceRestriction = new AudienceRestrictionBean();
+ audienceRestriction.getAudienceURIs().add(TEST_REQUEST_URL);
+ cp.setAudienceRestrictions(Collections.singletonList(audienceRestriction));
+ callbackHandler.setConditions(cp);
+
+ // Subject Confirmation Data
+ SubjectConfirmationDataBean subjectConfirmationData = new SubjectConfirmationDataBean();
+ subjectConfirmationData.setAddress(TEST_CLIENT_ADDRESS);
+ subjectConfirmationData.setInResponseTo(requestId);
+ subjectConfirmationData.setNotAfter(new DateTime().plusMinutes(5));
+ subjectConfirmationData.setRecipient(TEST_REQUEST_URL);
+ callbackHandler.setSubjectConfirmationData(subjectConfirmationData);
+
+ SAMLCallback samlCallback = new SAMLCallback();
+ SAMLUtil.doSAMLCallback(callbackHandler, samlCallback);
+ SamlAssertionWrapper assertion = new SamlAssertionWrapper(samlCallback);
+ Element response = createSamlResponse(assertion, "mystskey", true, requestId, null);
+ String responseStr = encodeResponse(response);
+
+ HttpServletRequest req = EasyMock.createMock(HttpServletRequest.class);
+ EasyMock.expect(req.getRequestURL()).andReturn(new StringBuffer(TEST_REQUEST_URL));
+ EasyMock.expect(req.getRemoteAddr()).andReturn(TEST_CLIENT_ADDRESS);
+ EasyMock.replay(req);
+
+ FedizRequest wfReq = new FedizRequest();
+ wfReq.setResponseToken(responseStr);
+ wfReq.setState(relayState);
+ wfReq.setRequest(req);
+
+ FedizProcessor wfProc = new SAMLProcessorImpl();
+ try {
+ wfProc.processRequest(wfReq, config);
+ fail("Failure expected");
+ } catch (ProcessingException ex) {
+ if (!TYPE.INVALID_REQUEST.equals(ex.getType())) {
+ fail("Expected ProcessingException with INVALID_REQUEST type");
+ }
+ }
+ }
+
+ @org.junit.Test
+ public void testNonMatchingRecipient() throws Exception {
+ // Mock up a Request
+ FedizContext config = getFederationConfigurator().getFedizContext("ROOT");
+
+ String requestId = URLEncoder.encode(UUID.randomUUID().toString(), "UTF-8");
+
+ RequestState requestState = new RequestState(TEST_REQUEST_URL,
+ TEST_IDP_ISSUER,
+ requestId,
+ TEST_REQUEST_URL,
+ (String)config.getProtocol().getIssuer(),
+ null,
+ System.currentTimeMillis());
+
+ String relayState = URLEncoder.encode(UUID.randomUUID().toString(), "UTF-8");
+ ((SAMLProtocol)config.getProtocol()).getStateManager().setRequestState(relayState, requestState);
+
+ // Create SAML Response
+ SAML2CallbackHandler callbackHandler = new SAML2CallbackHandler();
+ callbackHandler.setAlsoAddAuthnStatement(true);
+ callbackHandler.setStatement(SAML2CallbackHandler.Statement.ATTR);
+ callbackHandler.setConfirmationMethod(SAML2Constants.CONF_BEARER);
+ callbackHandler.setIssuer(TEST_IDP_ISSUER);
+ callbackHandler.setSubjectName(TEST_USER);
+
+ ConditionsBean cp = new ConditionsBean();
+ AudienceRestrictionBean audienceRestriction = new AudienceRestrictionBean();
+ audienceRestriction.getAudienceURIs().add(TEST_REQUEST_URL);
+ cp.setAudienceRestrictions(Collections.singletonList(audienceRestriction));
+ callbackHandler.setConditions(cp);
+
+ // Subject Confirmation Data
+ SubjectConfirmationDataBean subjectConfirmationData = new SubjectConfirmationDataBean();
+ subjectConfirmationData.setAddress(TEST_CLIENT_ADDRESS);
+ subjectConfirmationData.setInResponseTo(requestId);
+ subjectConfirmationData.setNotAfter(new DateTime().plusMinutes(5));
+ subjectConfirmationData.setRecipient(TEST_REQUEST_URL + "asf");
+ callbackHandler.setSubjectConfirmationData(subjectConfirmationData);
+
+ SAMLCallback samlCallback = new SAMLCallback();
+ SAMLUtil.doSAMLCallback(callbackHandler, samlCallback);
+ SamlAssertionWrapper assertion = new SamlAssertionWrapper(samlCallback);
+ Element response = createSamlResponse(assertion, "mystskey", true, requestId, null);
+ String responseStr = encodeResponse(response);
+
+ HttpServletRequest req = EasyMock.createMock(HttpServletRequest.class);
+ EasyMock.expect(req.getRequestURL()).andReturn(new StringBuffer(TEST_REQUEST_URL));
+ EasyMock.expect(req.getRemoteAddr()).andReturn(TEST_CLIENT_ADDRESS);
+ EasyMock.replay(req);
+
+ FedizRequest wfReq = new FedizRequest();
+ wfReq.setResponseToken(responseStr);
+ wfReq.setState(relayState);
+ wfReq.setRequest(req);
+
+ FedizProcessor wfProc = new SAMLProcessorImpl();
+ try {
+ wfProc.processRequest(wfReq, config);
+ fail("Failure expected");
+ } catch (ProcessingException ex) {
+ if (!TYPE.INVALID_REQUEST.equals(ex.getType())) {
+ fail("Expected ProcessingException with INVALID_REQUEST type");
+ }
+ }
+ }
+
+ @org.junit.Test
+ public void testNonMatchingInResponseTo() throws Exception {
+ // Mock up a Request
+ FedizContext config = getFederationConfigurator().getFedizContext("ROOT");
+
+ String requestId = URLEncoder.encode(UUID.randomUUID().toString(), "UTF-8");
+
+ RequestState requestState = new RequestState(TEST_REQUEST_URL,
+ TEST_IDP_ISSUER,
+ requestId,
+ TEST_REQUEST_URL,
+ (String)config.getProtocol().getIssuer(),
+ null,
+ System.currentTimeMillis());
+
+ String relayState = URLEncoder.encode(UUID.randomUUID().toString(), "UTF-8");
+ ((SAMLProtocol)config.getProtocol()).getStateManager().setRequestState(relayState, requestState);
+
+ // Create SAML Response
+ SAML2CallbackHandler callbackHandler = new SAML2CallbackHandler();
+ callbackHandler.setAlsoAddAuthnStatement(true);
+ callbackHandler.setStatement(SAML2CallbackHandler.Statement.ATTR);
+ callbackHandler.setConfirmationMethod(SAML2Constants.CONF_BEARER);
+ callbackHandler.setIssuer(TEST_IDP_ISSUER);
+ callbackHandler.setSubjectName(TEST_USER);
+
+ ConditionsBean cp = new ConditionsBean();
+ AudienceRestrictionBean audienceRestriction = new AudienceRestrictionBean();
+ audienceRestriction.getAudienceURIs().add(TEST_REQUEST_URL);
+ cp.setAudienceRestrictions(Collections.singletonList(audienceRestriction));
+ callbackHandler.setConditions(cp);
+
+ // Subject Confirmation Data
+ SubjectConfirmationDataBean subjectConfirmationData = new SubjectConfirmationDataBean();
+ subjectConfirmationData.setAddress(TEST_CLIENT_ADDRESS);
+ subjectConfirmationData.setInResponseTo(requestId + "123");
+ subjectConfirmationData.setNotAfter(new DateTime().plusMinutes(5));
+ subjectConfirmationData.setRecipient(TEST_REQUEST_URL);
+ callbackHandler.setSubjectConfirmationData(subjectConfirmationData);
+
+ SAMLCallback samlCallback = new SAMLCallback();
+ SAMLUtil.doSAMLCallback(callbackHandler, samlCallback);
+ SamlAssertionWrapper assertion = new SamlAssertionWrapper(samlCallback);
+ Element response = createSamlResponse(assertion, "mystskey", true, requestId, null);
+ String responseStr = encodeResponse(response);
+
+ HttpServletRequest req = EasyMock.createMock(HttpServletRequest.class);
+ EasyMock.expect(req.getRequestURL()).andReturn(new StringBuffer(TEST_REQUEST_URL));
+ EasyMock.expect(req.getRemoteAddr()).andReturn(TEST_CLIENT_ADDRESS);
+ EasyMock.replay(req);
+
+ FedizRequest wfReq = new FedizRequest();
+ wfReq.setResponseToken(responseStr);
+ wfReq.setState(relayState);
+ wfReq.setRequest(req);
+
+ FedizProcessor wfProc = new SAMLProcessorImpl();
+ try {
+ wfProc.processRequest(wfReq, config);
+ fail("Failure expected");
+ } catch (ProcessingException ex) {
+ if (!TYPE.INVALID_REQUEST.equals(ex.getType())) {
+ fail("Expected ProcessingException with INVALID_REQUEST type");
+ }
+ }
+ }
+
+ @org.junit.Test
+ public void testNonMatchingAddress() throws Exception {
+ // Mock up a Request
+ FedizContext config = getFederationConfigurator().getFedizContext("ROOT");
+
+ String requestId = URLEncoder.encode(UUID.randomUUID().toString(), "UTF-8");
+
+ RequestState requestState = new RequestState(TEST_REQUEST_URL,
+ TEST_IDP_ISSUER,
+ requestId,
+ TEST_REQUEST_URL,
+ (String)config.getProtocol().getIssuer(),
+ null,
+ System.currentTimeMillis());
+
+ String relayState = URLEncoder.encode(UUID.randomUUID().toString(), "UTF-8");
+ ((SAMLProtocol)config.getProtocol()).getStateManager().setRequestState(relayState, requestState);
+
+ // Create SAML Response
+ SAML2CallbackHandler callbackHandler = new SAML2CallbackHandler();
+ callbackHandler.setAlsoAddAuthnStatement(true);
+ callbackHandler.setStatement(SAML2CallbackHandler.Statement.ATTR);
+ callbackHandler.setConfirmationMethod(SAML2Constants.CONF_BEARER);
+ callbackHandler.setIssuer(TEST_IDP_ISSUER);
+ callbackHandler.setSubjectName(TEST_USER);
+
+ ConditionsBean cp = new ConditionsBean();
+ AudienceRestrictionBean audienceRestriction = new AudienceRestrictionBean();
+ audienceRestriction.getAudienceURIs().add(TEST_REQUEST_URL);
+ cp.setAudienceRestrictions(Collections.singletonList(audienceRestriction));
+ callbackHandler.setConditions(cp);
+
+ // Subject Confirmation Data
+ SubjectConfirmationDataBean subjectConfirmationData = new SubjectConfirmationDataBean();
+ subjectConfirmationData.setAddress(TEST_CLIENT_ADDRESS + "xyz");
+ subjectConfirmationData.setInResponseTo(requestId);
+ subjectConfirmationData.setNotAfter(new DateTime().plusMinutes(5));
+ subjectConfirmationData.setRecipient(TEST_REQUEST_URL);
+ callbackHandler.setSubjectConfirmationData(subjectConfirmationData);
+
+ SAMLCallback samlCallback = new SAMLCallback();
+ SAMLUtil.doSAMLCallback(callbackHandler, samlCallback);
+ SamlAssertionWrapper assertion = new SamlAssertionWrapper(samlCallback);
+ Element response = createSamlResponse(assertion, "mystskey", true, requestId, null);
+ String responseStr = encodeResponse(response);
+
+ HttpServletRequest req = EasyMock.createMock(HttpServletRequest.class);
+ EasyMock.expect(req.getRequestURL()).andReturn(new StringBuffer(TEST_REQUEST_URL));
+ EasyMock.expect(req.getRemoteAddr()).andReturn(TEST_CLIENT_ADDRESS);
+ EasyMock.replay(req);
+
+ FedizRequest wfReq = new FedizRequest();
+ wfReq.setResponseToken(responseStr);
+ wfReq.setState(relayState);
+ wfReq.setRequest(req);
+
+ FedizProcessor wfProc = new SAMLProcessorImpl();
+ try {
+ wfProc.processRequest(wfReq, config);
+ fail("Failure expected");
+ } catch (ProcessingException ex) {
+ if (!TYPE.INVALID_REQUEST.equals(ex.getType())) {
+ fail("Expected ProcessingException with INVALID_REQUEST type");
+ }
+ }
+ }
+
+ @org.junit.Test
+ public void testNotBefore() throws Exception {
+ // Mock up a Request
+ FedizContext config = getFederationConfigurator().getFedizContext("ROOT");
+
+ String requestId = URLEncoder.encode(UUID.randomUUID().toString(), "UTF-8");
+
+ RequestState requestState = new RequestState(TEST_REQUEST_URL,
+ TEST_IDP_ISSUER,
+ requestId,
+ TEST_REQUEST_URL,
+ (String)config.getProtocol().getIssuer(),
+ null,
+ System.currentTimeMillis());
+
+ String relayState = URLEncoder.encode(UUID.randomUUID().toString(), "UTF-8");
+ ((SAMLProtocol)config.getProtocol()).getStateManager().setRequestState(relayState, requestState);
+
+ // Create SAML Response
+ SAML2CallbackHandler callbackHandler = new SAML2CallbackHandler();
+ callbackHandler.setAlsoAddAuthnStatement(true);
+ callbackHandler.setStatement(SAML2CallbackHandler.Statement.ATTR);
+ callbackHandler.setConfirmationMethod(SAML2Constants.CONF_BEARER);
+ callbackHandler.setIssuer(TEST_IDP_ISSUER);
+ callbackHandler.setSubjectName(TEST_USER);
+
+ ConditionsBean cp = new ConditionsBean();
+ AudienceRestrictionBean audienceRestriction = new AudienceRestrictionBean();
+ audienceRestriction.getAudienceURIs().add(TEST_REQUEST_URL);
+ cp.setAudienceRestrictions(Collections.singletonList(audienceRestriction));
+ callbackHandler.setConditions(cp);
+
+ // Subject Confirmation Data
+ SubjectConfirmationDataBean subjectConfirmationData = new SubjectConfirmationDataBean();
+ subjectConfirmationData.setAddress(TEST_CLIENT_ADDRESS);
+ subjectConfirmationData.setInResponseTo(requestId);
+ subjectConfirmationData.setNotBefore(new DateTime().minusMinutes(1));
+ subjectConfirmationData.setNotAfter(new DateTime().plusMinutes(5));
+ subjectConfirmationData.setRecipient(TEST_REQUEST_URL);
+ callbackHandler.setSubjectConfirmationData(subjectConfirmationData);
+
+ SAMLCallback samlCallback = new SAMLCallback();
+ SAMLUtil.doSAMLCallback(callbackHandler, samlCallback);
+ SamlAssertionWrapper assertion = new SamlAssertionWrapper(samlCallback);
+ Element response = createSamlResponse(assertion, "mystskey", true, requestId, null);
+ String responseStr = encodeResponse(response);
+
+ HttpServletRequest req = EasyMock.createMock(HttpServletRequest.class);
+ EasyMock.expect(req.getRequestURL()).andReturn(new StringBuffer(TEST_REQUEST_URL));
+ EasyMock.expect(req.getRemoteAddr()).andReturn(TEST_CLIENT_ADDRESS);
+ EasyMock.replay(req);
+
+ FedizRequest wfReq = new FedizRequest();
+ wfReq.setResponseToken(responseStr);
+ wfReq.setState(relayState);
+ wfReq.setRequest(req);
+
+ FedizProcessor wfProc = new SAMLProcessorImpl();
+ try {
+ wfProc.processRequest(wfReq, config);
+ fail("Failure expected");
+ } catch (ProcessingException ex) {
+ if (!TYPE.INVALID_REQUEST.equals(ex.getType())) {
+ fail("Expected ProcessingException with INVALID_REQUEST type");
+ }
+ }
+ }
+
+ @org.junit.Test
+ public void testNotOnOfAfter() throws Exception {
+ // Mock up a Request
+ FedizContext config = getFederationConfigurator().getFedizContext("ROOT");
+
+ String requestId = URLEncoder.encode(UUID.randomUUID().toString(), "UTF-8");
+
+ RequestState requestState = new RequestState(TEST_REQUEST_URL,
+ TEST_IDP_ISSUER,
+ requestId,
+ TEST_REQUEST_URL,
+ (String)config.getProtocol().getIssuer(),
+ null,
+ System.currentTimeMillis());
+
+ String relayState = URLEncoder.encode(UUID.randomUUID().toString(), "UTF-8");
+ ((SAMLProtocol)config.getProtocol()).getStateManager().setRequestState(relayState, requestState);
+
+ // Create SAML Response
+ SAML2CallbackHandler callbackHandler = new SAML2CallbackHandler();
+ callbackHandler.setAlsoAddAuthnStatement(true);
+ callbackHandler.setStatement(SAML2CallbackHandler.Statement.ATTR);
+ callbackHandler.setConfirmationMethod(SAML2Constants.CONF_BEARER);
+ callbackHandler.setIssuer(TEST_IDP_ISSUER);
+ callbackHandler.setSubjectName(TEST_USER);
+
+ ConditionsBean cp = new ConditionsBean();
+ AudienceRestrictionBean audienceRestriction = new AudienceRestrictionBean();
+ audienceRestriction.getAudienceURIs().add(TEST_REQUEST_URL);
+ cp.setAudienceRestrictions(Collections.singletonList(audienceRestriction));
+ callbackHandler.setConditions(cp);
+
+ // Subject Confirmation Data
+ SubjectConfirmationDataBean subjectConfirmationData = new SubjectConfirmationDataBean();
+ subjectConfirmationData.setAddress(TEST_CLIENT_ADDRESS);
+ subjectConfirmationData.setInResponseTo(requestId);
+ subjectConfirmationData.setRecipient(TEST_REQUEST_URL);
+ callbackHandler.setSubjectConfirmationData(subjectConfirmationData);
+
+ SAMLCallback samlCallback = new SAMLCallback();
+ SAMLUtil.doSAMLCallback(callbackHandler, samlCallback);
+ SamlAssertionWrapper assertion = new SamlAssertionWrapper(samlCallback);
+ Element response = createSamlResponse(assertion, "mystskey", true, requestId, null);
+ String responseStr = encodeResponse(response);
+
+ HttpServletRequest req = EasyMock.createMock(HttpServletRequest.class);
+ EasyMock.expect(req.getRequestURL()).andReturn(new StringBuffer(TEST_REQUEST_URL));
+ EasyMock.expect(req.getRemoteAddr()).andReturn(TEST_CLIENT_ADDRESS);
+ EasyMock.replay(req);
+
+ FedizRequest wfReq = new FedizRequest();
+ wfReq.setResponseToken(responseStr);
+ wfReq.setState(relayState);
+ wfReq.setRequest(req);
+
+ FedizProcessor wfProc = new SAMLProcessorImpl();
+ try {
+ wfProc.processRequest(wfReq, config);
+ fail("Failure expected");
+ } catch (ProcessingException ex) {
+ if (!TYPE.INVALID_REQUEST.equals(ex.getType())) {
+ fail("Expected ProcessingException with INVALID_REQUEST type");
+ }
+ }
+ }
+
+ @org.junit.Test
+ public void testFailingStatusWithValidAssertion() throws Exception {
+ // Mock up a Request
+ FedizContext config = getFederationConfigurator().getFedizContext("ROOT");
+
+ String requestId = URLEncoder.encode(UUID.randomUUID().toString(), "UTF-8");
+
+ RequestState requestState = new RequestState(TEST_REQUEST_URL,
+ TEST_IDP_ISSUER,
+ requestId,
+ TEST_REQUEST_URL,
+ (String)config.getProtocol().getIssuer(),
+ null,
+ System.currentTimeMillis());
+
+ String relayState = URLEncoder.encode(UUID.randomUUID().toString(), "UTF-8");
+ ((SAMLProtocol)config.getProtocol()).getStateManager().setRequestState(relayState, requestState);
+
+ // Create SAML Response
+ SAML2CallbackHandler callbackHandler = new SAML2CallbackHandler();
+ callbackHandler.setAlsoAddAuthnStatement(true);
+ callbackHandler.setStatement(SAML2CallbackHandler.Statement.ATTR);
+ callbackHandler.setConfirmationMethod(SAML2Constants.CONF_BEARER);
+ callbackHandler.setIssuer(TEST_IDP_ISSUER);
+ callbackHandler.setSubjectName(TEST_USER);
+
+ ConditionsBean cp = new ConditionsBean();
+ AudienceRestrictionBean audienceRestriction = new AudienceRestrictionBean();
+ audienceRestriction.getAudienceURIs().add(TEST_REQUEST_URL);
+ cp.setAudienceRestrictions(Collections.singletonList(audienceRestriction));
+ callbackHandler.setConditions(cp);
+
+ // Subject Confirmation Data
+ SubjectConfirmationDataBean subjectConfirmationData = new SubjectConfirmationDataBean();
+ subjectConfirmationData.setAddress(TEST_CLIENT_ADDRESS);
+ subjectConfirmationData.setInResponseTo(requestId);
+ subjectConfirmationData.setRecipient(TEST_REQUEST_URL);
+ subjectConfirmationData.setNotAfter(new DateTime().plusMinutes(5));
+ callbackHandler.setSubjectConfirmationData(subjectConfirmationData);
+
+ SAMLCallback samlCallback = new SAMLCallback();
+ SAMLUtil.doSAMLCallback(callbackHandler, samlCallback);
+ SamlAssertionWrapper assertion = new SamlAssertionWrapper(samlCallback);
+
+ WSPasswordCallback[] cb = {
+ new WSPasswordCallback("mystskey", WSPasswordCallback.SIGNATURE)
+ };
+ cbPasswordHandler.handle(cb);
+ String password = cb[0].getPassword();
+ assertion.signAssertion("mystskey", password, crypto, false);
+
+ DocumentBuilder docBuilder = docBuilderFactory.newDocumentBuilder();
+ Document doc = docBuilder.newDocument();
+
+ Status status =
+ SAML2PResponseComponentBuilder.createStatus(
+ "urn:oasis:names:tc:SAML:2.0:status:Failure", null
+ );
+
+ Issuer responseIssuer =
+ SAML2PResponseComponentBuilder.createIssuer(assertion.getIssuerString());
+
+ Response response =
+ SAML2PResponseComponentBuilder.createSAMLResponse(requestId,
+ responseIssuer,
+ status);
+
+ response.getAssertions().add(assertion.getSaml2());
+
+ Element policyElement = OpenSAMLUtil.toDom(response, doc);
+ doc.appendChild(policyElement);
+
+ String responseStr = encodeResponse(policyElement);
+
+ HttpServletRequest req = EasyMock.createMock(HttpServletRequest.class);
+ EasyMock.expect(req.getRequestURL()).andReturn(new StringBuffer(TEST_REQUEST_URL));
+ EasyMock.expect(req.getRemoteAddr()).andReturn(TEST_CLIENT_ADDRESS);
+ EasyMock.replay(req);
+
+ FedizRequest wfReq = new FedizRequest();
+ wfReq.setResponseToken(responseStr);
+ wfReq.setState(relayState);
+ wfReq.setRequest(req);
+
+ FedizProcessor wfProc = new SAMLProcessorImpl();
+ try {
+ wfProc.processRequest(wfReq, config);
+ fail("Failure expected");
+ } catch (ProcessingException ex) {
+ if (!TYPE.INVALID_REQUEST.equals(ex.getType())) {
+ fail("Expected ProcessingException with INVALID_REQUEST type");
+ }
+ }
+ }
+
+
+ private Element createSamlResponse(SamlAssertionWrapper assertion, String alias,
+ boolean sign, String requestID, Issuer issuer)
+ throws IOException, UnsupportedCallbackException, WSSecurityException, Exception {
+ WSPasswordCallback[] cb = {
+ new WSPasswordCallback(alias, WSPasswordCallback.SIGNATURE)
+ };
+ cbPasswordHandler.handle(cb);
+ String password = cb[0].getPassword();
+
+ if (sign) {
+ assertion.signAssertion(alias, password, crypto, false);
+ }
+
+ DocumentBuilder docBuilder = docBuilderFactory.newDocumentBuilder();
+ Document doc = docBuilder.newDocument();
+
+ Status status =
+ SAML2PResponseComponentBuilder.createStatus(
+ "urn:oasis:names:tc:SAML:2.0:status:Success", null
+ );
+
+ Issuer responseIssuer = issuer;
+ if (responseIssuer == null) {
+ responseIssuer = SAML2PResponseComponentBuilder.createIssuer(assertion.getIssuerString());
+ }
+ Response response =
+ SAML2PResponseComponentBuilder.createSAMLResponse(requestID,
+ responseIssuer,
+ status);
+
+ response.getAssertions().add(assertion.getSaml2());
+
+ Element policyElement = OpenSAMLUtil.toDom(response, doc);
+ doc.appendChild(policyElement);
+
+ return policyElement;
+ }
+
+
+ /**
+ * Returns the first element that matches <code>name</code> and
+ * <code>namespace</code>. <p/> This is a replacement for a XPath lookup
+ * <code>//name</code> with the given namespace. It's somewhat faster than
+ * XPath, and we do not deal with prefixes, just with the real namespace URI
+ *
+ * @param startNode Where to start the search
+ * @param name Local name of the element
+ * @param namespace Namespace URI of the element
+ * @return The found element or <code>null</code>
+ */
+ public static Element findElement(Node startNode, String name, String namespace) {
+ //
+ // Replace the formerly recursive implementation with a depth-first-loop
+ // lookup
+ //
+ if (startNode == null) {
+ return null;
+ }
+ Node startParent = startNode.getParentNode();
+ Node processedNode = null;
+
+ while (startNode != null) {
+ // start node processing at this point
+ if (startNode.getNodeType() == Node.ELEMENT_NODE
+ && startNode.getLocalName().equals(name)) {
+ String ns = startNode.getNamespaceURI();
+ if (ns != null && ns.equals(namespace)) {
+ return (Element)startNode;
+ }
+
+ if ((namespace == null || namespace.length() == 0)
+ && (ns == null || ns.length() == 0)) {
+ return (Element)startNode;
+ }
+ }
+ processedNode = startNode;
+ startNode = startNode.getFirstChild();
+
+ // no child, this node is done.
+ if (startNode == null) {
+ // close node processing, get sibling
+ startNode = processedNode.getNextSibling();
+ }
+ // no more siblings, get parent, all children
+ // of parent are processed.
+ while (startNode == null) {
+ processedNode = processedNode.getParentNode();
+ if (processedNode == startParent) {
+ return null;
+ }
+ // close parent node processing (processed node now)
+ startNode = processedNode.getNextSibling();
+ }
+ }
+ return null;
+ }
+
+ private String encodeResponse(Element response) throws IOException {
+ String responseMessage = DOM2Writer.nodeToString(response);
+
+ byte[] deflatedBytes = CompressionUtils.deflate(responseMessage.getBytes("UTF-8"));
+
+ return Base64.encode(deflatedBytes);
+ }
+
+
+}