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/23 18:24:05 UTC
[1/4] Adding unit tests for SAML SSO
Repository: cxf-fediz
Updated Branches:
refs/heads/master 909e640e0 -> 617fd4e95
http://git-wip-us.apache.org/repos/asf/cxf-fediz/blob/617fd4e9/plugins/core/src/test/java/org/apache/cxf/fediz/core/samlsso/SAMLResponseTest.java
----------------------------------------------------------------------
diff --git a/plugins/core/src/test/java/org/apache/cxf/fediz/core/samlsso/SAMLResponseTest.java b/plugins/core/src/test/java/org/apache/cxf/fediz/core/samlsso/SAMLResponseTest.java
new file mode 100644
index 0000000..09e626a
--- /dev/null
+++ b/plugins/core/src/test/java/org/apache/cxf/fediz/core/samlsso/SAMLResponseTest.java
@@ -0,0 +1,1378 @@
+/**
+ * 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.List;
+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.STSUtil;
+import org.apache.cxf.fediz.common.SecurityTestUtil;
+import org.apache.cxf.fediz.core.AbstractSAMLCallbackHandler;
+import org.apache.cxf.fediz.core.Claim;
+import org.apache.cxf.fediz.core.ClaimTypes;
+import org.apache.cxf.fediz.core.FederationConstants;
+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.Response;
+import org.opensaml.saml2.core.Status;
+
+import static org.junit.Assert.fail;
+
+/**
+ * Some tests for processing SAMLResponses using the SAMLProcessorImpl
+ */
+public class SAMLResponseTest {
+ 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;
+ }
+ }
+
+ /**
+ * Successfully validate a SAMLResponse
+ */
+ @org.junit.Test
+ public void validateSAMLResponse() 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
+ String responseStr = createSamlResponseStr(requestId);
+
+ 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());
+ assertClaims(wfRes.getClaims(), FederationConstants.DEFAULT_ROLE_URI.toString());
+ }
+
+ /**
+ * Validate SAMLResponse with a Response without an internal token parameter
+ */
+ @org.junit.Test
+ public void validateResponseWithoutToken() 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);
+
+ Document doc = STSUtil.toSOAPPart(SAMLSSOTestUtils.SAMPLE_EMPTY_SAML_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(DOM2Writer.nodeToString(doc));
+ wfReq.setState(relayState);
+ wfReq.setRequest(req);
+
+ FedizProcessor wfProc = new SAMLProcessorImpl();
+ try {
+ wfProc.processRequest(wfReq, config);
+ fail("Failure expected on missing security token in response");
+ } catch (ProcessingException ex) {
+ if (!TYPE.INVALID_REQUEST.equals(ex.getType())) {
+ fail("Expected ProcessingException with BAD_REQUEST type");
+ }
+ }
+ }
+
+ @org.junit.Test
+ public void testMissingRelayState() 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
+ String responseStr = createSamlResponseStr(requestId);
+
+ 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.setRequest(req);
+
+ FedizProcessor wfProc = new SAMLProcessorImpl();
+ try {
+ wfProc.processRequest(wfReq, config);
+ fail("Failure expected on missing relay state in response");
+ } catch (ProcessingException ex) {
+ if (!TYPE.INVALID_REQUEST.equals(ex.getType())) {
+ fail("Expected ProcessingException with BAD_REQUEST type");
+ }
+ }
+ }
+
+ @org.junit.Test
+ public void testNonMatchingRelayState() 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
+ String responseStr = createSamlResponseStr(requestId);
+
+ 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("XYZ=");
+ wfReq.setRequest(req);
+
+ FedizProcessor wfProc = new SAMLProcessorImpl();
+ try {
+ wfProc.processRequest(wfReq, config);
+ fail("Failure expected on non matching relay state in response");
+ } catch (ProcessingException ex) {
+ if (!TYPE.INVALID_REQUEST.equals(ex.getType())) {
+ fail("Expected ProcessingException with BAD_REQUEST type");
+ }
+ }
+ }
+
+ /**
+ * Validate SAML 2 token which includes the role attribute with 2 values
+ * Roles are encoded as a multi-value saml attribute
+ @org.junit.Test
+ public void validateSAML2Token() throws Exception {
+ SAML2CallbackHandler callbackHandler = new SAML2CallbackHandler();
+ callbackHandler.setStatement(SAML2CallbackHandler.Statement.ATTR);
+ callbackHandler.setConfirmationMethod(SAML2Constants.CONF_BEARER);
+ callbackHandler.setIssuer(TEST_RSTR_ISSUER);
+ callbackHandler.setSubjectName(TEST_USER);
+ ConditionsBean cp = new ConditionsBean();
+ AudienceRestrictionBean audienceRestriction = new AudienceRestrictionBean();
+ audienceRestriction.getAudienceURIs().add(TEST_AUDIENCE);
+ cp.setAudienceRestrictions(Collections.singletonList(audienceRestriction));
+ callbackHandler.setConditions(cp);
+
+ SAMLCallback samlCallback = new SAMLCallback();
+ SAMLUtil.doSAMLCallback(callbackHandler, samlCallback);
+ SamlAssertionWrapper assertion = new SamlAssertionWrapper(samlCallback);
+ String rstr = createSamlToken(assertion, "mystskey", true);
+
+ FedizRequest wfReq = new FedizRequest();
+ wfReq.setAction(FederationConstants.ACTION_SIGNIN);
+ wfReq.setResponseToken(rstr);
+
+ configurator = null;
+ FedizContext config = getFederationConfigurator().getFedizContext("ROOT");
+
+ FedizProcessor wfProc = new FederationProcessorImpl();
+ FedizResponse wfRes = wfProc.processRequest(wfReq, config);
+
+ Assert.assertEquals("Principal name wrong", TEST_USER,
+ wfRes.getUsername());
+ Assert.assertEquals("Issuer wrong", TEST_RSTR_ISSUER, wfRes.getIssuer());
+ Assert.assertEquals("Two roles must be found", 2, wfRes.getRoles()
+ .size());
+ Assert.assertEquals("Audience wrong", TEST_AUDIENCE, wfRes.getAudience());
+ assertClaims(wfRes.getClaims(), callbackHandler.getRoleAttributeName());
+
+ }
+
+ /**
+ * Validate SAML 2 token which includes the role attribute with 2 values
+ * Roles are encoded as a multi-value saml attribute
+ * Not RequestedSecurityTokenCollection in this test, default in all others
+ @org.junit.Test
+ public void validateSAML2TokenRSTR() throws Exception {
+ SAML2CallbackHandler callbackHandler = new SAML2CallbackHandler();
+ callbackHandler.setStatement(SAML2CallbackHandler.Statement.ATTR);
+ callbackHandler.setConfirmationMethod(SAML2Constants.CONF_BEARER);
+ callbackHandler.setIssuer(TEST_RSTR_ISSUER);
+ callbackHandler.setSubjectName(TEST_USER);
+ ConditionsBean cp = new ConditionsBean();
+ AudienceRestrictionBean audienceRestriction = new AudienceRestrictionBean();
+ audienceRestriction.getAudienceURIs().add(TEST_AUDIENCE);
+ cp.setAudienceRestrictions(Collections.singletonList(audienceRestriction));
+ callbackHandler.setConditions(cp);
+
+ SAMLCallback samlCallback = new SAMLCallback();
+ SAMLUtil.doSAMLCallback(callbackHandler, samlCallback);
+ SamlAssertionWrapper assertion = new SamlAssertionWrapper(samlCallback);
+ String rstr = createSamlToken(assertion, "mystskey", true, STSUtil.SAMPLE_RSTR_MSG);
+
+ FedizRequest wfReq = new FedizRequest();
+ wfReq.setAction(FederationConstants.ACTION_SIGNIN);
+ wfReq.setResponseToken(rstr);
+
+ configurator = null;
+ FedizContext config = getFederationConfigurator().getFedizContext("ROOT");
+
+ FedizProcessor wfProc = new FederationProcessorImpl();
+ FedizResponse wfRes = wfProc.processRequest(wfReq, config);
+
+ Assert.assertEquals("Principal name wrong", TEST_USER,
+ wfRes.getUsername());
+ Assert.assertEquals("Issuer wrong", TEST_RSTR_ISSUER, wfRes.getIssuer());
+ Assert.assertEquals("Two roles must be found", 2, wfRes.getRoles()
+ .size());
+ Assert.assertEquals("Audience wrong", TEST_AUDIENCE, wfRes.getAudience());
+ }
+
+ /**
+ * Validate SAML 2 token which doesn't include the role SAML attribute
+ @org.junit.Test
+ public void validateSAML2TokenWithoutRoles() throws Exception {
+ SAML2CallbackHandler callbackHandler = new SAML2CallbackHandler();
+ callbackHandler.setStatement(SAML2CallbackHandler.Statement.ATTR);
+ callbackHandler.setConfirmationMethod(SAML2Constants.CONF_BEARER);
+ callbackHandler.setIssuer(TEST_RSTR_ISSUER);
+ callbackHandler.setSubjectName(TEST_USER);
+ callbackHandler.setRoles(null);
+ ConditionsBean cp = new ConditionsBean();
+ AudienceRestrictionBean audienceRestriction = new AudienceRestrictionBean();
+ audienceRestriction.getAudienceURIs().add(TEST_AUDIENCE);
+ cp.setAudienceRestrictions(Collections.singletonList(audienceRestriction));
+ callbackHandler.setConditions(cp);
+
+ SAMLCallback samlCallback = new SAMLCallback();
+ SAMLUtil.doSAMLCallback(callbackHandler, samlCallback);
+ SamlAssertionWrapper assertion = new SamlAssertionWrapper(samlCallback);
+ String rstr = createSamlToken(assertion, "mystskey", true);
+
+ FedizRequest wfReq = new FedizRequest();
+ wfReq.setAction(FederationConstants.ACTION_SIGNIN);
+ wfReq.setResponseToken(rstr);
+
+ configurator = null;
+ FedizContext config = getFederationConfigurator().getFedizContext("ROOT");
+
+ FedizProcessor wfProc = new FederationProcessorImpl();
+ FedizResponse wfRes = wfProc.processRequest(wfReq, config);
+
+ Assert.assertEquals("Principal name wrong", TEST_USER,
+ wfRes.getUsername());
+ Assert.assertEquals("Issuer wrong", TEST_RSTR_ISSUER, wfRes.getIssuer());
+ Assert.assertEquals("No roles must be found", null, wfRes.getRoles());
+ Assert.assertEquals("Audience wrong", TEST_AUDIENCE, wfRes.getAudience());
+ }
+
+ /**
+ * Validate SAML 2 token where role information is provided
+ * within another SAML attribute
+ @org.junit.Test
+ public void validateSAML2TokenDifferentRoleURI() throws Exception {
+ SAML2CallbackHandler callbackHandler = new SAML2CallbackHandler();
+ callbackHandler.setStatement(SAML2CallbackHandler.Statement.ATTR);
+ callbackHandler.setConfirmationMethod(SAML2Constants.CONF_BEARER);
+ callbackHandler.setIssuer(TEST_RSTR_ISSUER);
+ callbackHandler.setSubjectName(TEST_USER);
+ callbackHandler.setRoleAttributeName("http://schemas.mycompany.com/claims/role");
+ ConditionsBean cp = new ConditionsBean();
+ AudienceRestrictionBean audienceRestriction = new AudienceRestrictionBean();
+ audienceRestriction.getAudienceURIs().add(TEST_AUDIENCE);
+ cp.setAudienceRestrictions(Collections.singletonList(audienceRestriction));
+ callbackHandler.setConditions(cp);
+
+ SAMLCallback samlCallback = new SAMLCallback();
+ SAMLUtil.doSAMLCallback(callbackHandler, samlCallback);
+ SamlAssertionWrapper assertion = new SamlAssertionWrapper(samlCallback);
+ String rstr = createSamlToken(assertion, "mystskey", true);
+
+ FedizRequest wfReq = new FedizRequest();
+ wfReq.setAction(FederationConstants.ACTION_SIGNIN);
+ wfReq.setResponseToken(rstr);
+
+ configurator = null;
+ FedizContext config = getFederationConfigurator().getFedizContext("CUSTOMROLEURI");
+
+ FedizProcessor wfProc = new FederationProcessorImpl();
+ FedizResponse wfRes = wfProc.processRequest(wfReq, config);
+
+ Assert.assertEquals("Principal name wrong", TEST_USER, wfRes.getUsername());
+ Assert.assertEquals("Issuer wrong", TEST_RSTR_ISSUER, wfRes.getIssuer());
+ Assert.assertEquals("Two roles must be found", 2, wfRes.getRoles().size());
+ Assert.assertEquals("Audience wrong", TEST_AUDIENCE, wfRes.getAudience());
+ assertClaims(wfRes.getClaims(), callbackHandler.getRoleAttributeName());
+ }
+
+ /**
+ * Validate SAML 2 token where role information is provided
+ * within another SAML attribute
+ @org.junit.Test
+ public void validateSAML1TokenDifferentRoleURI() throws Exception {
+ SAML1CallbackHandler callbackHandler = new SAML1CallbackHandler();
+ callbackHandler.setStatement(SAML1CallbackHandler.Statement.ATTR);
+ callbackHandler.setConfirmationMethod(SAML2Constants.CONF_BEARER);
+ callbackHandler.setIssuer(TEST_RSTR_ISSUER);
+ callbackHandler.setSubjectName(TEST_USER);
+ callbackHandler.setRoleAttributeName("http://schemas.mycompany.com/claims/role");
+ ConditionsBean cp = new ConditionsBean();
+ AudienceRestrictionBean audienceRestriction = new AudienceRestrictionBean();
+ audienceRestriction.getAudienceURIs().add(TEST_AUDIENCE);
+ cp.setAudienceRestrictions(Collections.singletonList(audienceRestriction));
+ callbackHandler.setConditions(cp);
+
+ SAMLCallback samlCallback = new SAMLCallback();
+ SAMLUtil.doSAMLCallback(callbackHandler, samlCallback);
+ SamlAssertionWrapper assertion = new SamlAssertionWrapper(samlCallback);
+ String rstr = createSamlToken(assertion, "mystskey", true);
+
+ FedizRequest wfReq = new FedizRequest();
+ wfReq.setAction(FederationConstants.ACTION_SIGNIN);
+ wfReq.setResponseToken(rstr);
+
+ configurator = null;
+ FedizContext config = getFederationConfigurator().getFedizContext("CUSTOMROLEURI");
+
+ FedizProcessor wfProc = new FederationProcessorImpl();
+ FedizResponse wfRes = wfProc.processRequest(wfReq, config);
+
+ Assert.assertEquals("Principal name wrong", TEST_USER, wfRes.getUsername());
+ Assert.assertEquals("Issuer wrong", TEST_RSTR_ISSUER, wfRes.getIssuer());
+ Assert.assertEquals("Two roles must be found", 2, wfRes.getRoles().size());
+ Assert.assertEquals("Audience wrong", TEST_AUDIENCE, wfRes.getAudience());
+ assertClaims(wfRes.getClaims(), callbackHandler.getRoleAttributeName());
+ }
+
+ /**
+ * Validate SAML 2 token which includes role attribute
+ * but RoleURI is not configured
+ @org.junit.Test
+ public void validateSAML2TokenRoleURINotConfigured() throws Exception {
+ SAML2CallbackHandler callbackHandler = new SAML2CallbackHandler();
+ callbackHandler.setStatement(SAML2CallbackHandler.Statement.ATTR);
+ callbackHandler.setConfirmationMethod(SAML2Constants.CONF_BEARER);
+ callbackHandler.setIssuer(TEST_RSTR_ISSUER);
+ callbackHandler.setSubjectName(TEST_USER);
+ ConditionsBean cp = new ConditionsBean();
+ AudienceRestrictionBean audienceRestriction = new AudienceRestrictionBean();
+ audienceRestriction.getAudienceURIs().add(TEST_AUDIENCE);
+ cp.setAudienceRestrictions(Collections.singletonList(audienceRestriction));
+ callbackHandler.setConditions(cp);
+
+ SAMLCallback samlCallback = new SAMLCallback();
+ SAMLUtil.doSAMLCallback(callbackHandler, samlCallback);
+ SamlAssertionWrapper assertion = new SamlAssertionWrapper(samlCallback);
+ String rstr = createSamlToken(assertion, "mystskey", true);
+
+ FedizRequest wfReq = new FedizRequest();
+ wfReq.setAction(FederationConstants.ACTION_SIGNIN);
+ wfReq.setResponseToken(rstr);
+
+ configurator = null;
+ FedizContext config = getFederationConfigurator().getFedizContext("ROOT");
+ ((FederationProtocol)config.getProtocol()).setRoleURI(null);
+
+ FedizProcessor wfProc = new FederationProcessorImpl();
+ FedizResponse wfRes = wfProc.processRequest(wfReq, config);
+
+ Assert.assertEquals("Principal name wrong", TEST_USER,
+ wfRes.getUsername());
+ Assert.assertEquals("Issuer wrong", TEST_RSTR_ISSUER, wfRes.getIssuer());
+ Assert.assertEquals("Two roles must be found", null, wfRes.getRoles());
+ Assert.assertEquals("Audience wrong", TEST_AUDIENCE, wfRes.getAudience());
+ }
+
+ /**
+ * Validate SAML 1.1 token which includes the role attribute with 2 values
+ * Roles are encoded as a multi-value saml attribute
+ @org.junit.Test
+ public void validateSAML1Token() throws Exception {
+ SAML1CallbackHandler callbackHandler = new SAML1CallbackHandler();
+ callbackHandler.setStatement(SAML1CallbackHandler.Statement.ATTR);
+ callbackHandler.setConfirmationMethod(SAML1Constants.CONF_BEARER);
+ callbackHandler.setIssuer(TEST_RSTR_ISSUER);
+ callbackHandler.setSubjectName(TEST_USER);
+ ConditionsBean cp = new ConditionsBean();
+ AudienceRestrictionBean audienceRestriction = new AudienceRestrictionBean();
+ audienceRestriction.getAudienceURIs().add(TEST_AUDIENCE);
+ cp.setAudienceRestrictions(Collections.singletonList(audienceRestriction));
+ callbackHandler.setConditions(cp);
+
+ SAMLCallback samlCallback = new SAMLCallback();
+ SAMLUtil.doSAMLCallback(callbackHandler, samlCallback);
+ SamlAssertionWrapper assertion = new SamlAssertionWrapper(samlCallback);
+ String rstr = createSamlToken(assertion, "mystskey", true);
+
+ FedizRequest wfReq = new FedizRequest();
+ wfReq.setAction(FederationConstants.ACTION_SIGNIN);
+ wfReq.setResponseToken(rstr);
+
+ configurator = null;
+ FedizContext config = getFederationConfigurator().getFedizContext("ROOT");
+
+ FedizProcessor wfProc = new FederationProcessorImpl();
+ FedizResponse wfRes = wfProc.processRequest(wfReq, config);
+
+ Assert.assertEquals("Principal name wrong", TEST_USER,
+ wfRes.getUsername());
+ Assert.assertEquals("Issuer wrong", TEST_RSTR_ISSUER, wfRes.getIssuer());
+ Assert.assertEquals("Two roles must be found", 2, wfRes.getRoles()
+ .size());
+ Assert.assertEquals("Audience wrong", TEST_AUDIENCE, wfRes.getAudience());
+ assertClaims(wfRes.getClaims(), callbackHandler.getRoleAttributeName());
+ }
+
+ /**
+ * Validate SAML 1.1 token which includes the role attribute with 2 values
+ * Roles are encoded as a multi-value saml attribute
+ * Token embedded in RSTR 2005/02 - WS Federation 1.0
+ @org.junit.Test
+ public void validateSAML1TokenWSFed10() throws Exception {
+ SAML1CallbackHandler callbackHandler = new SAML1CallbackHandler();
+ callbackHandler.setStatement(SAML1CallbackHandler.Statement.ATTR);
+ callbackHandler.setConfirmationMethod(SAML1Constants.CONF_BEARER);
+ callbackHandler.setIssuer(TEST_RSTR_ISSUER);
+ callbackHandler.setSubjectName(TEST_USER);
+ ConditionsBean cp = new ConditionsBean();
+ AudienceRestrictionBean audienceRestriction = new AudienceRestrictionBean();
+ audienceRestriction.getAudienceURIs().add(TEST_AUDIENCE);
+ cp.setAudienceRestrictions(Collections.singletonList(audienceRestriction));
+ callbackHandler.setConditions(cp);
+
+ SAMLCallback samlCallback = new SAMLCallback();
+ SAMLUtil.doSAMLCallback(callbackHandler, samlCallback);
+ SamlAssertionWrapper assertion = new SamlAssertionWrapper(samlCallback);
+ String rstr = createSamlToken(assertion, "mystskey", true, STSUtil.SAMPLE_RSTR_2005_02_MSG);
+ FedizRequest wfReq = new FedizRequest();
+ wfReq.setAction(FederationConstants.ACTION_SIGNIN);
+ wfReq.setResponseToken(rstr);
+
+ configurator = null;
+ FedizContext config = getFederationConfigurator().getFedizContext("ROOT");
+
+ FedizProcessor wfProc = new FederationProcessorImpl();
+ FedizResponse wfRes = wfProc.processRequest(wfReq, config);
+
+ Assert.assertEquals("Principal name wrong", TEST_USER,
+ wfRes.getUsername());
+ Assert.assertEquals("Issuer wrong", TEST_RSTR_ISSUER, wfRes.getIssuer());
+ Assert.assertEquals("Two roles must be found", 2, wfRes.getRoles()
+ .size());
+ Assert.assertEquals("Audience wrong", TEST_AUDIENCE, wfRes.getAudience());
+ }
+
+ /**
+ * Validate SAML 2 token which includes the role attribute with 2 values
+ * Roles are encoded as a multiple saml attributes with the same name
+ @org.junit.Test
+ public void validateSAML2TokenRoleMultiAttributes() throws Exception {
+ SAML2CallbackHandler callbackHandler = new SAML2CallbackHandler();
+ callbackHandler.setStatement(SAML2CallbackHandler.Statement.ATTR);
+ callbackHandler.setConfirmationMethod(SAML2Constants.CONF_BEARER);
+ callbackHandler.setIssuer(TEST_RSTR_ISSUER);
+ callbackHandler.setSubjectName(TEST_USER);
+ callbackHandler.setMultiValueType(MultiValue.MULTI_ATTR);
+ ConditionsBean cp = new ConditionsBean();
+ AudienceRestrictionBean audienceRestriction = new AudienceRestrictionBean();
+ audienceRestriction.getAudienceURIs().add(TEST_AUDIENCE);
+ cp.setAudienceRestrictions(Collections.singletonList(audienceRestriction));
+ callbackHandler.setConditions(cp);
+
+ SAMLCallback samlCallback = new SAMLCallback();
+ SAMLUtil.doSAMLCallback(callbackHandler, samlCallback);
+ SamlAssertionWrapper assertion = new SamlAssertionWrapper(samlCallback);
+ String rstr = createSamlToken(assertion, "mystskey", true);
+
+ FedizRequest wfReq = new FedizRequest();
+ wfReq.setAction(FederationConstants.ACTION_SIGNIN);
+ wfReq.setResponseToken(rstr);
+
+ configurator = null;
+ FedizContext config = getFederationConfigurator().getFedizContext("ROOT");
+
+ FedizProcessor wfProc = new FederationProcessorImpl();
+ FedizResponse wfRes = wfProc.processRequest(wfReq, config);
+
+ Assert.assertEquals("Principal name wrong", TEST_USER,
+ wfRes.getUsername());
+ Assert.assertEquals("Issuer wrong", TEST_RSTR_ISSUER, wfRes.getIssuer());
+ Assert.assertEquals("Two roles must be found", 2, wfRes.getRoles()
+ .size());
+ assertClaims(wfRes.getClaims(), callbackHandler.getRoleAttributeName());
+ }
+
+ /**
+ * Validate SAML 2 token which includes the role attribute with 2 values
+ * Roles are encoded as a single saml attribute with encoded value
+ @org.junit.Test
+ public void validateSAML2TokenRoleEncodedValue() throws Exception {
+ SAML2CallbackHandler callbackHandler = new SAML2CallbackHandler();
+ callbackHandler.setStatement(SAML2CallbackHandler.Statement.ATTR);
+ callbackHandler.setConfirmationMethod(SAML2Constants.CONF_BEARER);
+ callbackHandler.setIssuer(TEST_RSTR_ISSUER);
+ callbackHandler.setSubjectName(TEST_USER);
+ callbackHandler.setMultiValueType(MultiValue.ENC_VALUE);
+ ConditionsBean cp = new ConditionsBean();
+ AudienceRestrictionBean audienceRestriction = new AudienceRestrictionBean();
+ audienceRestriction.getAudienceURIs().add(TEST_AUDIENCE);
+ cp.setAudienceRestrictions(Collections.singletonList(audienceRestriction));
+ callbackHandler.setConditions(cp);
+
+ SAMLCallback samlCallback = new SAMLCallback();
+ SAMLUtil.doSAMLCallback(callbackHandler, samlCallback);
+ SamlAssertionWrapper assertion = new SamlAssertionWrapper(samlCallback);
+ String rstr = createSamlToken(assertion, "mystskey", true);
+
+ FedizRequest wfReq = new FedizRequest();
+ wfReq.setAction(FederationConstants.ACTION_SIGNIN);
+ wfReq.setResponseToken(rstr);
+
+ configurator = null;
+ FedizContext config = getFederationConfigurator().getFedizContext("ROOT");
+ FederationProtocol fp = (FederationProtocol)config.getProtocol();
+ fp.setRoleDelimiter(",");
+
+ FedizProcessor wfProc = new FederationProcessorImpl();
+ FedizResponse wfRes = wfProc.processRequest(wfReq, config);
+
+ Assert.assertEquals("Principal name wrong", TEST_USER,
+ wfRes.getUsername());
+ Assert.assertEquals("Issuer wrong", TEST_RSTR_ISSUER, wfRes.getIssuer());
+ Assert.assertEquals("Two roles must be found", 2, wfRes.getRoles()
+ .size());
+ assertClaims(wfRes.getClaims(), callbackHandler.getRoleAttributeName());
+ }
+
+ /**
+ * Validate SAML 2 token which includes the role attribute with 2 values
+ * The configured subject of the trusted issuer doesn't match with
+ * the issuer of the SAML token
+ @org.junit.Test
+ public void validateUnsignedSAML2Token() throws Exception {
+ SAML2CallbackHandler callbackHandler = new SAML2CallbackHandler();
+ callbackHandler.setStatement(SAML2CallbackHandler.Statement.ATTR);
+ callbackHandler.setConfirmationMethod(SAML2Constants.CONF_BEARER);
+ callbackHandler.setIssuer(TEST_RSTR_ISSUER);
+ callbackHandler.setSubjectName(TEST_USER);
+ ConditionsBean cp = new ConditionsBean();
+ AudienceRestrictionBean audienceRestriction = new AudienceRestrictionBean();
+ audienceRestriction.getAudienceURIs().add(TEST_AUDIENCE);
+ cp.setAudienceRestrictions(Collections.singletonList(audienceRestriction));
+ callbackHandler.setConditions(cp);
+
+ SAMLCallback samlCallback = new SAMLCallback();
+ SAMLUtil.doSAMLCallback(callbackHandler, samlCallback);
+ SamlAssertionWrapper assertion = new SamlAssertionWrapper(samlCallback);
+
+ String rstr = createSamlToken(assertion, "mystskey", false);
+ FedizRequest wfReq = new FedizRequest();
+ wfReq.setAction(FederationConstants.ACTION_SIGNIN);
+ wfReq.setResponseToken(rstr);
+
+ // Load and update the config to enforce an error
+ configurator = null;
+ FedizContext config = getFederationConfigurator().getFedizContext("ROOT");
+
+ FedizProcessor wfProc = new FederationProcessorImpl();
+ try {
+ wfProc.processRequest(wfReq, config);
+ Assert.fail("Processing must fail because of missing signature");
+ } catch (ProcessingException ex) {
+ if (!TYPE.TOKEN_NO_SIGNATURE.equals(ex.getType())) {
+ fail("Expected ProcessingException with TOKEN_NO_SIGNATURE type");
+ }
+ }
+ }
+
+ /**
+ * Validate SAML 2 token twice which causes an exception
+ * due to replay attack
+ @org.junit.Test
+ public void testReplayAttack() throws Exception {
+ SAML2CallbackHandler callbackHandler = new SAML2CallbackHandler();
+ callbackHandler.setStatement(SAML2CallbackHandler.Statement.ATTR);
+ callbackHandler.setConfirmationMethod(SAML2Constants.CONF_BEARER);
+ callbackHandler.setIssuer(TEST_RSTR_ISSUER);
+ callbackHandler.setSubjectName(TEST_USER);
+ ConditionsBean cp = new ConditionsBean();
+ AudienceRestrictionBean audienceRestriction = new AudienceRestrictionBean();
+ audienceRestriction.getAudienceURIs().add(TEST_AUDIENCE);
+ cp.setAudienceRestrictions(Collections.singletonList(audienceRestriction));
+ callbackHandler.setConditions(cp);
+
+ SAMLCallback samlCallback = new SAMLCallback();
+ SAMLUtil.doSAMLCallback(callbackHandler, samlCallback);
+ SamlAssertionWrapper assertion = new SamlAssertionWrapper(samlCallback);
+
+ String rstr = createSamlToken(assertion, "mystskey", true);
+
+ FedizRequest wfReq = new FedizRequest();
+ wfReq.setAction(FederationConstants.ACTION_SIGNIN);
+ wfReq.setResponseToken(rstr);
+
+ configurator = null;
+ FedizContext config = getFederationConfigurator().getFedizContext("ROOT");
+
+ FedizProcessor wfProc = new FederationProcessorImpl();
+ FedizResponse wfRes = wfProc.processRequest(wfReq, config);
+ Assert.assertEquals("Principal name wrong", TEST_USER,
+ wfRes.getUsername());
+ Assert.assertEquals("Issuer wrong", TEST_RSTR_ISSUER, wfRes.getIssuer());
+
+ wfProc = new FederationProcessorImpl();
+ try {
+ wfProc.processRequest(wfReq, config);
+ fail("Failure expected on a replay attack");
+ } catch (ProcessingException ex) {
+ if (!TYPE.TOKEN_REPLAY.equals(ex.getType())) {
+ fail("Expected ProcessingException with TOKEN_REPLAY type");
+ }
+ }
+ }
+
+
+ /**
+ * Validate SAML 2 token which includes the role attribute with 2 values
+ * The configured subject of the trusted issuer doesn't match with
+ * the issuer of the SAML token
+ @org.junit.Test
+ public void validateSAML2TokenSeveralCertStore() throws Exception {
+ SAML2CallbackHandler callbackHandler = new SAML2CallbackHandler();
+ callbackHandler.setStatement(SAML2CallbackHandler.Statement.ATTR);
+ callbackHandler.setConfirmationMethod(SAML2Constants.CONF_BEARER);
+ callbackHandler.setIssuer(TEST_RSTR_ISSUER);
+ callbackHandler.setSubjectName(TEST_USER);
+ ConditionsBean cp = new ConditionsBean();
+ AudienceRestrictionBean audienceRestriction = new AudienceRestrictionBean();
+ audienceRestriction.getAudienceURIs().add(TEST_AUDIENCE);
+ cp.setAudienceRestrictions(Collections.singletonList(audienceRestriction));
+ callbackHandler.setConditions(cp);
+
+ SAMLCallback samlCallback = new SAMLCallback();
+ SAMLUtil.doSAMLCallback(callbackHandler, samlCallback);
+ SamlAssertionWrapper assertion = new SamlAssertionWrapper(samlCallback);
+
+ String rstr = createSamlToken(assertion, "mystskey", true);
+ FedizRequest wfReq = new FedizRequest();
+ wfReq.setAction(FederationConstants.ACTION_SIGNIN);
+ wfReq.setResponseToken(rstr);
+
+ // Load and update the config to enforce an error
+ configurator = null;
+ FedizContext config = getFederationConfigurator().getFedizContext("ROOT2");
+
+ FedizProcessor wfProc = new FederationProcessorImpl();
+ FedizResponse wfRes = wfProc.processRequest(wfReq, config);
+
+ Assert.assertEquals("Principal name wrong", TEST_USER,
+ wfRes.getUsername());
+ Assert.assertEquals("Issuer wrong", TEST_RSTR_ISSUER, wfRes.getIssuer());
+ Assert.assertEquals("Two roles must be found", 2, wfRes.getRoles()
+ .size());
+ }
+
+ /**
+ * Validate SAML 2 token which includes the role attribute with 2 values
+ * The configured subject of the trusted issuer doesn't match with
+ * the issuer of the SAML token
+ @org.junit.Test
+ public void validateSAML2TokenSeveralCertStoreTrustedIssuer() throws Exception {
+ SAML2CallbackHandler callbackHandler = new SAML2CallbackHandler();
+ callbackHandler.setStatement(SAML2CallbackHandler.Statement.ATTR);
+ callbackHandler.setConfirmationMethod(SAML2Constants.CONF_BEARER);
+ callbackHandler.setIssuer(TEST_RSTR_ISSUER);
+ callbackHandler.setSubjectName(TEST_USER);
+ ConditionsBean cp = new ConditionsBean();
+ AudienceRestrictionBean audienceRestriction = new AudienceRestrictionBean();
+ audienceRestriction.getAudienceURIs().add(TEST_AUDIENCE);
+ cp.setAudienceRestrictions(Collections.singletonList(audienceRestriction));
+ callbackHandler.setConditions(cp);
+
+ SAMLCallback samlCallback = new SAMLCallback();
+ SAMLUtil.doSAMLCallback(callbackHandler, samlCallback);
+ SamlAssertionWrapper assertion = new SamlAssertionWrapper(samlCallback);
+
+ String rstr = createSamlToken(assertion, "mystskey", true);
+ FedizRequest wfReq = new FedizRequest();
+ wfReq.setAction(FederationConstants.ACTION_SIGNIN);
+ wfReq.setResponseToken(rstr);
+
+ // Load and update the config to enforce an error
+ configurator = null;
+ FedizContext config = getFederationConfigurator().getFedizContext("ROOT3");
+
+ FedizProcessor wfProc = new FederationProcessorImpl();
+ FedizResponse wfRes = wfProc.processRequest(wfReq, config);
+
+ Assert.assertEquals("Principal name wrong", TEST_USER,
+ wfRes.getUsername());
+ Assert.assertEquals("Issuer wrong", TEST_RSTR_ISSUER, wfRes.getIssuer());
+ Assert.assertEquals("Two roles must be found", 2, wfRes.getRoles()
+ .size());
+ }
+
+ /**
+ * Validate SAML 2 token which is expired
+ @org.junit.Test
+ public void validateSAML2TokenExpired() throws Exception {
+ SAML2CallbackHandler callbackHandler = new SAML2CallbackHandler();
+ callbackHandler.setStatement(SAML2CallbackHandler.Statement.ATTR);
+ callbackHandler.setConfirmationMethod(SAML2Constants.CONF_BEARER);
+ callbackHandler.setIssuer(TEST_RSTR_ISSUER);
+ callbackHandler.setSubjectName(TEST_USER);
+ ConditionsBean cp = new ConditionsBean();
+ DateTime currentTime = new DateTime();
+ currentTime = currentTime.minusSeconds(60);
+ cp.setNotAfter(currentTime);
+ currentTime = new DateTime();
+ currentTime = currentTime.minusSeconds(300);
+ cp.setNotBefore(currentTime);
+ AudienceRestrictionBean audienceRestriction = new AudienceRestrictionBean();
+ audienceRestriction.getAudienceURIs().add(TEST_AUDIENCE);
+ cp.setAudienceRestrictions(Collections.singletonList(audienceRestriction));
+ callbackHandler.setConditions(cp);
+
+ SAMLCallback samlCallback = new SAMLCallback();
+ SAMLUtil.doSAMLCallback(callbackHandler, samlCallback);
+ SamlAssertionWrapper assertion = new SamlAssertionWrapper(samlCallback);
+
+ String rstr = createSamlToken(assertion, "mystskey", true);
+
+ FedizRequest wfReq = new FedizRequest();
+ wfReq.setAction(FederationConstants.ACTION_SIGNIN);
+ wfReq.setResponseToken(rstr);
+
+ configurator = null;
+ FedizContext config = getFederationConfigurator().getFedizContext("ROOT");
+
+ FedizProcessor wfProc = new FederationProcessorImpl();
+ try {
+ wfProc.processRequest(wfReq, config);
+ fail("Failure expected on expired SAML token");
+ } catch (ProcessingException ex) {
+ if (!TYPE.TOKEN_EXPIRED.equals(ex.getType())) {
+ fail("Expected ProcessingException with TOKEN_EXPIRED type");
+ }
+ }
+ }
+
+ /**
+ * Validate SAML 2 token which is not yet valid (in 30 seconds)
+ * but within the maximum clock skew range (60 seconds)
+ @org.junit.Test
+ public void validateSAML2TokenClockSkewRange() throws Exception {
+ SAML2CallbackHandler callbackHandler = new SAML2CallbackHandler();
+ callbackHandler.setStatement(SAML2CallbackHandler.Statement.ATTR);
+ callbackHandler.setConfirmationMethod(SAML2Constants.CONF_BEARER);
+ callbackHandler.setIssuer(TEST_RSTR_ISSUER);
+ callbackHandler.setSubjectName(TEST_USER);
+ ConditionsBean cp = new ConditionsBean();
+ DateTime currentTime = new DateTime();
+ currentTime = currentTime.plusSeconds(300);
+ cp.setNotAfter(currentTime);
+ currentTime = new DateTime();
+ currentTime = currentTime.plusSeconds(30);
+ cp.setNotBefore(currentTime);
+ AudienceRestrictionBean audienceRestriction = new AudienceRestrictionBean();
+ audienceRestriction.getAudienceURIs().add(TEST_AUDIENCE);
+ cp.setAudienceRestrictions(Collections.singletonList(audienceRestriction));
+ callbackHandler.setConditions(cp);
+
+ SAMLCallback samlCallback = new SAMLCallback();
+ SAMLUtil.doSAMLCallback(callbackHandler, samlCallback);
+ SamlAssertionWrapper assertion = new SamlAssertionWrapper(samlCallback);
+
+ String rstr = createSamlToken(assertion, "mystskey", true);
+
+ FedizRequest wfReq = new FedizRequest();
+ wfReq.setAction(FederationConstants.ACTION_SIGNIN);
+ wfReq.setResponseToken(rstr);
+
+ configurator = null;
+ FedizContext config = getFederationConfigurator().getFedizContext("ROOT");
+ config.setMaximumClockSkew(BigInteger.valueOf(60));
+
+ FedizProcessor wfProc = new FederationProcessorImpl();
+ FedizResponse wfRes = wfProc.processRequest(wfReq, config);
+
+ Assert.assertEquals("Principal name wrong", TEST_USER,
+ wfRes.getUsername());
+ Assert.assertEquals("Issuer wrong", TEST_RSTR_ISSUER, wfRes.getIssuer());
+ Assert.assertEquals("Two roles must be found", 2, wfRes.getRoles()
+ .size());
+ }
+
+ /**
+ * "Validate" SAML 2 token with a custom token validator
+ * If a validator is configured it precedes the SAMLTokenValidator as part of Fediz
+ @org.junit.Test
+ public void validateSAML2TokenCustomValidator() throws Exception {
+ SAML2CallbackHandler callbackHandler = new SAML2CallbackHandler();
+ callbackHandler.setStatement(SAML2CallbackHandler.Statement.ATTR);
+ callbackHandler.setConfirmationMethod(SAML2Constants.CONF_BEARER);
+ callbackHandler.setIssuer(TEST_RSTR_ISSUER);
+ callbackHandler.setSubjectName(TEST_USER);
+ ConditionsBean cp = new ConditionsBean();
+ AudienceRestrictionBean audienceRestriction = new AudienceRestrictionBean();
+ audienceRestriction.getAudienceURIs().add(TEST_AUDIENCE);
+ cp.setAudienceRestrictions(Collections.singletonList(audienceRestriction));
+ callbackHandler.setConditions(cp);
+
+ SAMLCallback samlCallback = new SAMLCallback();
+ SAMLUtil.doSAMLCallback(callbackHandler, samlCallback);
+ SamlAssertionWrapper assertion = new SamlAssertionWrapper(samlCallback);
+
+ String rstr = createSamlToken(assertion, "mystskey", true);
+
+ FedizRequest wfReq = new FedizRequest();
+ wfReq.setAction(FederationConstants.ACTION_SIGNIN);
+ wfReq.setResponseToken(rstr);
+
+ configurator = null;
+ FedizContext config = getFederationConfigurator().getFedizContext("CUSTTOK");
+ FederationProtocol fp = (FederationProtocol)config.getProtocol();
+ List<TokenValidator> validators = fp.getTokenValidators();
+ Assert.assertEquals("Two validators must be found", 2, validators.size());
+ Assert.assertEquals("First validator must be custom validator",
+ CustomValidator.class.getName(), validators.get(0).getClass().getName());
+
+ FedizProcessor wfProc = new FederationProcessorImpl();
+ FedizResponse wfRes = wfProc.processRequest(wfReq, config);
+
+ Assert.assertEquals("Principal name wrong", TEST_USER,
+ wfRes.getUsername());
+ Assert.assertEquals("Issuer wrong", TEST_RSTR_ISSUER, wfRes.getIssuer());
+ }
+
+ /**
+ * "Validate" SAML 2 token with a custom token validator
+ * If a validator is configured it precedes the SAMLTokenValidator as part of Fediz
+ @org.junit.Test
+ public void validateSAML2TokenMaxClockSkewNotDefined() throws Exception {
+ SAML2CallbackHandler callbackHandler = new SAML2CallbackHandler();
+ callbackHandler.setStatement(SAML2CallbackHandler.Statement.ATTR);
+ callbackHandler.setConfirmationMethod(SAML2Constants.CONF_BEARER);
+ callbackHandler.setIssuer(TEST_RSTR_ISSUER);
+ callbackHandler.setSubjectName(TEST_USER);
+ ConditionsBean cp = new ConditionsBean();
+ AudienceRestrictionBean audienceRestriction = new AudienceRestrictionBean();
+ audienceRestriction.getAudienceURIs().add(TEST_AUDIENCE);
+ cp.setAudienceRestrictions(Collections.singletonList(audienceRestriction));
+ callbackHandler.setConditions(cp);
+
+ SAMLCallback samlCallback = new SAMLCallback();
+ SAMLUtil.doSAMLCallback(callbackHandler, samlCallback);
+ SamlAssertionWrapper assertion = new SamlAssertionWrapper(samlCallback);
+
+ String rstr = createSamlToken(assertion, "mystskey", true);
+
+ FedizRequest wfReq = new FedizRequest();
+ wfReq.setAction(FederationConstants.ACTION_SIGNIN);
+ wfReq.setResponseToken(rstr);
+
+ configurator = null;
+ FedizContext config = getFederationConfigurator().getFedizContext("NOCLOCKSKEW");
+
+ FedizProcessor wfProc = new FederationProcessorImpl();
+ FedizResponse wfRes = wfProc.processRequest(wfReq, config);
+
+ Assert.assertEquals("Principal name wrong", TEST_USER,
+ wfRes.getUsername());
+ Assert.assertEquals("Issuer wrong", TEST_RSTR_ISSUER, wfRes.getIssuer());
+ Assert.assertEquals("Two roles must be found", 2, wfRes.getRoles()
+ .size());
+ Assert.assertEquals("Audience wrong", TEST_AUDIENCE, wfRes.getAudience());
+ }
+
+ /**
+ * Validate an encrypted SAML 2 token which includes the role attribute with 2 values
+ * Roles are encoded as a multi-value saml attribute
+ @org.junit.Test
+ public void validateEncryptedSAML2Token() throws Exception {
+ SAML2CallbackHandler callbackHandler = new SAML2CallbackHandler();
+ callbackHandler.setStatement(SAML2CallbackHandler.Statement.ATTR);
+ callbackHandler.setConfirmationMethod(SAML2Constants.CONF_BEARER);
+ callbackHandler.setIssuer(TEST_RSTR_ISSUER);
+ callbackHandler.setSubjectName(TEST_USER);
+ ConditionsBean cp = new ConditionsBean();
+ AudienceRestrictionBean audienceRestriction = new AudienceRestrictionBean();
+ audienceRestriction.getAudienceURIs().add(TEST_AUDIENCE);
+ cp.setAudienceRestrictions(Collections.singletonList(audienceRestriction));
+ callbackHandler.setConditions(cp);
+
+ SAMLCallback samlCallback = new SAMLCallback();
+ SAMLUtil.doSAMLCallback(callbackHandler, samlCallback);
+ SamlAssertionWrapper assertion = new SamlAssertionWrapper(samlCallback);
+
+ String rstr = encryptAndSignToken(assertion);
+
+ FedizRequest wfReq = new FedizRequest();
+ wfReq.setAction(FederationConstants.ACTION_SIGNIN);
+ wfReq.setResponseToken(rstr);
+
+ configurator = null;
+ FedizContext config =
+ getFederationConfigurator().getFedizContext("ROOT_DECRYPTION");
+
+ FedizProcessor wfProc = new FederationProcessorImpl();
+ FedizResponse wfRes = wfProc.processRequest(wfReq, config);
+
+ Assert.assertEquals("Principal name wrong", TEST_USER,
+ wfRes.getUsername());
+ Assert.assertEquals("Issuer wrong", TEST_RSTR_ISSUER, wfRes.getIssuer());
+ Assert.assertEquals("Two roles must be found", 2, wfRes.getRoles()
+ .size());
+ Assert.assertEquals("Audience wrong", TEST_AUDIENCE, wfRes.getAudience());
+ assertClaims(wfRes.getClaims(), callbackHandler.getRoleAttributeName());
+ }
+
+ /**
+ * Validate a HolderOfKey SAML 2 token
+ @org.junit.Test
+ public void validateHOKSAML2Token() throws Exception {
+ SAML2CallbackHandler callbackHandler = new SAML2CallbackHandler();
+ callbackHandler.setStatement(SAML2CallbackHandler.Statement.AUTHN);
+ callbackHandler.setConfirmationMethod(SAML2Constants.CONF_HOLDER_KEY);
+ callbackHandler.setIssuer(TEST_RSTR_ISSUER);
+ callbackHandler.setSubjectName(TEST_USER);
+ ConditionsBean cp = new ConditionsBean();
+ AudienceRestrictionBean audienceRestriction = new AudienceRestrictionBean();
+ audienceRestriction.getAudienceURIs().add(TEST_AUDIENCE);
+ cp.setAudienceRestrictions(Collections.singletonList(audienceRestriction));
+ callbackHandler.setConditions(cp);
+
+ Crypto clientCrypto = CryptoFactory.getInstance("client-crypto.properties");
+ CryptoType cryptoType = new CryptoType(CryptoType.TYPE.ALIAS);
+ cryptoType.setAlias("myclientkey");
+ X509Certificate[] certs = clientCrypto.getX509Certificates(cryptoType);
+ callbackHandler.setCerts(certs);
+
+ 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);
+
+ Document doc = STSUtil.toSOAPPart(STSUtil.SAMPLE_RSTR_COLL_MSG);
+ Element token = assertion.toDOM(doc);
+
+ Element e = SAMLProcessorTest.findElement(doc, "RequestedSecurityToken",
+ FederationConstants.WS_TRUST_13_NS);
+ if (e == null) {
+ e = SAMLProcessorTest.findElement(doc, "RequestedSecurityToken",
+ FederationConstants.WS_TRUST_2005_02_NS);
+ }
+ e.appendChild(token);
+
+ String rstr = DOM2Writer.nodeToString(doc);
+
+ FedizRequest wfReq = new FedizRequest();
+ wfReq.setAction(FederationConstants.ACTION_SIGNIN);
+ wfReq.setResponseToken(rstr);
+
+ configurator = null;
+ FedizContext config =
+ getFederationConfigurator().getFedizContext("ROOT_DECRYPTION");
+
+ FedizProcessor wfProc = new FederationProcessorImpl();
+ try {
+ wfProc.processRequest(wfReq, config);
+ fail("Failure expected on missing client certs");
+ } catch (ProcessingException ex) {
+ // expected
+ }
+
+ // Now set client certs
+ wfReq.setCerts(certs);
+ wfProc.processRequest(wfReq, config);
+ }
+
+ @org.junit.Test
+ public void validateSAML2TokenWithConfigCreatedWithAPI() throws Exception {
+
+ ContextConfig config = new ContextConfig();
+
+ config.setName("whatever");
+
+ // Configure certificate store
+ CertificateStores certStores = new CertificateStores();
+ TrustManagersType tm0 = new TrustManagersType();
+ KeyStoreType ks0 = new KeyStoreType();
+ ks0.setType("JKS");
+ ks0.setPassword("storepass");
+ ks0.setFile("ststrust.jks");
+ tm0.setKeyStore(ks0);
+ certStores.getTrustManager().add(tm0);
+ config.setCertificateStores(certStores);
+
+ // Configure trusted IDP
+ TrustedIssuers trustedIssuers = new TrustedIssuers();
+ TrustedIssuerType ti0 = new TrustedIssuerType();
+ ti0.setCertificateValidation(ValidationType.CHAIN_TRUST);
+ ti0.setName("FedizSTSIssuer");
+ ti0.setSubject(".*CN=www.sts.com.*");
+ trustedIssuers.getIssuer().add(ti0);
+ config.setTrustedIssuers(trustedIssuers);
+
+ FederationProtocolType protocol = new FederationProtocolType();
+ config.setProtocol(protocol);
+
+ AudienceUris audienceUris = new AudienceUris();
+ audienceUris.getAudienceItem().add("https://localhost/fedizhelloworld");
+ config.setAudienceUris(audienceUris);
+
+ protocol.setRoleURI("http://schemas.xmlsoap.org/ws/2005/05/identity/claims/role");
+
+ FedizContext fedContext = new FedizContext(config);
+ fedContext.init();
+
+ SAML2CallbackHandler callbackHandler = new SAML2CallbackHandler();
+ callbackHandler.setStatement(SAML2CallbackHandler.Statement.ATTR);
+ callbackHandler.setConfirmationMethod(SAML2Constants.CONF_BEARER);
+ callbackHandler.setIssuer(TEST_RSTR_ISSUER);
+ callbackHandler.setSubjectName(TEST_USER);
+ ConditionsBean cp = new ConditionsBean();
+ AudienceRestrictionBean audienceRestriction = new AudienceRestrictionBean();
+ audienceRestriction.getAudienceURIs().add(TEST_AUDIENCE);
+ cp.setAudienceRestrictions(Collections.singletonList(audienceRestriction));
+ callbackHandler.setConditions(cp);
+
+ SAMLCallback samlCallback = new SAMLCallback();
+ SAMLUtil.doSAMLCallback(callbackHandler, samlCallback);
+ SamlAssertionWrapper assertion = new SamlAssertionWrapper(samlCallback);
+
+ String rstr = createSamlToken(assertion, "mystskey", true, STSUtil.SAMPLE_RSTR_MSG);
+
+ FedizRequest wfReq = new FedizRequest();
+ wfReq.setAction(FederationConstants.ACTION_SIGNIN);
+ wfReq.setResponseToken(rstr);
+
+ FedizProcessor wfProc = new FederationProcessorImpl();
+ FedizResponse wfRes = wfProc.processRequest(wfReq, fedContext);
+
+ Assert.assertEquals("Principal name wrong", TEST_USER,
+ wfRes.getUsername());
+ Assert.assertEquals("Issuer wrong", TEST_RSTR_ISSUER, wfRes.getIssuer());
+ Assert.assertEquals("Two roles must be found", 2, wfRes.getRoles()
+ .size());
+ Assert.assertEquals("Audience wrong", TEST_AUDIENCE, wfRes.getAudience());
+
+ fedContext.close();
+
+ }
+ */
+
+ private String createSamlResponseStr(String requestId) throws Exception {
+ // Create SAML Assertion
+ 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);
+ Element response = createSamlResponse(assertion, "mystskey", true, requestId);
+ return encodeResponse(response);
+ }
+
+ private Element createSamlResponse(SamlAssertionWrapper assertion, String alias,
+ boolean sign, String requestID)
+ 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
+ );
+ Response response =
+ SAML2PResponseComponentBuilder.createSAMLResponse(requestID,
+ assertion.getIssuerString(),
+ 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 void assertClaims(List<Claim> claims, String roleClaimType) {
+ for (Claim c : claims) {
+ Assert.assertTrue("Invalid ClaimType URI: " + c.getClaimType(),
+ c.getClaimType().equals(roleClaimType)
+ || c.getClaimType().equals(ClaimTypes.COUNTRY)
+ || c.getClaimType().equals(AbstractSAMLCallbackHandler.CLAIM_TYPE_LANGUAGE)
+ );
+ }
+ }
+
+ private String encodeResponse(Element response) throws IOException {
+ String responseMessage = DOM2Writer.nodeToString(response);
+
+ byte[] deflatedBytes = CompressionUtils.deflate(responseMessage.getBytes("UTF-8"));
+
+ return Base64.encode(deflatedBytes);
+ }
+
+
+}
http://git-wip-us.apache.org/repos/asf/cxf-fediz/blob/617fd4e9/plugins/core/src/test/java/org/apache/cxf/fediz/core/samlsso/SAMLSSOTestUtils.java
----------------------------------------------------------------------
diff --git a/plugins/core/src/test/java/org/apache/cxf/fediz/core/samlsso/SAMLSSOTestUtils.java b/plugins/core/src/test/java/org/apache/cxf/fediz/core/samlsso/SAMLSSOTestUtils.java
new file mode 100644
index 0000000..842dcd8
--- /dev/null
+++ b/plugins/core/src/test/java/org/apache/cxf/fediz/core/samlsso/SAMLSSOTestUtils.java
@@ -0,0 +1,41 @@
+/**
+ * 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;
+
+
+public final class SAMLSSOTestUtils {
+
+
+ public static final String SAMPLE_EMPTY_SAML_RESPONSE =
+ "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
+ + "<saml2p:Response ID=\"c4b78949-d52e-4ae0-ad44-04ef58fe1ca8\" "
+ + "InResponseTo=\"612223b6-fb12-4c40-9a31-9bd94e09a579\" "
+ + "IssueInstant=\"2014-07-22T15:32:52.933Z\" Version=\"2.0\" "
+ + "xmlns:saml2p=\"urn:oasis:names:tc:SAML:2.0:protocol\">"
+ + "<saml2:Issuer xmlns:saml2=\"urn:oasis:names:tc:SAML:2.0:assertion\">"
+ + "http://localhost:12345/idp/samlsso</saml2:Issuer><saml2p:Status>"
+ + "<saml2p:StatusCode Value=\"urn:oasis:names:tc:SAML:2.0:status:Success\"/>"
+ + "</saml2p:Status></saml2p:Response>";
+
+ private SAMLSSOTestUtils() {
+
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/cxf-fediz/blob/617fd4e9/plugins/core/src/test/resources/fediz_test_config.xml
----------------------------------------------------------------------
diff --git a/plugins/core/src/test/resources/fediz_test_config.xml b/plugins/core/src/test/resources/fediz_test_config.xml
index d2f83d2..48622a7 100644
--- a/plugins/core/src/test/resources/fediz_test_config.xml
+++ b/plugins/core/src/test/resources/fediz_test_config.xml
@@ -133,7 +133,7 @@
<claimType type="a particular claim type" optional="true" />
</claimTypesRequested>
<tokenValidators>
- <validator>org.apache.cxf.fediz.core.CustomValidator</validator>
+ <validator>org.apache.cxf.fediz.core.federation.CustomValidator</validator>
<validator>org.apache.cxf.fediz.core.NonexistentCustomValidator</validator>
</tokenValidators>
</protocol>
http://git-wip-us.apache.org/repos/asf/cxf-fediz/blob/617fd4e9/plugins/core/src/test/resources/fediz_test_config_saml.xml
----------------------------------------------------------------------
diff --git a/plugins/core/src/test/resources/fediz_test_config_saml.xml b/plugins/core/src/test/resources/fediz_test_config_saml.xml
new file mode 100644
index 0000000..8c971d6
--- /dev/null
+++ b/plugins/core/src/test/resources/fediz_test_config_saml.xml
@@ -0,0 +1,196 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<FedizConfig>
+ <contextConfig name="ROOT">
+ <audienceUris>
+ <audienceItem>http://host_one:port/url</audienceItem>
+ </audienceUris>
+ <certificateStores>
+ <trustManager>
+ <keyStore file="ststrust.jks" password="storepass"
+ type="JKS" />
+ </trustManager>
+ </certificateStores>
+ <trustedIssuers>
+ <issuer certificateValidation="PeerTrust" />
+ </trustedIssuers>
+
+ <maximumClockSkew>1000</maximumClockSkew>
+ <protocol xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:type="samlProtocolType" version="1.2">
+ <issuer>http://url_to_the_issuer</issuer>
+ <roleDelimiter>;</roleDelimiter>
+ <roleURI>http://schemas.xmlsoap.org/ws/2005/05/identity/claims/role</roleURI>
+ <claimTypesRequested>
+ <claimType type="a particular claim type" optional="true" />
+ </claimTypesRequested>
+ </protocol>
+ </contextConfig>
+
+ <contextConfig name="ROOT2">
+ <audienceUris>
+ <audienceItem>http://host_one:port/url</audienceItem>
+ </audienceUris>
+ <certificateStores>
+ <trustManager>
+ <keyStore file="stsrealm_a.jks" password="storepass"
+ type="JKS" />
+ </trustManager>
+ <trustManager>
+ <keyStore file="ststrust.jks" password="storepass"
+ type="JKS" />
+ </trustManager>
+ </certificateStores>
+ <trustedIssuers>
+ <issuer certificateValidation="PeerTrust" />
+ </trustedIssuers>
+
+ <maximumClockSkew>1000</maximumClockSkew>
+ <protocol xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:type="samlProtocolType" version="1.2">
+ <issuer>http://url_to_the_issuer</issuer>
+ <roleDelimiter>;</roleDelimiter>
+ <roleURI>http://schemas.xmlsoap.org/ws/2005/05/identity/claims/role</roleURI>
+ <claimTypesRequested>
+ <claimType type="a particular claim type" optional="true" />
+ </claimTypesRequested>
+ </protocol>
+ </contextConfig>
+
+ <contextConfig name="ROOT3">
+ <audienceUris>
+ <audienceItem>http://host_one:port/url</audienceItem>
+ </audienceUris>
+ <certificateStores>
+ <trustManager>
+ <keyStore file="stsrealm_a.jks" password="storepass"
+ type="JKS" />
+ </trustManager>
+ <trustManager>
+ <keyStore file="ststrust.jks" password="storepass"
+ type="JKS" />
+ </trustManager>
+ </certificateStores>
+ <trustedIssuers>
+ <issuer certificateValidation="PeerTrust" />
+ </trustedIssuers>
+
+ <maximumClockSkew>1000</maximumClockSkew>
+ <protocol xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:type="samlProtocolType" version="1.2">
+ <issuer>http://url_to_the_issuer</issuer>
+ <roleDelimiter>;</roleDelimiter>
+ <roleURI>http://schemas.xmlsoap.org/ws/2005/05/identity/claims/role</roleURI>
+ <claimTypesRequested>
+ <claimType type="a particular claim type" optional="true" />
+ </claimTypesRequested>
+ </protocol>
+ </contextConfig>
+ <contextConfig name="CUSTTOK">
+ <audienceUris>
+ <audienceItem>http://host_one:port/url</audienceItem>
+ </audienceUris>
+ <certificateStores>
+ <trustManager>
+ <keyStore file="ststrust.jks" password="storepass"
+ type="JKS" />
+ </trustManager>
+ </certificateStores>
+ <trustedIssuers>
+ <issuer certificateValidation="PeerTrust" />
+ </trustedIssuers>
+
+ <maximumClockSkew>1000</maximumClockSkew>
+ <protocol xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:type="samlProtocolType" version="1.2">
+ <issuer>http://url_to_the_issuer</issuer>
+ <roleDelimiter>;</roleDelimiter>
+ <roleURI>http://schemas.xmlsoap.org/ws/2005/05/identity/claims/role</roleURI>
+ <claimTypesRequested>
+ <claimType type="a particular claim type" optional="true" />
+ </claimTypesRequested>
+ <tokenValidators>
+ <validator>org.apache.cxf.fediz.core.CustomValidator</validator>
+ <validator>org.apache.cxf.fediz.core.NonexistentCustomValidator</validator>
+ </tokenValidators>
+ </protocol>
+ </contextConfig>
+ <contextConfig name="NOCLOCKSKEW">
+ <audienceUris>
+ <audienceItem>http://host_one:port/url</audienceItem>
+ </audienceUris>
+ <certificateStores>
+ <trustManager>
+ <keyStore file="ststrust.jks" password="storepass"
+ type="JKS" />
+ </trustManager>
+ </certificateStores>
+ <trustedIssuers>
+ <issuer certificateValidation="PeerTrust" />
+ </trustedIssuers>
+
+ <protocol xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:type="samlProtocolType" version="1.2">
+ <issuer>http://url_to_the_issuer</issuer>
+ <roleDelimiter>;</roleDelimiter>
+ <roleURI>http://schemas.xmlsoap.org/ws/2005/05/identity/claims/role</roleURI>
+ <claimTypesRequested>
+ <claimType type="a particular claim type" optional="true" />
+ </claimTypesRequested>
+ </protocol>
+ </contextConfig>
+ <contextConfig name="CUSTOMROLEURI">
+ <audienceUris>
+ <audienceItem>http://host_one:port/url</audienceItem>
+ </audienceUris>
+ <certificateStores>
+ <trustManager>
+ <keyStore file="ststrust.jks" password="storepass"
+ type="JKS" />
+ </trustManager>
+ </certificateStores>
+ <trustedIssuers>
+ <issuer certificateValidation="PeerTrust" />
+ </trustedIssuers>
+
+ <maximumClockSkew>1000</maximumClockSkew>
+ <protocol xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:type="samlProtocolType" version="1.2">
+ <issuer>http://url_to_the_issuer</issuer>
+ <roleDelimiter>;</roleDelimiter>
+ <roleURI>http://schemas.mycompany.com/claims/role</roleURI>
+ <claimTypesRequested>
+ <claimType type="a particular claim type" optional="true" />
+ </claimTypesRequested>
+ </protocol>
+ </contextConfig>
+
+ <contextConfig name="SIGNED_ROOT">
+ <audienceUris>
+ <audienceItem>http://host_one:port/url</audienceItem>
+ </audienceUris>
+ <certificateStores>
+ <trustManager>
+ <keyStore file="ststrust.jks" password="storepass"
+ type="JKS" />
+ </trustManager>
+ </certificateStores>
+ <signingKey keyPassword="stskpass" keyAlias="mystskey">
+ <keyStore file="stsstore.jks" password="stsspass" type="JKS" />
+ </signingKey>
+ <trustedIssuers>
+ <issuer certificateValidation="PeerTrust" />
+ </trustedIssuers>
+
+ <maximumClockSkew>1000</maximumClockSkew>
+ <protocol xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:type="samlProtocolType" version="1.2">
+ <signRequest>true</signRequest>
+ <issuer>http://url_to_the_issuer</issuer>
+ <roleDelimiter>;</roleDelimiter>
+ <roleURI>http://schemas.xmlsoap.org/ws/2005/05/identity/claims/role</roleURI>
+ <claimTypesRequested>
+ <claimType type="a particular claim type" optional="true" />
+ </claimTypesRequested>
+ </protocol>
+ </contextConfig>
+</FedizConfig>
http://git-wip-us.apache.org/repos/asf/cxf-fediz/blob/617fd4e9/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index ed23110..e1cb718 100644
--- a/pom.xml
+++ b/pom.xml
@@ -40,6 +40,7 @@
<commons.logging.version>1.1.3</commons.logging.version>
<cxf.version>3.0.1</cxf.version>
<cxf.build-utils.version>2.6.0</cxf.build-utils.version>
+ <easymock.version>3.1</easymock.version>
<ehcache.version>2.8.3</ehcache.version>
<httpclient.version>4.3.3</httpclient.version>
<hsqldb.version>1.8.0.10</hsqldb.version>
[3/4] Adding unit tests for SAML SSO
Posted by co...@apache.org.
http://git-wip-us.apache.org/repos/asf/cxf-fediz/blob/617fd4e9/plugins/core/src/test/java/org/apache/cxf/fediz/core/SAMLTokenValidatorOldTest.java
----------------------------------------------------------------------
diff --git a/plugins/core/src/test/java/org/apache/cxf/fediz/core/SAMLTokenValidatorOldTest.java b/plugins/core/src/test/java/org/apache/cxf/fediz/core/SAMLTokenValidatorOldTest.java
deleted file mode 100644
index 8785895..0000000
--- a/plugins/core/src/test/java/org/apache/cxf/fediz/core/SAMLTokenValidatorOldTest.java
+++ /dev/null
@@ -1,392 +0,0 @@
-/**
- * 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;
-
-import java.io.File;
-import java.io.IOException;
-import java.net.URL;
-import java.util.Collections;
-import java.util.List;
-
-import javax.security.auth.callback.CallbackHandler;
-import javax.security.auth.callback.UnsupportedCallbackException;
-
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-import org.w3c.dom.Node;
-import org.apache.cxf.fediz.common.STSUtil;
-import org.apache.cxf.fediz.common.SecurityTestUtil;
-import org.apache.cxf.fediz.core.config.FedizConfigurator;
-import org.apache.cxf.fediz.core.config.FedizContext;
-import org.apache.cxf.fediz.core.processor.FederationProcessorImpl;
-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.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.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.builder.SAML1Constants;
-import org.apache.wss4j.common.saml.builder.SAML2Constants;
-import org.apache.wss4j.common.util.DOM2Writer;
-import org.junit.AfterClass;
-import org.junit.Assert;
-import org.junit.BeforeClass;
-
-
-// This testcases tests the encoding implemented before CXF-4484
-public class SAMLTokenValidatorOldTest {
- static final String TEST_USER = "alice";
- static final String TEST_RSTR_ISSUER = "FedizSTSIssuer";
- static final String TEST_AUDIENCE = "https://localhost/fedizhelloworld";
-
- private static final String CONFIG_FILE = "fediz_test_config.xml";
-
- private static Crypto crypto;
- private static CallbackHandler cbPasswordHandler;
- private static FedizConfigurator configurator;
-
-
- @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;
- }
- }
-
- /**
- * Validate SAML 2 token which includes the role attribute with 2 values
- * Roles are encoded as a multi-value saml attribute
- */
- @org.junit.Test
- public void validateSAML2Token() throws Exception {
- SAML2CallbackHandler callbackHandler = new SAML2CallbackHandler();
- callbackHandler.setStatement(SAML2CallbackHandler.Statement.ATTR);
- callbackHandler.setConfirmationMethod(SAML2Constants.CONF_BEARER);
- callbackHandler.setIssuer(TEST_RSTR_ISSUER);
- callbackHandler.setSubjectName(TEST_USER);
- callbackHandler.setAttributeNameFormat(ClaimTypes.URI_BASE.toString());
- callbackHandler.setCountryClaimName("country");
- callbackHandler.setRoleAttributeName("role");
-
- ConditionsBean cp = new ConditionsBean();
- AudienceRestrictionBean audienceRestriction = new AudienceRestrictionBean();
- audienceRestriction.getAudienceURIs().add(TEST_AUDIENCE);
- cp.setAudienceRestrictions(Collections.singletonList(audienceRestriction));
- callbackHandler.setConditions(cp);
-
- SAMLCallback samlCallback = new SAMLCallback();
- SAMLUtil.doSAMLCallback(callbackHandler, samlCallback);
- SamlAssertionWrapper assertion = new SamlAssertionWrapper(samlCallback);
-
- String rstr = createSamlToken(assertion, "mystskey", true);
-
- FedizRequest wfReq = new FedizRequest();
- wfReq.setAction(FederationConstants.ACTION_SIGNIN);
- wfReq.setResponseToken(rstr);
-
- configurator = null;
- FedizContext config = getFederationConfigurator().getFedizContext("ROOT");
-
- FedizProcessor wfProc = new FederationProcessorImpl();
- FedizResponse wfRes = wfProc.processRequest(wfReq, config);
-
- Assert.assertEquals("Principal name wrong", TEST_USER,
- wfRes.getUsername());
- Assert.assertEquals("Issuer wrong", TEST_RSTR_ISSUER, wfRes.getIssuer());
- Assert.assertEquals("Two roles must be found", 2, wfRes.getRoles()
- .size());
- Assert.assertEquals("Audience wrong", TEST_AUDIENCE, wfRes.getAudience());
- assertClaims(wfRes.getClaims(), callbackHandler.getRoleAttributeName());
-
- }
-
- /**
- * Validate SAML 2 token where role information is provided
- * within another SAML attribute
- */
- @org.junit.Test
- public void validateSAML2TokenDifferentRoleURI() throws Exception {
- SAML2CallbackHandler callbackHandler = new SAML2CallbackHandler();
- callbackHandler.setStatement(SAML2CallbackHandler.Statement.ATTR);
- callbackHandler.setConfirmationMethod(SAML2Constants.CONF_BEARER);
- callbackHandler.setIssuer(TEST_RSTR_ISSUER);
- callbackHandler.setSubjectName(TEST_USER);
- callbackHandler.setAttributeNameFormat(ClaimTypes.URI_BASE.toString());
- callbackHandler.setCountryClaimName("country");
- callbackHandler.setRoleAttributeName("http://schemas.mycompany.com/claims/role");
-
- ConditionsBean cp = new ConditionsBean();
- AudienceRestrictionBean audienceRestriction = new AudienceRestrictionBean();
- audienceRestriction.getAudienceURIs().add(TEST_AUDIENCE);
- cp.setAudienceRestrictions(Collections.singletonList(audienceRestriction));
- callbackHandler.setConditions(cp);
-
- SAMLCallback samlCallback = new SAMLCallback();
- SAMLUtil.doSAMLCallback(callbackHandler, samlCallback);
- SamlAssertionWrapper assertion = new SamlAssertionWrapper(samlCallback);
-
- String rstr = createSamlToken(assertion, "mystskey", true);
-
- FedizRequest wfReq = new FedizRequest();
- wfReq.setAction(FederationConstants.ACTION_SIGNIN);
- wfReq.setResponseToken(rstr);
-
- configurator = null;
- FedizContext config = getFederationConfigurator().getFedizContext("CUSTOMROLEURI");
-
- FedizProcessor wfProc = new FederationProcessorImpl();
- FedizResponse wfRes = wfProc.processRequest(wfReq, config);
-
- Assert.assertEquals("Principal name wrong", TEST_USER, wfRes.getUsername());
- Assert.assertEquals("Issuer wrong", TEST_RSTR_ISSUER, wfRes.getIssuer());
- Assert.assertEquals("Two roles must be found", 2, wfRes.getRoles().size());
- Assert.assertEquals("Audience wrong", TEST_AUDIENCE, wfRes.getAudience());
- assertClaims(wfRes.getClaims(), callbackHandler.getRoleAttributeName());
- }
-
- /**
- * Validate SAML 2 token where role information is provided
- * within another SAML attribute
- */
- @org.junit.Test
- public void validateSAML1TokenDifferentRoleURI() throws Exception {
- SAML1CallbackHandler callbackHandler = new SAML1CallbackHandler();
- callbackHandler.setStatement(SAML1CallbackHandler.Statement.ATTR);
- callbackHandler.setConfirmationMethod(SAML2Constants.CONF_BEARER);
- callbackHandler.setIssuer(TEST_RSTR_ISSUER);
- callbackHandler.setSubjectName(TEST_USER);
- callbackHandler.setUseNameFormatAsNamespace(true);
- callbackHandler.setAttributeNameFormat(ClaimTypes.URI_BASE.toString());
- callbackHandler.setRoleAttributeName("http://schemas.mycompany.com/claims/role");
- ConditionsBean cp = new ConditionsBean();
- AudienceRestrictionBean audienceRestriction = new AudienceRestrictionBean();
- audienceRestriction.getAudienceURIs().add(TEST_AUDIENCE);
- cp.setAudienceRestrictions(Collections.singletonList(audienceRestriction));
- callbackHandler.setConditions(cp);
-
- SAMLCallback samlCallback = new SAMLCallback();
- SAMLUtil.doSAMLCallback(callbackHandler, samlCallback);
- SamlAssertionWrapper assertion = new SamlAssertionWrapper(samlCallback);
-
- String rstr = createSamlToken(assertion, "mystskey", true);
-
- FedizRequest wfReq = new FedizRequest();
- wfReq.setAction(FederationConstants.ACTION_SIGNIN);
- wfReq.setResponseToken(rstr);
-
- configurator = null;
- FedizContext config = getFederationConfigurator().getFedizContext("CUSTOMROLEURI");
-
- FedizProcessor wfProc = new FederationProcessorImpl();
- FedizResponse wfRes = wfProc.processRequest(wfReq, config);
-
- Assert.assertEquals("Principal name wrong", TEST_USER, wfRes.getUsername());
- Assert.assertEquals("Issuer wrong", TEST_RSTR_ISSUER, wfRes.getIssuer());
- Assert.assertEquals("Two roles must be found", 2, wfRes.getRoles().size());
- Assert.assertEquals("Audience wrong", TEST_AUDIENCE, wfRes.getAudience());
- assertClaims(wfRes.getClaims(), callbackHandler.getRoleAttributeName());
- }
-
- /**
- * Validate SAML 1.1 token which includes the role attribute with 2 values
- * Roles are encoded as a multi-value saml attribute
- */
- @org.junit.Test
- public void validateSAML1Token() throws Exception {
- SAML1CallbackHandler callbackHandler = new SAML1CallbackHandler();
- callbackHandler.setStatement(SAML1CallbackHandler.Statement.ATTR);
- callbackHandler.setConfirmationMethod(SAML1Constants.CONF_BEARER);
- callbackHandler.setIssuer(TEST_RSTR_ISSUER);
- callbackHandler.setSubjectName(TEST_USER);
- callbackHandler.setUseNameFormatAsNamespace(true);
- callbackHandler.setAttributeNameFormat(ClaimTypes.URI_BASE.toString());
- callbackHandler.setRoleAttributeName("role");
-
- ConditionsBean cp = new ConditionsBean();
- AudienceRestrictionBean audienceRestriction = new AudienceRestrictionBean();
- audienceRestriction.getAudienceURIs().add(TEST_AUDIENCE);
- cp.setAudienceRestrictions(Collections.singletonList(audienceRestriction));
- callbackHandler.setConditions(cp);
-
- SAMLCallback samlCallback = new SAMLCallback();
- SAMLUtil.doSAMLCallback(callbackHandler, samlCallback);
- SamlAssertionWrapper assertion = new SamlAssertionWrapper(samlCallback);
-
- String rstr = createSamlToken(assertion, "mystskey", true);
-
- FedizRequest wfReq = new FedizRequest();
- wfReq.setAction(FederationConstants.ACTION_SIGNIN);
- wfReq.setResponseToken(rstr);
-
- configurator = null;
- FedizContext config = getFederationConfigurator().getFedizContext("ROOT");
-
- FedizProcessor wfProc = new FederationProcessorImpl();
- FedizResponse wfRes = wfProc.processRequest(wfReq, config);
-
- Assert.assertEquals("Principal name wrong", TEST_USER,
- wfRes.getUsername());
- Assert.assertEquals("Issuer wrong", TEST_RSTR_ISSUER, wfRes.getIssuer());
- Assert.assertEquals("Two roles must be found", 2, wfRes.getRoles()
- .size());
- Assert.assertEquals("Audience wrong", TEST_AUDIENCE, wfRes.getAudience());
- assertClaims(wfRes.getClaims(), callbackHandler.getRoleAttributeName());
- }
-
-
- private String createSamlToken(SamlAssertionWrapper assertion, String alias, boolean sign)
- throws IOException, UnsupportedCallbackException, WSSecurityException, Exception {
- return createSamlToken(assertion, alias, sign, STSUtil.SAMPLE_RSTR_COLL_MSG);
- }
-
- private String createSamlToken(SamlAssertionWrapper assertion, String alias, boolean sign, String rstr)
- 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);
- }
- Document doc = STSUtil.toSOAPPart(rstr);
- Element token = assertion.toDOM(doc);
-
- Element e = SAMLTokenValidatorOldTest.findElement(doc, "RequestedSecurityToken",
- FederationConstants.WS_TRUST_13_NS);
- if (e == null) {
- e = SAMLTokenValidatorOldTest.findElement(doc, "RequestedSecurityToken",
- FederationConstants.WS_TRUST_2005_02_NS);
- }
- e.appendChild(token);
- return DOM2Writer.nodeToString(doc);
- }
-
-
-
-
- /**
- * 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 void assertClaims(List<Claim> claims, String roleClaimType) {
- for (Claim c : claims) {
- Assert.assertTrue("Invalid ClaimType URI: " + c.getClaimType(),
- c.getClaimType().equals(roleClaimType)
- || c.getClaimType().equals(ClaimTypes.COUNTRY)
- || c.getClaimType().equals(AbstractSAMLCallbackHandler.CLAIM_TYPE_LANGUAGE)
- );
- }
- }
-
-
-
-
-}
http://git-wip-us.apache.org/repos/asf/cxf-fediz/blob/617fd4e9/plugins/core/src/test/java/org/apache/cxf/fediz/core/federation/CustomValidator.java
----------------------------------------------------------------------
diff --git a/plugins/core/src/test/java/org/apache/cxf/fediz/core/federation/CustomValidator.java b/plugins/core/src/test/java/org/apache/cxf/fediz/core/federation/CustomValidator.java
new file mode 100644
index 0000000..9f988bb
--- /dev/null
+++ b/plugins/core/src/test/java/org/apache/cxf/fediz/core/federation/CustomValidator.java
@@ -0,0 +1,54 @@
+/**
+ * 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.federation;
+
+import org.w3c.dom.Element;
+import org.apache.cxf.fediz.core.TokenValidator;
+import org.apache.cxf.fediz.core.TokenValidatorRequest;
+import org.apache.cxf.fediz.core.TokenValidatorResponse;
+import org.apache.cxf.fediz.core.config.FedizContext;
+
+
+public class CustomValidator implements TokenValidator {
+
+ @Override
+ public boolean canHandleTokenType(String tokenType) {
+ return true;
+ }
+
+ @Override
+ public boolean canHandleToken(Element token) {
+ return true;
+ }
+
+ @Override
+ public TokenValidatorResponse validateAndProcessToken(
+ TokenValidatorRequest request,
+ FedizContext config
+ ) {
+ return new TokenValidatorResponse(null,
+ FederationProcessorTest.TEST_USER,
+ FederationProcessorTest.TEST_RSTR_ISSUER,
+ null,
+ null,
+ FederationProcessorTest.TEST_AUDIENCE);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/cxf-fediz/blob/617fd4e9/plugins/core/src/test/java/org/apache/cxf/fediz/core/federation/FederationMetaDataTest.java
----------------------------------------------------------------------
diff --git a/plugins/core/src/test/java/org/apache/cxf/fediz/core/federation/FederationMetaDataTest.java b/plugins/core/src/test/java/org/apache/cxf/fediz/core/federation/FederationMetaDataTest.java
new file mode 100644
index 0000000..211df13
--- /dev/null
+++ b/plugins/core/src/test/java/org/apache/cxf/fediz/core/federation/FederationMetaDataTest.java
@@ -0,0 +1,117 @@
+/**
+ * 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.federation;
+
+import java.io.File;
+import java.net.URL;
+
+import javax.xml.transform.TransformerException;
+
+import org.w3c.dom.Document;
+import org.apache.cxf.fediz.common.SecurityTestUtil;
+import org.apache.cxf.fediz.core.config.FedizConfigurator;
+import org.apache.cxf.fediz.core.config.FedizContext;
+import org.apache.cxf.fediz.core.exception.ProcessingException;
+import org.apache.cxf.fediz.core.processor.FederationProcessorImpl;
+import org.apache.cxf.fediz.core.processor.FedizProcessor;
+import org.apache.cxf.fediz.core.util.DOMUtils;
+import org.junit.AfterClass;
+import org.junit.Assert;
+
+import static org.junit.Assert.fail;
+
+public class FederationMetaDataTest {
+ private static final String CONFIG_FILE = "fediz_meta_test_config.xml";
+
+ @AfterClass
+ public static void cleanup() {
+ SecurityTestUtil.cleanup();
+ }
+
+
+ private FedizContext loadConfig(String context) {
+ try {
+ FedizConfigurator configurator = new FedizConfigurator();
+ final URL resource = Thread.currentThread().getContextClassLoader()
+ .getResource(CONFIG_FILE);
+ File f = new File(resource.toURI());
+ configurator.loadConfig(f);
+ return configurator.getFedizContext(context);
+ } catch (Exception e) {
+ e.printStackTrace();
+ return null;
+ }
+ }
+
+
+ @org.junit.Test
+ public void validateMetaDataWithAlias() throws ProcessingException {
+
+ FedizContext config = loadConfig("ROOT");
+
+ FedizProcessor wfProc = new FederationProcessorImpl();
+ Document doc = wfProc.getMetaData(config);
+ Assert.assertNotNull(doc);
+
+ try {
+ DOMUtils.writeXml(doc, System.out);
+ } catch (TransformerException e) {
+ fail("Exception not expected: " + e.getMessage());
+ }
+
+ }
+
+ @org.junit.Test
+ public void validateMetaDataNoAlias() throws ProcessingException {
+
+ try {
+ FedizContext config = loadConfig("ROOT_NO_KEY");
+
+ FedizProcessor wfProc = new FederationProcessorImpl();
+ Document doc;
+
+ doc = wfProc.getMetaData(config);
+ Assert.assertNull(doc);
+ } catch (ProcessingException ex) {
+ //Expected as signing store contains more than one certificate
+ }
+
+
+ }
+
+ @org.junit.Test
+ public void validateMetaDataNoSigningKey() throws ProcessingException {
+
+ FedizContext config = loadConfig("ROOT_NO_SIGNINGKEY");
+
+ FedizProcessor wfProc = new FederationProcessorImpl();
+ Document doc = wfProc.getMetaData(config);
+ Assert.assertNotNull(doc);
+
+ try {
+ DOMUtils.writeXml(doc, System.out);
+ } catch (TransformerException e) {
+ fail("Exception not expected: " + e.getMessage());
+ }
+
+ }
+
+
+}
http://git-wip-us.apache.org/repos/asf/cxf-fediz/blob/617fd4e9/plugins/core/src/test/java/org/apache/cxf/fediz/core/federation/FederationProcessorTest.java
----------------------------------------------------------------------
diff --git a/plugins/core/src/test/java/org/apache/cxf/fediz/core/federation/FederationProcessorTest.java b/plugins/core/src/test/java/org/apache/cxf/fediz/core/federation/FederationProcessorTest.java
new file mode 100644
index 0000000..fd564b2
--- /dev/null
+++ b/plugins/core/src/test/java/org/apache/cxf/fediz/core/federation/FederationProcessorTest.java
@@ -0,0 +1,1350 @@
+/**
+ * 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.federation;
+
+import java.io.File;
+import java.io.IOException;
+import java.math.BigInteger;
+import java.net.URL;
+import java.security.cert.X509Certificate;
+import java.util.Collections;
+import java.util.List;
+
+import javax.security.auth.callback.CallbackHandler;
+import javax.security.auth.callback.UnsupportedCallbackException;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.apache.cxf.fediz.common.STSUtil;
+import org.apache.cxf.fediz.common.SecurityTestUtil;
+import org.apache.cxf.fediz.core.AbstractSAMLCallbackHandler;
+import org.apache.cxf.fediz.core.AbstractSAMLCallbackHandler.MultiValue;
+import org.apache.cxf.fediz.core.Claim;
+import org.apache.cxf.fediz.core.ClaimTypes;
+import org.apache.cxf.fediz.core.FederationConstants;
+import org.apache.cxf.fediz.core.KeystoreCallbackHandler;
+import org.apache.cxf.fediz.core.SAML1CallbackHandler;
+import org.apache.cxf.fediz.core.SAML2CallbackHandler;
+import org.apache.cxf.fediz.core.TokenValidator;
+import org.apache.cxf.fediz.core.config.FederationProtocol;
+import org.apache.cxf.fediz.core.config.FedizConfigurator;
+import org.apache.cxf.fediz.core.config.FedizContext;
+import org.apache.cxf.fediz.core.config.jaxb.AudienceUris;
+import org.apache.cxf.fediz.core.config.jaxb.CertificateStores;
+import org.apache.cxf.fediz.core.config.jaxb.ContextConfig;
+import org.apache.cxf.fediz.core.config.jaxb.FederationProtocolType;
+import org.apache.cxf.fediz.core.config.jaxb.KeyStoreType;
+import org.apache.cxf.fediz.core.config.jaxb.TrustManagersType;
+import org.apache.cxf.fediz.core.config.jaxb.TrustedIssuerType;
+import org.apache.cxf.fediz.core.config.jaxb.TrustedIssuers;
+import org.apache.cxf.fediz.core.config.jaxb.ValidationType;
+import org.apache.cxf.fediz.core.exception.ProcessingException;
+import org.apache.cxf.fediz.core.exception.ProcessingException.TYPE;
+import org.apache.cxf.fediz.core.processor.FederationProcessorImpl;
+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.wss4j.common.WSEncryptionPart;
+import org.apache.wss4j.common.crypto.Crypto;
+import org.apache.wss4j.common.crypto.CryptoFactory;
+import org.apache.wss4j.common.crypto.CryptoType;
+import org.apache.wss4j.common.ext.WSPasswordCallback;
+import org.apache.wss4j.common.ext.WSSecurityException;
+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.builder.SAML1Constants;
+import org.apache.wss4j.common.saml.builder.SAML2Constants;
+import org.apache.wss4j.common.util.DOM2Writer;
+import org.apache.wss4j.dom.WSConstants;
+import org.apache.wss4j.dom.message.WSSecEncrypt;
+import org.joda.time.DateTime;
+import org.junit.AfterClass;
+import org.junit.Assert;
+import org.junit.BeforeClass;
+
+import static org.junit.Assert.fail;
+
+/**
+ * Some tests for the WS-Federation "FederationProcessor".
+ */
+public class FederationProcessorTest {
+ static final String TEST_USER = "alice";
+ static final String TEST_RSTR_ISSUER = "FedizSTSIssuer";
+ static final String TEST_AUDIENCE = "https://localhost/fedizhelloworld";
+
+ private static final String CONFIG_FILE = "fediz_test_config.xml";
+
+ private static Crypto crypto;
+ private static CallbackHandler cbPasswordHandler;
+ private static FedizConfigurator configurator;
+
+
+ @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;
+ }
+ }
+
+
+ /**
+ * Validate RSTR without RequestedSecurityToken element
+ */
+ @org.junit.Test
+ public void validateRSTRWithoutToken() throws Exception {
+ Document doc = STSUtil.toSOAPPart(STSUtil.SAMPLE_RSTR_COLL_MSG);
+
+ FedizRequest wfReq = new FedizRequest();
+ wfReq.setAction(FederationConstants.ACTION_SIGNIN);
+ wfReq.setResponseToken(DOM2Writer.nodeToString(doc));
+
+ configurator = null;
+ FedizContext config = getFederationConfigurator().getFedizContext("ROOT");
+
+ FedizProcessor wfProc = new FederationProcessorImpl();
+ try {
+ wfProc.processRequest(wfReq, config);
+ fail("Failure expected on missing security token in RSTR");
+ } catch (ProcessingException ex) {
+ if (!TYPE.BAD_REQUEST.equals(ex.getType())) {
+ fail("Expected ProcessingException with BAD_REQUEST type");
+ }
+ }
+ }
+
+ /**
+ * Validate FederationRequest with unknown action
+ */
+ @org.junit.Test
+ public void validateRequestUnknownAction() throws Exception {
+ Document doc = STSUtil.toSOAPPart(STSUtil.SAMPLE_RSTR_COLL_MSG);
+
+ FedizRequest wfReq = new FedizRequest();
+ wfReq.setAction("gugus");
+ wfReq.setResponseToken(DOM2Writer.nodeToString(doc));
+
+ configurator = null;
+ FedizContext config = getFederationConfigurator().getFedizContext("ROOT");
+
+ FedizProcessor wfProc = new FederationProcessorImpl();
+ try {
+ wfProc.processRequest(wfReq, config);
+ fail("Failure expected due to invalid action");
+ } catch (ProcessingException ex) {
+ if (!TYPE.INVALID_REQUEST.equals(ex.getType())) {
+ fail("Expected ProcessingException with INVALID_REQUEST type");
+ }
+ }
+ }
+
+ /**
+ *Validate FederationRequest with invalid RSTR/wresult
+ */
+ @org.junit.Test
+ public void validateSignInInvalidWResult() throws Exception {
+ FedizRequest wfReq = new FedizRequest();
+ wfReq.setAction(FederationConstants.ACTION_SIGNIN);
+ wfReq.setResponseToken("gugus");
+
+ configurator = null;
+ FedizContext config = getFederationConfigurator().getFedizContext("ROOT");
+
+ FedizProcessor wfProc = new FederationProcessorImpl();
+ try {
+ wfProc.processRequest(wfReq, config);
+ fail("Failure expected due to invalid wresult");
+ } catch (ProcessingException ex) {
+ if (!TYPE.INVALID_REQUEST.equals(ex.getType())) {
+ fail("Expected ProcessingException with INVALID_REQUEST type");
+ }
+ }
+ }
+
+ @org.junit.Test
+ public void validateTokenAndCreateMetadata() throws Exception {
+ validateSAML2Token();
+ FederationMetaDataTest other = new FederationMetaDataTest();
+ other.validateMetaDataWithAlias();
+ }
+
+ /**
+ * Validate SAML 2 token which includes the role attribute with 2 values
+ * Roles are encoded as a multi-value saml attribute
+ */
+ @org.junit.Test
+ public void validateSAML2Token() throws Exception {
+ SAML2CallbackHandler callbackHandler = new SAML2CallbackHandler();
+ callbackHandler.setStatement(SAML2CallbackHandler.Statement.ATTR);
+ callbackHandler.setConfirmationMethod(SAML2Constants.CONF_BEARER);
+ callbackHandler.setIssuer(TEST_RSTR_ISSUER);
+ callbackHandler.setSubjectName(TEST_USER);
+ ConditionsBean cp = new ConditionsBean();
+ AudienceRestrictionBean audienceRestriction = new AudienceRestrictionBean();
+ audienceRestriction.getAudienceURIs().add(TEST_AUDIENCE);
+ cp.setAudienceRestrictions(Collections.singletonList(audienceRestriction));
+ callbackHandler.setConditions(cp);
+
+ SAMLCallback samlCallback = new SAMLCallback();
+ SAMLUtil.doSAMLCallback(callbackHandler, samlCallback);
+ SamlAssertionWrapper assertion = new SamlAssertionWrapper(samlCallback);
+ String rstr = createSamlToken(assertion, "mystskey", true);
+
+ FedizRequest wfReq = new FedizRequest();
+ wfReq.setAction(FederationConstants.ACTION_SIGNIN);
+ wfReq.setResponseToken(rstr);
+
+ configurator = null;
+ FedizContext config = getFederationConfigurator().getFedizContext("ROOT");
+
+ FedizProcessor wfProc = new FederationProcessorImpl();
+ FedizResponse wfRes = wfProc.processRequest(wfReq, config);
+
+ Assert.assertEquals("Principal name wrong", TEST_USER,
+ wfRes.getUsername());
+ Assert.assertEquals("Issuer wrong", TEST_RSTR_ISSUER, wfRes.getIssuer());
+ Assert.assertEquals("Two roles must be found", 2, wfRes.getRoles()
+ .size());
+ Assert.assertEquals("Audience wrong", TEST_AUDIENCE, wfRes.getAudience());
+ assertClaims(wfRes.getClaims(), callbackHandler.getRoleAttributeName());
+
+ }
+
+ /**
+ * Validate SAML 2 token which includes the role attribute with 2 values
+ * Roles are encoded as a multi-value saml attribute
+ * Not RequestedSecurityTokenCollection in this test, default in all others
+ */
+ @org.junit.Test
+ public void validateSAML2TokenRSTR() throws Exception {
+ SAML2CallbackHandler callbackHandler = new SAML2CallbackHandler();
+ callbackHandler.setStatement(SAML2CallbackHandler.Statement.ATTR);
+ callbackHandler.setConfirmationMethod(SAML2Constants.CONF_BEARER);
+ callbackHandler.setIssuer(TEST_RSTR_ISSUER);
+ callbackHandler.setSubjectName(TEST_USER);
+ ConditionsBean cp = new ConditionsBean();
+ AudienceRestrictionBean audienceRestriction = new AudienceRestrictionBean();
+ audienceRestriction.getAudienceURIs().add(TEST_AUDIENCE);
+ cp.setAudienceRestrictions(Collections.singletonList(audienceRestriction));
+ callbackHandler.setConditions(cp);
+
+ SAMLCallback samlCallback = new SAMLCallback();
+ SAMLUtil.doSAMLCallback(callbackHandler, samlCallback);
+ SamlAssertionWrapper assertion = new SamlAssertionWrapper(samlCallback);
+ String rstr = createSamlToken(assertion, "mystskey", true, STSUtil.SAMPLE_RSTR_MSG);
+
+ FedizRequest wfReq = new FedizRequest();
+ wfReq.setAction(FederationConstants.ACTION_SIGNIN);
+ wfReq.setResponseToken(rstr);
+
+ configurator = null;
+ FedizContext config = getFederationConfigurator().getFedizContext("ROOT");
+
+ FedizProcessor wfProc = new FederationProcessorImpl();
+ FedizResponse wfRes = wfProc.processRequest(wfReq, config);
+
+ Assert.assertEquals("Principal name wrong", TEST_USER,
+ wfRes.getUsername());
+ Assert.assertEquals("Issuer wrong", TEST_RSTR_ISSUER, wfRes.getIssuer());
+ Assert.assertEquals("Two roles must be found", 2, wfRes.getRoles()
+ .size());
+ Assert.assertEquals("Audience wrong", TEST_AUDIENCE, wfRes.getAudience());
+ }
+
+ /**
+ * Validate SAML 2 token which doesn't include the role SAML attribute
+ */
+ @org.junit.Test
+ public void validateSAML2TokenWithoutRoles() throws Exception {
+ SAML2CallbackHandler callbackHandler = new SAML2CallbackHandler();
+ callbackHandler.setStatement(SAML2CallbackHandler.Statement.ATTR);
+ callbackHandler.setConfirmationMethod(SAML2Constants.CONF_BEARER);
+ callbackHandler.setIssuer(TEST_RSTR_ISSUER);
+ callbackHandler.setSubjectName(TEST_USER);
+ callbackHandler.setRoles(null);
+ ConditionsBean cp = new ConditionsBean();
+ AudienceRestrictionBean audienceRestriction = new AudienceRestrictionBean();
+ audienceRestriction.getAudienceURIs().add(TEST_AUDIENCE);
+ cp.setAudienceRestrictions(Collections.singletonList(audienceRestriction));
+ callbackHandler.setConditions(cp);
+
+ SAMLCallback samlCallback = new SAMLCallback();
+ SAMLUtil.doSAMLCallback(callbackHandler, samlCallback);
+ SamlAssertionWrapper assertion = new SamlAssertionWrapper(samlCallback);
+ String rstr = createSamlToken(assertion, "mystskey", true);
+
+ FedizRequest wfReq = new FedizRequest();
+ wfReq.setAction(FederationConstants.ACTION_SIGNIN);
+ wfReq.setResponseToken(rstr);
+
+ configurator = null;
+ FedizContext config = getFederationConfigurator().getFedizContext("ROOT");
+
+ FedizProcessor wfProc = new FederationProcessorImpl();
+ FedizResponse wfRes = wfProc.processRequest(wfReq, config);
+
+ Assert.assertEquals("Principal name wrong", TEST_USER,
+ wfRes.getUsername());
+ Assert.assertEquals("Issuer wrong", TEST_RSTR_ISSUER, wfRes.getIssuer());
+ Assert.assertEquals("No roles must be found", null, wfRes.getRoles());
+ Assert.assertEquals("Audience wrong", TEST_AUDIENCE, wfRes.getAudience());
+ }
+
+ /**
+ * Validate SAML 2 token where role information is provided
+ * within another SAML attribute
+ */
+ @org.junit.Test
+ public void validateSAML2TokenDifferentRoleURI() throws Exception {
+ SAML2CallbackHandler callbackHandler = new SAML2CallbackHandler();
+ callbackHandler.setStatement(SAML2CallbackHandler.Statement.ATTR);
+ callbackHandler.setConfirmationMethod(SAML2Constants.CONF_BEARER);
+ callbackHandler.setIssuer(TEST_RSTR_ISSUER);
+ callbackHandler.setSubjectName(TEST_USER);
+ callbackHandler.setRoleAttributeName("http://schemas.mycompany.com/claims/role");
+ ConditionsBean cp = new ConditionsBean();
+ AudienceRestrictionBean audienceRestriction = new AudienceRestrictionBean();
+ audienceRestriction.getAudienceURIs().add(TEST_AUDIENCE);
+ cp.setAudienceRestrictions(Collections.singletonList(audienceRestriction));
+ callbackHandler.setConditions(cp);
+
+ SAMLCallback samlCallback = new SAMLCallback();
+ SAMLUtil.doSAMLCallback(callbackHandler, samlCallback);
+ SamlAssertionWrapper assertion = new SamlAssertionWrapper(samlCallback);
+ String rstr = createSamlToken(assertion, "mystskey", true);
+
+ FedizRequest wfReq = new FedizRequest();
+ wfReq.setAction(FederationConstants.ACTION_SIGNIN);
+ wfReq.setResponseToken(rstr);
+
+ configurator = null;
+ FedizContext config = getFederationConfigurator().getFedizContext("CUSTOMROLEURI");
+
+ FedizProcessor wfProc = new FederationProcessorImpl();
+ FedizResponse wfRes = wfProc.processRequest(wfReq, config);
+
+ Assert.assertEquals("Principal name wrong", TEST_USER, wfRes.getUsername());
+ Assert.assertEquals("Issuer wrong", TEST_RSTR_ISSUER, wfRes.getIssuer());
+ Assert.assertEquals("Two roles must be found", 2, wfRes.getRoles().size());
+ Assert.assertEquals("Audience wrong", TEST_AUDIENCE, wfRes.getAudience());
+ assertClaims(wfRes.getClaims(), callbackHandler.getRoleAttributeName());
+ }
+
+ /**
+ * Validate SAML 2 token where role information is provided
+ * within another SAML attribute
+ */
+ @org.junit.Test
+ public void validateSAML1TokenDifferentRoleURI() throws Exception {
+ SAML1CallbackHandler callbackHandler = new SAML1CallbackHandler();
+ callbackHandler.setStatement(SAML1CallbackHandler.Statement.ATTR);
+ callbackHandler.setConfirmationMethod(SAML2Constants.CONF_BEARER);
+ callbackHandler.setIssuer(TEST_RSTR_ISSUER);
+ callbackHandler.setSubjectName(TEST_USER);
+ callbackHandler.setRoleAttributeName("http://schemas.mycompany.com/claims/role");
+ ConditionsBean cp = new ConditionsBean();
+ AudienceRestrictionBean audienceRestriction = new AudienceRestrictionBean();
+ audienceRestriction.getAudienceURIs().add(TEST_AUDIENCE);
+ cp.setAudienceRestrictions(Collections.singletonList(audienceRestriction));
+ callbackHandler.setConditions(cp);
+
+ SAMLCallback samlCallback = new SAMLCallback();
+ SAMLUtil.doSAMLCallback(callbackHandler, samlCallback);
+ SamlAssertionWrapper assertion = new SamlAssertionWrapper(samlCallback);
+ String rstr = createSamlToken(assertion, "mystskey", true);
+
+ FedizRequest wfReq = new FedizRequest();
+ wfReq.setAction(FederationConstants.ACTION_SIGNIN);
+ wfReq.setResponseToken(rstr);
+
+ configurator = null;
+ FedizContext config = getFederationConfigurator().getFedizContext("CUSTOMROLEURI");
+
+ FedizProcessor wfProc = new FederationProcessorImpl();
+ FedizResponse wfRes = wfProc.processRequest(wfReq, config);
+
+ Assert.assertEquals("Principal name wrong", TEST_USER, wfRes.getUsername());
+ Assert.assertEquals("Issuer wrong", TEST_RSTR_ISSUER, wfRes.getIssuer());
+ Assert.assertEquals("Two roles must be found", 2, wfRes.getRoles().size());
+ Assert.assertEquals("Audience wrong", TEST_AUDIENCE, wfRes.getAudience());
+ assertClaims(wfRes.getClaims(), callbackHandler.getRoleAttributeName());
+ }
+
+ /**
+ * Validate SAML 2 token which includes role attribute
+ * but RoleURI is not configured
+ */
+ @org.junit.Test
+ public void validateSAML2TokenRoleURINotConfigured() throws Exception {
+ SAML2CallbackHandler callbackHandler = new SAML2CallbackHandler();
+ callbackHandler.setStatement(SAML2CallbackHandler.Statement.ATTR);
+ callbackHandler.setConfirmationMethod(SAML2Constants.CONF_BEARER);
+ callbackHandler.setIssuer(TEST_RSTR_ISSUER);
+ callbackHandler.setSubjectName(TEST_USER);
+ ConditionsBean cp = new ConditionsBean();
+ AudienceRestrictionBean audienceRestriction = new AudienceRestrictionBean();
+ audienceRestriction.getAudienceURIs().add(TEST_AUDIENCE);
+ cp.setAudienceRestrictions(Collections.singletonList(audienceRestriction));
+ callbackHandler.setConditions(cp);
+
+ SAMLCallback samlCallback = new SAMLCallback();
+ SAMLUtil.doSAMLCallback(callbackHandler, samlCallback);
+ SamlAssertionWrapper assertion = new SamlAssertionWrapper(samlCallback);
+ String rstr = createSamlToken(assertion, "mystskey", true);
+
+ FedizRequest wfReq = new FedizRequest();
+ wfReq.setAction(FederationConstants.ACTION_SIGNIN);
+ wfReq.setResponseToken(rstr);
+
+ configurator = null;
+ FedizContext config = getFederationConfigurator().getFedizContext("ROOT");
+ ((FederationProtocol)config.getProtocol()).setRoleURI(null);
+
+ FedizProcessor wfProc = new FederationProcessorImpl();
+ FedizResponse wfRes = wfProc.processRequest(wfReq, config);
+
+ Assert.assertEquals("Principal name wrong", TEST_USER,
+ wfRes.getUsername());
+ Assert.assertEquals("Issuer wrong", TEST_RSTR_ISSUER, wfRes.getIssuer());
+ Assert.assertEquals("Two roles must be found", null, wfRes.getRoles());
+ Assert.assertEquals("Audience wrong", TEST_AUDIENCE, wfRes.getAudience());
+ }
+
+ /**
+ * Validate SAML 1.1 token which includes the role attribute with 2 values
+ * Roles are encoded as a multi-value saml attribute
+ */
+ @org.junit.Test
+ public void validateSAML1Token() throws Exception {
+ SAML1CallbackHandler callbackHandler = new SAML1CallbackHandler();
+ callbackHandler.setStatement(SAML1CallbackHandler.Statement.ATTR);
+ callbackHandler.setConfirmationMethod(SAML1Constants.CONF_BEARER);
+ callbackHandler.setIssuer(TEST_RSTR_ISSUER);
+ callbackHandler.setSubjectName(TEST_USER);
+ ConditionsBean cp = new ConditionsBean();
+ AudienceRestrictionBean audienceRestriction = new AudienceRestrictionBean();
+ audienceRestriction.getAudienceURIs().add(TEST_AUDIENCE);
+ cp.setAudienceRestrictions(Collections.singletonList(audienceRestriction));
+ callbackHandler.setConditions(cp);
+
+ SAMLCallback samlCallback = new SAMLCallback();
+ SAMLUtil.doSAMLCallback(callbackHandler, samlCallback);
+ SamlAssertionWrapper assertion = new SamlAssertionWrapper(samlCallback);
+ String rstr = createSamlToken(assertion, "mystskey", true);
+
+ FedizRequest wfReq = new FedizRequest();
+ wfReq.setAction(FederationConstants.ACTION_SIGNIN);
+ wfReq.setResponseToken(rstr);
+
+ configurator = null;
+ FedizContext config = getFederationConfigurator().getFedizContext("ROOT");
+
+ FedizProcessor wfProc = new FederationProcessorImpl();
+ FedizResponse wfRes = wfProc.processRequest(wfReq, config);
+
+ Assert.assertEquals("Principal name wrong", TEST_USER,
+ wfRes.getUsername());
+ Assert.assertEquals("Issuer wrong", TEST_RSTR_ISSUER, wfRes.getIssuer());
+ Assert.assertEquals("Two roles must be found", 2, wfRes.getRoles()
+ .size());
+ Assert.assertEquals("Audience wrong", TEST_AUDIENCE, wfRes.getAudience());
+ assertClaims(wfRes.getClaims(), callbackHandler.getRoleAttributeName());
+ }
+
+ /**
+ * Validate SAML 1.1 token which includes the role attribute with 2 values
+ * Roles are encoded as a multi-value saml attribute
+ * Token embedded in RSTR 2005/02 - WS Federation 1.0
+ */
+ @org.junit.Test
+ public void validateSAML1TokenWSFed10() throws Exception {
+ SAML1CallbackHandler callbackHandler = new SAML1CallbackHandler();
+ callbackHandler.setStatement(SAML1CallbackHandler.Statement.ATTR);
+ callbackHandler.setConfirmationMethod(SAML1Constants.CONF_BEARER);
+ callbackHandler.setIssuer(TEST_RSTR_ISSUER);
+ callbackHandler.setSubjectName(TEST_USER);
+ ConditionsBean cp = new ConditionsBean();
+ AudienceRestrictionBean audienceRestriction = new AudienceRestrictionBean();
+ audienceRestriction.getAudienceURIs().add(TEST_AUDIENCE);
+ cp.setAudienceRestrictions(Collections.singletonList(audienceRestriction));
+ callbackHandler.setConditions(cp);
+
+ SAMLCallback samlCallback = new SAMLCallback();
+ SAMLUtil.doSAMLCallback(callbackHandler, samlCallback);
+ SamlAssertionWrapper assertion = new SamlAssertionWrapper(samlCallback);
+ String rstr = createSamlToken(assertion, "mystskey", true, STSUtil.SAMPLE_RSTR_2005_02_MSG);
+ FedizRequest wfReq = new FedizRequest();
+ wfReq.setAction(FederationConstants.ACTION_SIGNIN);
+ wfReq.setResponseToken(rstr);
+
+ configurator = null;
+ FedizContext config = getFederationConfigurator().getFedizContext("ROOT");
+
+ FedizProcessor wfProc = new FederationProcessorImpl();
+ FedizResponse wfRes = wfProc.processRequest(wfReq, config);
+
+ Assert.assertEquals("Principal name wrong", TEST_USER,
+ wfRes.getUsername());
+ Assert.assertEquals("Issuer wrong", TEST_RSTR_ISSUER, wfRes.getIssuer());
+ Assert.assertEquals("Two roles must be found", 2, wfRes.getRoles()
+ .size());
+ Assert.assertEquals("Audience wrong", TEST_AUDIENCE, wfRes.getAudience());
+ }
+
+ /**
+ * Validate SAML 2 token which includes the role attribute with 2 values
+ * Roles are encoded as a multiple saml attributes with the same name
+ */
+ @org.junit.Test
+ public void validateSAML2TokenRoleMultiAttributes() throws Exception {
+ SAML2CallbackHandler callbackHandler = new SAML2CallbackHandler();
+ callbackHandler.setStatement(SAML2CallbackHandler.Statement.ATTR);
+ callbackHandler.setConfirmationMethod(SAML2Constants.CONF_BEARER);
+ callbackHandler.setIssuer(TEST_RSTR_ISSUER);
+ callbackHandler.setSubjectName(TEST_USER);
+ callbackHandler.setMultiValueType(MultiValue.MULTI_ATTR);
+ ConditionsBean cp = new ConditionsBean();
+ AudienceRestrictionBean audienceRestriction = new AudienceRestrictionBean();
+ audienceRestriction.getAudienceURIs().add(TEST_AUDIENCE);
+ cp.setAudienceRestrictions(Collections.singletonList(audienceRestriction));
+ callbackHandler.setConditions(cp);
+
+ SAMLCallback samlCallback = new SAMLCallback();
+ SAMLUtil.doSAMLCallback(callbackHandler, samlCallback);
+ SamlAssertionWrapper assertion = new SamlAssertionWrapper(samlCallback);
+ String rstr = createSamlToken(assertion, "mystskey", true);
+
+ FedizRequest wfReq = new FedizRequest();
+ wfReq.setAction(FederationConstants.ACTION_SIGNIN);
+ wfReq.setResponseToken(rstr);
+
+ configurator = null;
+ FedizContext config = getFederationConfigurator().getFedizContext("ROOT");
+
+ FedizProcessor wfProc = new FederationProcessorImpl();
+ FedizResponse wfRes = wfProc.processRequest(wfReq, config);
+
+ Assert.assertEquals("Principal name wrong", TEST_USER,
+ wfRes.getUsername());
+ Assert.assertEquals("Issuer wrong", TEST_RSTR_ISSUER, wfRes.getIssuer());
+ Assert.assertEquals("Two roles must be found", 2, wfRes.getRoles()
+ .size());
+ assertClaims(wfRes.getClaims(), callbackHandler.getRoleAttributeName());
+ }
+
+ /**
+ * Validate SAML 2 token which includes the role attribute with 2 values
+ * Roles are encoded as a single saml attribute with encoded value
+ */
+ @org.junit.Test
+ public void validateSAML2TokenRoleEncodedValue() throws Exception {
+ SAML2CallbackHandler callbackHandler = new SAML2CallbackHandler();
+ callbackHandler.setStatement(SAML2CallbackHandler.Statement.ATTR);
+ callbackHandler.setConfirmationMethod(SAML2Constants.CONF_BEARER);
+ callbackHandler.setIssuer(TEST_RSTR_ISSUER);
+ callbackHandler.setSubjectName(TEST_USER);
+ callbackHandler.setMultiValueType(MultiValue.ENC_VALUE);
+ ConditionsBean cp = new ConditionsBean();
+ AudienceRestrictionBean audienceRestriction = new AudienceRestrictionBean();
+ audienceRestriction.getAudienceURIs().add(TEST_AUDIENCE);
+ cp.setAudienceRestrictions(Collections.singletonList(audienceRestriction));
+ callbackHandler.setConditions(cp);
+
+ SAMLCallback samlCallback = new SAMLCallback();
+ SAMLUtil.doSAMLCallback(callbackHandler, samlCallback);
+ SamlAssertionWrapper assertion = new SamlAssertionWrapper(samlCallback);
+ String rstr = createSamlToken(assertion, "mystskey", true);
+
+ FedizRequest wfReq = new FedizRequest();
+ wfReq.setAction(FederationConstants.ACTION_SIGNIN);
+ wfReq.setResponseToken(rstr);
+
+ configurator = null;
+ FedizContext config = getFederationConfigurator().getFedizContext("ROOT");
+ FederationProtocol fp = (FederationProtocol)config.getProtocol();
+ fp.setRoleDelimiter(",");
+
+ FedizProcessor wfProc = new FederationProcessorImpl();
+ FedizResponse wfRes = wfProc.processRequest(wfReq, config);
+
+ Assert.assertEquals("Principal name wrong", TEST_USER,
+ wfRes.getUsername());
+ Assert.assertEquals("Issuer wrong", TEST_RSTR_ISSUER, wfRes.getIssuer());
+ Assert.assertEquals("Two roles must be found", 2, wfRes.getRoles()
+ .size());
+ assertClaims(wfRes.getClaims(), callbackHandler.getRoleAttributeName());
+ }
+
+ /**
+ * Validate SAML 2 token which includes the role attribute with 2 values
+ * The configured subject of the trusted issuer doesn't match with
+ * the issuer of the SAML token
+ *
+ * Ignored because PeerTrust ignores subject attribute
+ */
+ @org.junit.Test
+ @org.junit.Ignore
+ public void validateSAML2TokenUntrustedIssuer() throws Exception {
+ SAML2CallbackHandler callbackHandler = new SAML2CallbackHandler();
+ callbackHandler.setStatement(SAML2CallbackHandler.Statement.ATTR);
+ callbackHandler.setConfirmationMethod(SAML2Constants.CONF_BEARER);
+ callbackHandler.setIssuer(TEST_RSTR_ISSUER);
+ callbackHandler.setSubjectName(TEST_USER);
+ ConditionsBean cp = new ConditionsBean();
+ AudienceRestrictionBean audienceRestriction = new AudienceRestrictionBean();
+ audienceRestriction.getAudienceURIs().add(TEST_AUDIENCE);
+ cp.setAudienceRestrictions(Collections.singletonList(audienceRestriction));
+ callbackHandler.setConditions(cp);
+
+ SAMLCallback samlCallback = new SAMLCallback();
+ SAMLUtil.doSAMLCallback(callbackHandler, samlCallback);
+ SamlAssertionWrapper assertion = new SamlAssertionWrapper(samlCallback);
+
+ String rstr = createSamlToken(assertion, "mystskey", true);
+ FedizRequest wfReq = new FedizRequest();
+ wfReq.setAction(FederationConstants.ACTION_SIGNIN);
+ wfReq.setResponseToken(rstr);
+
+ // Load and update the config to enforce an error
+ configurator = null;
+ FedizContext config = getFederationConfigurator().getFedizContext("ROOT");
+ config.getTrustedIssuers().get(0).setSubject("wrong-issuer-name");
+
+ FedizProcessor wfProc = new FederationProcessorImpl();
+ try {
+ wfProc.processRequest(wfReq, config);
+ Assert.fail("Processing must fail because of untrusted issuer configured");
+ } catch (ProcessingException ex) {
+ if (!TYPE.ISSUER_NOT_TRUSTED.equals(ex.getType())) {
+ fail("Expected ProcessingException with ISSUER_NOT_TRUSTED type");
+ }
+ }
+ }
+
+ /**
+ * Validate SAML 2 token which includes the role attribute with 2 values
+ * The configured subject of the trusted issuer doesn't match with
+ * the issuer of the SAML token
+ */
+ @org.junit.Test
+ public void validateUnsignedSAML2Token() throws Exception {
+ SAML2CallbackHandler callbackHandler = new SAML2CallbackHandler();
+ callbackHandler.setStatement(SAML2CallbackHandler.Statement.ATTR);
+ callbackHandler.setConfirmationMethod(SAML2Constants.CONF_BEARER);
+ callbackHandler.setIssuer(TEST_RSTR_ISSUER);
+ callbackHandler.setSubjectName(TEST_USER);
+ ConditionsBean cp = new ConditionsBean();
+ AudienceRestrictionBean audienceRestriction = new AudienceRestrictionBean();
+ audienceRestriction.getAudienceURIs().add(TEST_AUDIENCE);
+ cp.setAudienceRestrictions(Collections.singletonList(audienceRestriction));
+ callbackHandler.setConditions(cp);
+
+ SAMLCallback samlCallback = new SAMLCallback();
+ SAMLUtil.doSAMLCallback(callbackHandler, samlCallback);
+ SamlAssertionWrapper assertion = new SamlAssertionWrapper(samlCallback);
+
+ String rstr = createSamlToken(assertion, "mystskey", false);
+ FedizRequest wfReq = new FedizRequest();
+ wfReq.setAction(FederationConstants.ACTION_SIGNIN);
+ wfReq.setResponseToken(rstr);
+
+ // Load and update the config to enforce an error
+ configurator = null;
+ FedizContext config = getFederationConfigurator().getFedizContext("ROOT");
+
+ FedizProcessor wfProc = new FederationProcessorImpl();
+ try {
+ wfProc.processRequest(wfReq, config);
+ Assert.fail("Processing must fail because of missing signature");
+ } catch (ProcessingException ex) {
+ if (!TYPE.TOKEN_NO_SIGNATURE.equals(ex.getType())) {
+ fail("Expected ProcessingException with TOKEN_NO_SIGNATURE type");
+ }
+ }
+ }
+
+ /**
+ * Validate SAML 2 token twice which causes an exception
+ * due to replay attack
+ */
+ @org.junit.Test
+ public void testReplayAttack() throws Exception {
+ SAML2CallbackHandler callbackHandler = new SAML2CallbackHandler();
+ callbackHandler.setStatement(SAML2CallbackHandler.Statement.ATTR);
+ callbackHandler.setConfirmationMethod(SAML2Constants.CONF_BEARER);
+ callbackHandler.setIssuer(TEST_RSTR_ISSUER);
+ callbackHandler.setSubjectName(TEST_USER);
+ ConditionsBean cp = new ConditionsBean();
+ AudienceRestrictionBean audienceRestriction = new AudienceRestrictionBean();
+ audienceRestriction.getAudienceURIs().add(TEST_AUDIENCE);
+ cp.setAudienceRestrictions(Collections.singletonList(audienceRestriction));
+ callbackHandler.setConditions(cp);
+
+ SAMLCallback samlCallback = new SAMLCallback();
+ SAMLUtil.doSAMLCallback(callbackHandler, samlCallback);
+ SamlAssertionWrapper assertion = new SamlAssertionWrapper(samlCallback);
+
+ String rstr = createSamlToken(assertion, "mystskey", true);
+
+ FedizRequest wfReq = new FedizRequest();
+ wfReq.setAction(FederationConstants.ACTION_SIGNIN);
+ wfReq.setResponseToken(rstr);
+
+ configurator = null;
+ FedizContext config = getFederationConfigurator().getFedizContext("ROOT");
+
+ FedizProcessor wfProc = new FederationProcessorImpl();
+ FedizResponse wfRes = wfProc.processRequest(wfReq, config);
+ Assert.assertEquals("Principal name wrong", TEST_USER,
+ wfRes.getUsername());
+ Assert.assertEquals("Issuer wrong", TEST_RSTR_ISSUER, wfRes.getIssuer());
+
+ wfProc = new FederationProcessorImpl();
+ try {
+ wfProc.processRequest(wfReq, config);
+ fail("Failure expected on a replay attack");
+ } catch (ProcessingException ex) {
+ if (!TYPE.TOKEN_REPLAY.equals(ex.getType())) {
+ fail("Expected ProcessingException with TOKEN_REPLAY type");
+ }
+ }
+ }
+
+
+ /**
+ * Validate SAML 2 token which includes the role attribute with 2 values
+ * The configured subject of the trusted issuer doesn't match with
+ * the issuer of the SAML token
+ */
+ @org.junit.Test
+ public void validateSAML2TokenSeveralCertStore() throws Exception {
+ SAML2CallbackHandler callbackHandler = new SAML2CallbackHandler();
+ callbackHandler.setStatement(SAML2CallbackHandler.Statement.ATTR);
+ callbackHandler.setConfirmationMethod(SAML2Constants.CONF_BEARER);
+ callbackHandler.setIssuer(TEST_RSTR_ISSUER);
+ callbackHandler.setSubjectName(TEST_USER);
+ ConditionsBean cp = new ConditionsBean();
+ AudienceRestrictionBean audienceRestriction = new AudienceRestrictionBean();
+ audienceRestriction.getAudienceURIs().add(TEST_AUDIENCE);
+ cp.setAudienceRestrictions(Collections.singletonList(audienceRestriction));
+ callbackHandler.setConditions(cp);
+
+ SAMLCallback samlCallback = new SAMLCallback();
+ SAMLUtil.doSAMLCallback(callbackHandler, samlCallback);
+ SamlAssertionWrapper assertion = new SamlAssertionWrapper(samlCallback);
+
+ String rstr = createSamlToken(assertion, "mystskey", true);
+ FedizRequest wfReq = new FedizRequest();
+ wfReq.setAction(FederationConstants.ACTION_SIGNIN);
+ wfReq.setResponseToken(rstr);
+
+ // Load and update the config to enforce an error
+ configurator = null;
+ FedizContext config = getFederationConfigurator().getFedizContext("ROOT2");
+
+ FedizProcessor wfProc = new FederationProcessorImpl();
+ FedizResponse wfRes = wfProc.processRequest(wfReq, config);
+
+ Assert.assertEquals("Principal name wrong", TEST_USER,
+ wfRes.getUsername());
+ Assert.assertEquals("Issuer wrong", TEST_RSTR_ISSUER, wfRes.getIssuer());
+ Assert.assertEquals("Two roles must be found", 2, wfRes.getRoles()
+ .size());
+ }
+
+ /**
+ * Validate SAML 2 token which includes the role attribute with 2 values
+ * The configured subject of the trusted issuer doesn't match with
+ * the issuer of the SAML token
+ */
+ @org.junit.Test
+ public void validateSAML2TokenSeveralCertStoreTrustedIssuer() throws Exception {
+ SAML2CallbackHandler callbackHandler = new SAML2CallbackHandler();
+ callbackHandler.setStatement(SAML2CallbackHandler.Statement.ATTR);
+ callbackHandler.setConfirmationMethod(SAML2Constants.CONF_BEARER);
+ callbackHandler.setIssuer(TEST_RSTR_ISSUER);
+ callbackHandler.setSubjectName(TEST_USER);
+ ConditionsBean cp = new ConditionsBean();
+ AudienceRestrictionBean audienceRestriction = new AudienceRestrictionBean();
+ audienceRestriction.getAudienceURIs().add(TEST_AUDIENCE);
+ cp.setAudienceRestrictions(Collections.singletonList(audienceRestriction));
+ callbackHandler.setConditions(cp);
+
+ SAMLCallback samlCallback = new SAMLCallback();
+ SAMLUtil.doSAMLCallback(callbackHandler, samlCallback);
+ SamlAssertionWrapper assertion = new SamlAssertionWrapper(samlCallback);
+
+ String rstr = createSamlToken(assertion, "mystskey", true);
+ FedizRequest wfReq = new FedizRequest();
+ wfReq.setAction(FederationConstants.ACTION_SIGNIN);
+ wfReq.setResponseToken(rstr);
+
+ // Load and update the config to enforce an error
+ configurator = null;
+ FedizContext config = getFederationConfigurator().getFedizContext("ROOT3");
+
+ FedizProcessor wfProc = new FederationProcessorImpl();
+ FedizResponse wfRes = wfProc.processRequest(wfReq, config);
+
+ Assert.assertEquals("Principal name wrong", TEST_USER,
+ wfRes.getUsername());
+ Assert.assertEquals("Issuer wrong", TEST_RSTR_ISSUER, wfRes.getIssuer());
+ Assert.assertEquals("Two roles must be found", 2, wfRes.getRoles()
+ .size());
+ }
+
+ /**
+ * Validate SAML 2 token which is expired
+ */
+ @org.junit.Test
+ public void validateSAML2TokenExpired() throws Exception {
+ SAML2CallbackHandler callbackHandler = new SAML2CallbackHandler();
+ callbackHandler.setStatement(SAML2CallbackHandler.Statement.ATTR);
+ callbackHandler.setConfirmationMethod(SAML2Constants.CONF_BEARER);
+ callbackHandler.setIssuer(TEST_RSTR_ISSUER);
+ callbackHandler.setSubjectName(TEST_USER);
+ ConditionsBean cp = new ConditionsBean();
+ DateTime currentTime = new DateTime();
+ currentTime = currentTime.minusSeconds(60);
+ cp.setNotAfter(currentTime);
+ currentTime = new DateTime();
+ currentTime = currentTime.minusSeconds(300);
+ cp.setNotBefore(currentTime);
+ AudienceRestrictionBean audienceRestriction = new AudienceRestrictionBean();
+ audienceRestriction.getAudienceURIs().add(TEST_AUDIENCE);
+ cp.setAudienceRestrictions(Collections.singletonList(audienceRestriction));
+ callbackHandler.setConditions(cp);
+
+ SAMLCallback samlCallback = new SAMLCallback();
+ SAMLUtil.doSAMLCallback(callbackHandler, samlCallback);
+ SamlAssertionWrapper assertion = new SamlAssertionWrapper(samlCallback);
+
+ String rstr = createSamlToken(assertion, "mystskey", true);
+
+ FedizRequest wfReq = new FedizRequest();
+ wfReq.setAction(FederationConstants.ACTION_SIGNIN);
+ wfReq.setResponseToken(rstr);
+
+ configurator = null;
+ FedizContext config = getFederationConfigurator().getFedizContext("ROOT");
+
+ FedizProcessor wfProc = new FederationProcessorImpl();
+ try {
+ wfProc.processRequest(wfReq, config);
+ fail("Failure expected on expired SAML token");
+ } catch (ProcessingException ex) {
+ if (!TYPE.TOKEN_EXPIRED.equals(ex.getType())) {
+ fail("Expected ProcessingException with TOKEN_EXPIRED type");
+ }
+ }
+ }
+
+ /**
+ * Validate SAML 2 token which is not yet valid (in 30 seconds)
+ * but within the maximum clock skew range (60 seconds)
+ */
+ @org.junit.Test
+ public void validateSAML2TokenClockSkewRange() throws Exception {
+ SAML2CallbackHandler callbackHandler = new SAML2CallbackHandler();
+ callbackHandler.setStatement(SAML2CallbackHandler.Statement.ATTR);
+ callbackHandler.setConfirmationMethod(SAML2Constants.CONF_BEARER);
+ callbackHandler.setIssuer(TEST_RSTR_ISSUER);
+ callbackHandler.setSubjectName(TEST_USER);
+ ConditionsBean cp = new ConditionsBean();
+ DateTime currentTime = new DateTime();
+ currentTime = currentTime.plusSeconds(300);
+ cp.setNotAfter(currentTime);
+ currentTime = new DateTime();
+ currentTime = currentTime.plusSeconds(30);
+ cp.setNotBefore(currentTime);
+ AudienceRestrictionBean audienceRestriction = new AudienceRestrictionBean();
+ audienceRestriction.getAudienceURIs().add(TEST_AUDIENCE);
+ cp.setAudienceRestrictions(Collections.singletonList(audienceRestriction));
+ callbackHandler.setConditions(cp);
+
+ SAMLCallback samlCallback = new SAMLCallback();
+ SAMLUtil.doSAMLCallback(callbackHandler, samlCallback);
+ SamlAssertionWrapper assertion = new SamlAssertionWrapper(samlCallback);
+
+ String rstr = createSamlToken(assertion, "mystskey", true);
+
+ FedizRequest wfReq = new FedizRequest();
+ wfReq.setAction(FederationConstants.ACTION_SIGNIN);
+ wfReq.setResponseToken(rstr);
+
+ configurator = null;
+ FedizContext config = getFederationConfigurator().getFedizContext("ROOT");
+ config.setMaximumClockSkew(BigInteger.valueOf(60));
+
+ FedizProcessor wfProc = new FederationProcessorImpl();
+ FedizResponse wfRes = wfProc.processRequest(wfReq, config);
+
+ Assert.assertEquals("Principal name wrong", TEST_USER,
+ wfRes.getUsername());
+ Assert.assertEquals("Issuer wrong", TEST_RSTR_ISSUER, wfRes.getIssuer());
+ Assert.assertEquals("Two roles must be found", 2, wfRes.getRoles()
+ .size());
+ }
+
+ /**
+ * "Validate" SAML 2 token with a custom token validator
+ * If a validator is configured it precedes the SAMLTokenValidator as part of Fediz
+ */
+ @org.junit.Test
+ public void validateSAML2TokenCustomValidator() throws Exception {
+ SAML2CallbackHandler callbackHandler = new SAML2CallbackHandler();
+ callbackHandler.setStatement(SAML2CallbackHandler.Statement.ATTR);
+ callbackHandler.setConfirmationMethod(SAML2Constants.CONF_BEARER);
+ callbackHandler.setIssuer(TEST_RSTR_ISSUER);
+ callbackHandler.setSubjectName(TEST_USER);
+ ConditionsBean cp = new ConditionsBean();
+ AudienceRestrictionBean audienceRestriction = new AudienceRestrictionBean();
+ audienceRestriction.getAudienceURIs().add(TEST_AUDIENCE);
+ cp.setAudienceRestrictions(Collections.singletonList(audienceRestriction));
+ callbackHandler.setConditions(cp);
+
+ SAMLCallback samlCallback = new SAMLCallback();
+ SAMLUtil.doSAMLCallback(callbackHandler, samlCallback);
+ SamlAssertionWrapper assertion = new SamlAssertionWrapper(samlCallback);
+
+ String rstr = createSamlToken(assertion, "mystskey", true);
+
+ FedizRequest wfReq = new FedizRequest();
+ wfReq.setAction(FederationConstants.ACTION_SIGNIN);
+ wfReq.setResponseToken(rstr);
+
+ configurator = null;
+ FedizContext config = getFederationConfigurator().getFedizContext("CUSTTOK");
+ FederationProtocol fp = (FederationProtocol)config.getProtocol();
+ List<TokenValidator> validators = fp.getTokenValidators();
+ Assert.assertEquals("Two validators must be found", 2, validators.size());
+ Assert.assertEquals("First validator must be custom validator",
+ CustomValidator.class.getName(), validators.get(0).getClass().getName());
+
+ FedizProcessor wfProc = new FederationProcessorImpl();
+ FedizResponse wfRes = wfProc.processRequest(wfReq, config);
+
+ Assert.assertEquals("Principal name wrong", TEST_USER,
+ wfRes.getUsername());
+ Assert.assertEquals("Issuer wrong", TEST_RSTR_ISSUER, wfRes.getIssuer());
+ }
+
+ /**
+ * "Validate" SAML 2 token with a custom token validator
+ * If a validator is configured it precedes the SAMLTokenValidator as part of Fediz
+ */
+ @org.junit.Test
+ public void validateSAML2TokenMaxClockSkewNotDefined() throws Exception {
+ SAML2CallbackHandler callbackHandler = new SAML2CallbackHandler();
+ callbackHandler.setStatement(SAML2CallbackHandler.Statement.ATTR);
+ callbackHandler.setConfirmationMethod(SAML2Constants.CONF_BEARER);
+ callbackHandler.setIssuer(TEST_RSTR_ISSUER);
+ callbackHandler.setSubjectName(TEST_USER);
+ ConditionsBean cp = new ConditionsBean();
+ AudienceRestrictionBean audienceRestriction = new AudienceRestrictionBean();
+ audienceRestriction.getAudienceURIs().add(TEST_AUDIENCE);
+ cp.setAudienceRestrictions(Collections.singletonList(audienceRestriction));
+ callbackHandler.setConditions(cp);
+
+ SAMLCallback samlCallback = new SAMLCallback();
+ SAMLUtil.doSAMLCallback(callbackHandler, samlCallback);
+ SamlAssertionWrapper assertion = new SamlAssertionWrapper(samlCallback);
+
+ String rstr = createSamlToken(assertion, "mystskey", true);
+
+ FedizRequest wfReq = new FedizRequest();
+ wfReq.setAction(FederationConstants.ACTION_SIGNIN);
+ wfReq.setResponseToken(rstr);
+
+ configurator = null;
+ FedizContext config = getFederationConfigurator().getFedizContext("NOCLOCKSKEW");
+
+ FedizProcessor wfProc = new FederationProcessorImpl();
+ FedizResponse wfRes = wfProc.processRequest(wfReq, config);
+
+ Assert.assertEquals("Principal name wrong", TEST_USER,
+ wfRes.getUsername());
+ Assert.assertEquals("Issuer wrong", TEST_RSTR_ISSUER, wfRes.getIssuer());
+ Assert.assertEquals("Two roles must be found", 2, wfRes.getRoles()
+ .size());
+ Assert.assertEquals("Audience wrong", TEST_AUDIENCE, wfRes.getAudience());
+ }
+
+ /**
+ * Validate an encrypted SAML 2 token which includes the role attribute with 2 values
+ * Roles are encoded as a multi-value saml attribute
+ */
+ @org.junit.Test
+ public void validateEncryptedSAML2Token() throws Exception {
+ SAML2CallbackHandler callbackHandler = new SAML2CallbackHandler();
+ callbackHandler.setStatement(SAML2CallbackHandler.Statement.ATTR);
+ callbackHandler.setConfirmationMethod(SAML2Constants.CONF_BEARER);
+ callbackHandler.setIssuer(TEST_RSTR_ISSUER);
+ callbackHandler.setSubjectName(TEST_USER);
+ ConditionsBean cp = new ConditionsBean();
+ AudienceRestrictionBean audienceRestriction = new AudienceRestrictionBean();
+ audienceRestriction.getAudienceURIs().add(TEST_AUDIENCE);
+ cp.setAudienceRestrictions(Collections.singletonList(audienceRestriction));
+ callbackHandler.setConditions(cp);
+
+ SAMLCallback samlCallback = new SAMLCallback();
+ SAMLUtil.doSAMLCallback(callbackHandler, samlCallback);
+ SamlAssertionWrapper assertion = new SamlAssertionWrapper(samlCallback);
+
+ String rstr = encryptAndSignToken(assertion);
+
+ FedizRequest wfReq = new FedizRequest();
+ wfReq.setAction(FederationConstants.ACTION_SIGNIN);
+ wfReq.setResponseToken(rstr);
+
+ configurator = null;
+ FedizContext config =
+ getFederationConfigurator().getFedizContext("ROOT_DECRYPTION");
+
+ FedizProcessor wfProc = new FederationProcessorImpl();
+ FedizResponse wfRes = wfProc.processRequest(wfReq, config);
+
+ Assert.assertEquals("Principal name wrong", TEST_USER,
+ wfRes.getUsername());
+ Assert.assertEquals("Issuer wrong", TEST_RSTR_ISSUER, wfRes.getIssuer());
+ Assert.assertEquals("Two roles must be found", 2, wfRes.getRoles()
+ .size());
+ Assert.assertEquals("Audience wrong", TEST_AUDIENCE, wfRes.getAudience());
+ assertClaims(wfRes.getClaims(), callbackHandler.getRoleAttributeName());
+ }
+
+ /**
+ * Validate a HolderOfKey SAML 2 token
+ */
+ @org.junit.Test
+ public void validateHOKSAML2Token() throws Exception {
+ SAML2CallbackHandler callbackHandler = new SAML2CallbackHandler();
+ callbackHandler.setStatement(SAML2CallbackHandler.Statement.AUTHN);
+ callbackHandler.setConfirmationMethod(SAML2Constants.CONF_HOLDER_KEY);
+ callbackHandler.setIssuer(TEST_RSTR_ISSUER);
+ callbackHandler.setSubjectName(TEST_USER);
+ ConditionsBean cp = new ConditionsBean();
+ AudienceRestrictionBean audienceRestriction = new AudienceRestrictionBean();
+ audienceRestriction.getAudienceURIs().add(TEST_AUDIENCE);
+ cp.setAudienceRestrictions(Collections.singletonList(audienceRestriction));
+ callbackHandler.setConditions(cp);
+
+ Crypto clientCrypto = CryptoFactory.getInstance("client-crypto.properties");
+ CryptoType cryptoType = new CryptoType(CryptoType.TYPE.ALIAS);
+ cryptoType.setAlias("myclientkey");
+ X509Certificate[] certs = clientCrypto.getX509Certificates(cryptoType);
+ callbackHandler.setCerts(certs);
+
+ 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);
+
+ Document doc = STSUtil.toSOAPPart(STSUtil.SAMPLE_RSTR_COLL_MSG);
+ Element token = assertion.toDOM(doc);
+
+ Element e = FederationProcessorTest.findElement(doc, "RequestedSecurityToken",
+ FederationConstants.WS_TRUST_13_NS);
+ if (e == null) {
+ e = FederationProcessorTest.findElement(doc, "RequestedSecurityToken",
+ FederationConstants.WS_TRUST_2005_02_NS);
+ }
+ e.appendChild(token);
+
+ String rstr = DOM2Writer.nodeToString(doc);
+
+ FedizRequest wfReq = new FedizRequest();
+ wfReq.setAction(FederationConstants.ACTION_SIGNIN);
+ wfReq.setResponseToken(rstr);
+
+ configurator = null;
+ FedizContext config =
+ getFederationConfigurator().getFedizContext("ROOT_DECRYPTION");
+
+ FedizProcessor wfProc = new FederationProcessorImpl();
+ try {
+ wfProc.processRequest(wfReq, config);
+ fail("Failure expected on missing client certs");
+ } catch (ProcessingException ex) {
+ // expected
+ }
+
+ // Now set client certs
+ wfReq.setCerts(certs);
+ wfProc.processRequest(wfReq, config);
+ }
+
+ @org.junit.Test
+ public void validateSAML2TokenWithConfigCreatedWithAPI() throws Exception {
+
+ ContextConfig config = new ContextConfig();
+
+ config.setName("whatever");
+
+ // Configure certificate store
+ CertificateStores certStores = new CertificateStores();
+ TrustManagersType tm0 = new TrustManagersType();
+ KeyStoreType ks0 = new KeyStoreType();
+ ks0.setType("JKS");
+ ks0.setPassword("storepass");
+ ks0.setFile("ststrust.jks");
+ tm0.setKeyStore(ks0);
+ certStores.getTrustManager().add(tm0);
+ config.setCertificateStores(certStores);
+
+ // Configure trusted IDP
+ TrustedIssuers trustedIssuers = new TrustedIssuers();
+ TrustedIssuerType ti0 = new TrustedIssuerType();
+ ti0.setCertificateValidation(ValidationType.CHAIN_TRUST);
+ ti0.setName("FedizSTSIssuer");
+ ti0.setSubject(".*CN=www.sts.com.*");
+ trustedIssuers.getIssuer().add(ti0);
+ config.setTrustedIssuers(trustedIssuers);
+
+ FederationProtocolType protocol = new FederationProtocolType();
+ config.setProtocol(protocol);
+
+ AudienceUris audienceUris = new AudienceUris();
+ audienceUris.getAudienceItem().add("https://localhost/fedizhelloworld");
+ config.setAudienceUris(audienceUris);
+
+ protocol.setRoleURI("http://schemas.xmlsoap.org/ws/2005/05/identity/claims/role");
+
+ FedizContext fedContext = new FedizContext(config);
+
+ SAML2CallbackHandler callbackHandler = new SAML2CallbackHandler();
+ callbackHandler.setStatement(SAML2CallbackHandler.Statement.ATTR);
+ callbackHandler.setConfirmationMethod(SAML2Constants.CONF_BEARER);
+ callbackHandler.setIssuer(TEST_RSTR_ISSUER);
+ callbackHandler.setSubjectName(TEST_USER);
+ ConditionsBean cp = new ConditionsBean();
+ AudienceRestrictionBean audienceRestriction = new AudienceRestrictionBean();
+ audienceRestriction.getAudienceURIs().add(TEST_AUDIENCE);
+ cp.setAudienceRestrictions(Collections.singletonList(audienceRestriction));
+ callbackHandler.setConditions(cp);
+
+ SAMLCallback samlCallback = new SAMLCallback();
+ SAMLUtil.doSAMLCallback(callbackHandler, samlCallback);
+ SamlAssertionWrapper assertion = new SamlAssertionWrapper(samlCallback);
+
+ String rstr = createSamlToken(assertion, "mystskey", true, STSUtil.SAMPLE_RSTR_MSG);
+
+ FedizRequest wfReq = new FedizRequest();
+ wfReq.setAction(FederationConstants.ACTION_SIGNIN);
+ wfReq.setResponseToken(rstr);
+
+ FedizProcessor wfProc = new FederationProcessorImpl();
+ FedizResponse wfRes = wfProc.processRequest(wfReq, fedContext);
+
+ Assert.assertEquals("Principal name wrong", TEST_USER,
+ wfRes.getUsername());
+ Assert.assertEquals("Issuer wrong", TEST_RSTR_ISSUER, wfRes.getIssuer());
+ Assert.assertEquals("Two roles must be found", 2, wfRes.getRoles()
+ .size());
+ Assert.assertEquals("Audience wrong", TEST_AUDIENCE, wfRes.getAudience());
+
+ fedContext.close();
+
+ }
+
+
+ private String encryptAndSignToken(
+ SamlAssertionWrapper assertion
+ ) throws Exception {
+
+ WSPasswordCallback[] cb = {
+ new WSPasswordCallback("mystskey", WSPasswordCallback.SIGNATURE)
+ };
+ cbPasswordHandler.handle(cb);
+ String password = cb[0].getPassword();
+
+ assertion.signAssertion("mystskey", password, crypto, false);
+
+ Document doc = STSUtil.toSOAPPart(STSUtil.SAMPLE_RSTR_COLL_MSG);
+ Element token = assertion.toDOM(doc);
+
+ Element e = FederationProcessorTest.findElement(doc, "RequestedSecurityToken",
+ FederationConstants.WS_TRUST_13_NS);
+ if (e == null) {
+ e = FederationProcessorTest.findElement(doc, "RequestedSecurityToken",
+ FederationConstants.WS_TRUST_2005_02_NS);
+ }
+ e.appendChild(token);
+
+ WSSecEncrypt builder = new WSSecEncrypt();
+ builder.setUserInfo("mystskey");
+
+ builder.setKeyIdentifierType(WSConstants.ISSUER_SERIAL);
+ builder.setSymmetricEncAlgorithm(WSConstants.AES_128);
+ builder.setKeyEncAlgo(WSConstants.KEYTRANSPORT_RSA15);
+ builder.setEmbedEncryptedKey(true);
+
+ WSEncryptionPart encryptionPart = new WSEncryptionPart(assertion.getId(), "Element");
+ encryptionPart.setElement(token);
+
+ Crypto encrCrypto = CryptoFactory.getInstance("signature.properties");
+ builder.prepare(token.getOwnerDocument(), encrCrypto);
+ builder.encryptForRef(null, Collections.singletonList(encryptionPart));
+
+ // return doc.getDocumentElement();
+ return DOM2Writer.nodeToString(doc);
+ }
+
+ private String createSamlToken(SamlAssertionWrapper assertion, String alias, boolean sign)
+ throws IOException, UnsupportedCallbackException, WSSecurityException, Exception {
+ return createSamlToken(assertion, alias, sign, STSUtil.SAMPLE_RSTR_COLL_MSG);
+ }
+
+ private String createSamlToken(SamlAssertionWrapper assertion, String alias, boolean sign, String rstr)
+ 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);
+ }
+ Document doc = STSUtil.toSOAPPart(rstr);
+ Element token = assertion.toDOM(doc);
+
+ Element e = FederationProcessorTest.findElement(doc, "RequestedSecurityToken",
+ FederationConstants.WS_TRUST_13_NS);
+ if (e == null) {
+ e = FederationProcessorTest.findElement(doc, "RequestedSecurityToken",
+ FederationConstants.WS_TRUST_2005_02_NS);
+ }
+ e.appendChild(token);
+ return DOM2Writer.nodeToString(doc);
+ }
+
+
+
+
+ /**
+ * 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 void assertClaims(List<Claim> claims, String roleClaimType) {
+ for (Claim c : claims) {
+ Assert.assertTrue("Invalid ClaimType URI: " + c.getClaimType(),
+ c.getClaimType().equals(roleClaimType)
+ || c.getClaimType().equals(ClaimTypes.COUNTRY)
+ || c.getClaimType().equals(AbstractSAMLCallbackHandler.CLAIM_TYPE_LANGUAGE)
+ );
+ }
+ }
+
+
+}
[2/4] Adding unit tests for SAML SSO
Posted by co...@apache.org.
http://git-wip-us.apache.org/repos/asf/cxf-fediz/blob/617fd4e9/plugins/core/src/test/java/org/apache/cxf/fediz/core/federation/SAMLTokenValidatorOldTest.java
----------------------------------------------------------------------
diff --git a/plugins/core/src/test/java/org/apache/cxf/fediz/core/federation/SAMLTokenValidatorOldTest.java b/plugins/core/src/test/java/org/apache/cxf/fediz/core/federation/SAMLTokenValidatorOldTest.java
new file mode 100644
index 0000000..fb21c21
--- /dev/null
+++ b/plugins/core/src/test/java/org/apache/cxf/fediz/core/federation/SAMLTokenValidatorOldTest.java
@@ -0,0 +1,399 @@
+/**
+ * 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.federation;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.URL;
+import java.util.Collections;
+import java.util.List;
+
+import javax.security.auth.callback.CallbackHandler;
+import javax.security.auth.callback.UnsupportedCallbackException;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.apache.cxf.fediz.common.STSUtil;
+import org.apache.cxf.fediz.common.SecurityTestUtil;
+import org.apache.cxf.fediz.core.AbstractSAMLCallbackHandler;
+import org.apache.cxf.fediz.core.Claim;
+import org.apache.cxf.fediz.core.ClaimTypes;
+import org.apache.cxf.fediz.core.FederationConstants;
+import org.apache.cxf.fediz.core.KeystoreCallbackHandler;
+import org.apache.cxf.fediz.core.SAML1CallbackHandler;
+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.processor.FederationProcessorImpl;
+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.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.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.builder.SAML1Constants;
+import org.apache.wss4j.common.saml.builder.SAML2Constants;
+import org.apache.wss4j.common.util.DOM2Writer;
+import org.junit.AfterClass;
+import org.junit.Assert;
+import org.junit.BeforeClass;
+
+
+// This testcases tests the encoding implemented before CXF-4484
+public class SAMLTokenValidatorOldTest {
+ static final String TEST_USER = "alice";
+ static final String TEST_RSTR_ISSUER = "FedizSTSIssuer";
+ static final String TEST_AUDIENCE = "https://localhost/fedizhelloworld";
+
+ private static final String CONFIG_FILE = "fediz_test_config.xml";
+
+ private static Crypto crypto;
+ private static CallbackHandler cbPasswordHandler;
+ private static FedizConfigurator configurator;
+
+
+ @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;
+ }
+ }
+
+ /**
+ * Validate SAML 2 token which includes the role attribute with 2 values
+ * Roles are encoded as a multi-value saml attribute
+ */
+ @org.junit.Test
+ public void validateSAML2Token() throws Exception {
+ SAML2CallbackHandler callbackHandler = new SAML2CallbackHandler();
+ callbackHandler.setStatement(SAML2CallbackHandler.Statement.ATTR);
+ callbackHandler.setConfirmationMethod(SAML2Constants.CONF_BEARER);
+ callbackHandler.setIssuer(TEST_RSTR_ISSUER);
+ callbackHandler.setSubjectName(TEST_USER);
+ callbackHandler.setAttributeNameFormat(ClaimTypes.URI_BASE.toString());
+ callbackHandler.setCountryClaimName("country");
+ callbackHandler.setRoleAttributeName("role");
+
+ ConditionsBean cp = new ConditionsBean();
+ AudienceRestrictionBean audienceRestriction = new AudienceRestrictionBean();
+ audienceRestriction.getAudienceURIs().add(TEST_AUDIENCE);
+ cp.setAudienceRestrictions(Collections.singletonList(audienceRestriction));
+ callbackHandler.setConditions(cp);
+
+ SAMLCallback samlCallback = new SAMLCallback();
+ SAMLUtil.doSAMLCallback(callbackHandler, samlCallback);
+ SamlAssertionWrapper assertion = new SamlAssertionWrapper(samlCallback);
+
+ String rstr = createSamlToken(assertion, "mystskey", true);
+
+ FedizRequest wfReq = new FedizRequest();
+ wfReq.setAction(FederationConstants.ACTION_SIGNIN);
+ wfReq.setResponseToken(rstr);
+
+ configurator = null;
+ FedizContext config = getFederationConfigurator().getFedizContext("ROOT");
+
+ FedizProcessor wfProc = new FederationProcessorImpl();
+ FedizResponse wfRes = wfProc.processRequest(wfReq, config);
+
+ Assert.assertEquals("Principal name wrong", TEST_USER,
+ wfRes.getUsername());
+ Assert.assertEquals("Issuer wrong", TEST_RSTR_ISSUER, wfRes.getIssuer());
+ Assert.assertEquals("Two roles must be found", 2, wfRes.getRoles()
+ .size());
+ Assert.assertEquals("Audience wrong", TEST_AUDIENCE, wfRes.getAudience());
+ assertClaims(wfRes.getClaims(), callbackHandler.getRoleAttributeName());
+
+ }
+
+ /**
+ * Validate SAML 2 token where role information is provided
+ * within another SAML attribute
+ */
+ @org.junit.Test
+ public void validateSAML2TokenDifferentRoleURI() throws Exception {
+ SAML2CallbackHandler callbackHandler = new SAML2CallbackHandler();
+ callbackHandler.setStatement(SAML2CallbackHandler.Statement.ATTR);
+ callbackHandler.setConfirmationMethod(SAML2Constants.CONF_BEARER);
+ callbackHandler.setIssuer(TEST_RSTR_ISSUER);
+ callbackHandler.setSubjectName(TEST_USER);
+ callbackHandler.setAttributeNameFormat(ClaimTypes.URI_BASE.toString());
+ callbackHandler.setCountryClaimName("country");
+ callbackHandler.setRoleAttributeName("http://schemas.mycompany.com/claims/role");
+
+ ConditionsBean cp = new ConditionsBean();
+ AudienceRestrictionBean audienceRestriction = new AudienceRestrictionBean();
+ audienceRestriction.getAudienceURIs().add(TEST_AUDIENCE);
+ cp.setAudienceRestrictions(Collections.singletonList(audienceRestriction));
+ callbackHandler.setConditions(cp);
+
+ SAMLCallback samlCallback = new SAMLCallback();
+ SAMLUtil.doSAMLCallback(callbackHandler, samlCallback);
+ SamlAssertionWrapper assertion = new SamlAssertionWrapper(samlCallback);
+
+ String rstr = createSamlToken(assertion, "mystskey", true);
+
+ FedizRequest wfReq = new FedizRequest();
+ wfReq.setAction(FederationConstants.ACTION_SIGNIN);
+ wfReq.setResponseToken(rstr);
+
+ configurator = null;
+ FedizContext config = getFederationConfigurator().getFedizContext("CUSTOMROLEURI");
+
+ FedizProcessor wfProc = new FederationProcessorImpl();
+ FedizResponse wfRes = wfProc.processRequest(wfReq, config);
+
+ Assert.assertEquals("Principal name wrong", TEST_USER, wfRes.getUsername());
+ Assert.assertEquals("Issuer wrong", TEST_RSTR_ISSUER, wfRes.getIssuer());
+ Assert.assertEquals("Two roles must be found", 2, wfRes.getRoles().size());
+ Assert.assertEquals("Audience wrong", TEST_AUDIENCE, wfRes.getAudience());
+ assertClaims(wfRes.getClaims(), callbackHandler.getRoleAttributeName());
+ }
+
+ /**
+ * Validate SAML 2 token where role information is provided
+ * within another SAML attribute
+ */
+ @org.junit.Test
+ public void validateSAML1TokenDifferentRoleURI() throws Exception {
+ SAML1CallbackHandler callbackHandler = new SAML1CallbackHandler();
+ callbackHandler.setStatement(SAML1CallbackHandler.Statement.ATTR);
+ callbackHandler.setConfirmationMethod(SAML2Constants.CONF_BEARER);
+ callbackHandler.setIssuer(TEST_RSTR_ISSUER);
+ callbackHandler.setSubjectName(TEST_USER);
+ callbackHandler.setUseNameFormatAsNamespace(true);
+ callbackHandler.setAttributeNameFormat(ClaimTypes.URI_BASE.toString());
+ callbackHandler.setRoleAttributeName("http://schemas.mycompany.com/claims/role");
+ ConditionsBean cp = new ConditionsBean();
+ AudienceRestrictionBean audienceRestriction = new AudienceRestrictionBean();
+ audienceRestriction.getAudienceURIs().add(TEST_AUDIENCE);
+ cp.setAudienceRestrictions(Collections.singletonList(audienceRestriction));
+ callbackHandler.setConditions(cp);
+
+ SAMLCallback samlCallback = new SAMLCallback();
+ SAMLUtil.doSAMLCallback(callbackHandler, samlCallback);
+ SamlAssertionWrapper assertion = new SamlAssertionWrapper(samlCallback);
+
+ String rstr = createSamlToken(assertion, "mystskey", true);
+
+ FedizRequest wfReq = new FedizRequest();
+ wfReq.setAction(FederationConstants.ACTION_SIGNIN);
+ wfReq.setResponseToken(rstr);
+
+ configurator = null;
+ FedizContext config = getFederationConfigurator().getFedizContext("CUSTOMROLEURI");
+
+ FedizProcessor wfProc = new FederationProcessorImpl();
+ FedizResponse wfRes = wfProc.processRequest(wfReq, config);
+
+ Assert.assertEquals("Principal name wrong", TEST_USER, wfRes.getUsername());
+ Assert.assertEquals("Issuer wrong", TEST_RSTR_ISSUER, wfRes.getIssuer());
+ Assert.assertEquals("Two roles must be found", 2, wfRes.getRoles().size());
+ Assert.assertEquals("Audience wrong", TEST_AUDIENCE, wfRes.getAudience());
+ assertClaims(wfRes.getClaims(), callbackHandler.getRoleAttributeName());
+ }
+
+ /**
+ * Validate SAML 1.1 token which includes the role attribute with 2 values
+ * Roles are encoded as a multi-value saml attribute
+ */
+ @org.junit.Test
+ public void validateSAML1Token() throws Exception {
+ SAML1CallbackHandler callbackHandler = new SAML1CallbackHandler();
+ callbackHandler.setStatement(SAML1CallbackHandler.Statement.ATTR);
+ callbackHandler.setConfirmationMethod(SAML1Constants.CONF_BEARER);
+ callbackHandler.setIssuer(TEST_RSTR_ISSUER);
+ callbackHandler.setSubjectName(TEST_USER);
+ callbackHandler.setUseNameFormatAsNamespace(true);
+ callbackHandler.setAttributeNameFormat(ClaimTypes.URI_BASE.toString());
+ callbackHandler.setRoleAttributeName("role");
+
+ ConditionsBean cp = new ConditionsBean();
+ AudienceRestrictionBean audienceRestriction = new AudienceRestrictionBean();
+ audienceRestriction.getAudienceURIs().add(TEST_AUDIENCE);
+ cp.setAudienceRestrictions(Collections.singletonList(audienceRestriction));
+ callbackHandler.setConditions(cp);
+
+ SAMLCallback samlCallback = new SAMLCallback();
+ SAMLUtil.doSAMLCallback(callbackHandler, samlCallback);
+ SamlAssertionWrapper assertion = new SamlAssertionWrapper(samlCallback);
+
+ String rstr = createSamlToken(assertion, "mystskey", true);
+
+ FedizRequest wfReq = new FedizRequest();
+ wfReq.setAction(FederationConstants.ACTION_SIGNIN);
+ wfReq.setResponseToken(rstr);
+
+ configurator = null;
+ FedizContext config = getFederationConfigurator().getFedizContext("ROOT");
+
+ FedizProcessor wfProc = new FederationProcessorImpl();
+ FedizResponse wfRes = wfProc.processRequest(wfReq, config);
+
+ Assert.assertEquals("Principal name wrong", TEST_USER,
+ wfRes.getUsername());
+ Assert.assertEquals("Issuer wrong", TEST_RSTR_ISSUER, wfRes.getIssuer());
+ Assert.assertEquals("Two roles must be found", 2, wfRes.getRoles()
+ .size());
+ Assert.assertEquals("Audience wrong", TEST_AUDIENCE, wfRes.getAudience());
+ assertClaims(wfRes.getClaims(), callbackHandler.getRoleAttributeName());
+ }
+
+
+ private String createSamlToken(SamlAssertionWrapper assertion, String alias, boolean sign)
+ throws IOException, UnsupportedCallbackException, WSSecurityException, Exception {
+ return createSamlToken(assertion, alias, sign, STSUtil.SAMPLE_RSTR_COLL_MSG);
+ }
+
+ private String createSamlToken(SamlAssertionWrapper assertion, String alias, boolean sign, String rstr)
+ 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);
+ }
+ Document doc = STSUtil.toSOAPPart(rstr);
+ Element token = assertion.toDOM(doc);
+
+ Element e = SAMLTokenValidatorOldTest.findElement(doc, "RequestedSecurityToken",
+ FederationConstants.WS_TRUST_13_NS);
+ if (e == null) {
+ e = SAMLTokenValidatorOldTest.findElement(doc, "RequestedSecurityToken",
+ FederationConstants.WS_TRUST_2005_02_NS);
+ }
+ e.appendChild(token);
+ return DOM2Writer.nodeToString(doc);
+ }
+
+
+
+
+ /**
+ * 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 void assertClaims(List<Claim> claims, String roleClaimType) {
+ for (Claim c : claims) {
+ Assert.assertTrue("Invalid ClaimType URI: " + c.getClaimType(),
+ c.getClaimType().equals(roleClaimType)
+ || c.getClaimType().equals(ClaimTypes.COUNTRY)
+ || c.getClaimType().equals(AbstractSAMLCallbackHandler.CLAIM_TYPE_LANGUAGE)
+ );
+ }
+ }
+
+
+
+
+}
http://git-wip-us.apache.org/repos/asf/cxf-fediz/blob/617fd4e9/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
new file mode 100644
index 0000000..ffaade7
--- /dev/null
+++ b/plugins/core/src/test/java/org/apache/cxf/fediz/core/samlsso/SAML2PResponseComponentBuilder.java
@@ -0,0 +1,126 @@
+/**
+ * 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.util.UUID;
+
+import org.joda.time.DateTime;
+import org.opensaml.Configuration;
+import org.opensaml.common.SAMLObjectBuilder;
+import org.opensaml.common.SAMLVersion;
+import org.opensaml.saml2.core.Issuer;
+import org.opensaml.saml2.core.Response;
+import org.opensaml.saml2.core.Status;
+import org.opensaml.saml2.core.StatusCode;
+import org.opensaml.saml2.core.StatusMessage;
+import org.opensaml.xml.XMLObjectBuilderFactory;
+
+/**
+* A (basic) set of utility methods to construct SAML 2.0 Protocol Response statements
+*/
+public final class SAML2PResponseComponentBuilder {
+
+ private static SAMLObjectBuilder<Response> responseBuilder;
+
+ private static SAMLObjectBuilder<Issuer> issuerBuilder;
+
+ private static SAMLObjectBuilder<Status> statusBuilder;
+
+ private static SAMLObjectBuilder<StatusCode> statusCodeBuilder;
+
+ private static SAMLObjectBuilder<StatusMessage> statusMessageBuilder;
+
+ private static XMLObjectBuilderFactory builderFactory = Configuration.getBuilderFactory();
+
+ private SAML2PResponseComponentBuilder() {
+
+ }
+
+ @SuppressWarnings("unchecked")
+ public static Response createSAMLResponse(
+ String inResponseTo,
+ String issuer,
+ Status status
+ ) {
+ if (responseBuilder == null) {
+ responseBuilder = (SAMLObjectBuilder<Response>)
+ builderFactory.getBuilder(Response.DEFAULT_ELEMENT_NAME);
+ }
+ Response response = responseBuilder.buildObject();
+
+ response.setID(UUID.randomUUID().toString());
+ response.setIssueInstant(new DateTime());
+ response.setInResponseTo(inResponseTo);
+ response.setIssuer(createIssuer(issuer));
+ response.setStatus(status);
+ response.setVersion(SAMLVersion.VERSION_20);
+
+ return response;
+ }
+
+ @SuppressWarnings("unchecked")
+ public static Issuer createIssuer(
+ String issuerValue
+ ) {
+ if (issuerBuilder == null) {
+ issuerBuilder = (SAMLObjectBuilder<Issuer>)
+ builderFactory.getBuilder(Issuer.DEFAULT_ELEMENT_NAME);
+ }
+ Issuer issuer = issuerBuilder.buildObject();
+ issuer.setValue(issuerValue);
+
+ return issuer;
+ }
+
+ @SuppressWarnings("unchecked")
+ public static Status createStatus(
+ String statusCodeValue,
+ String statusMessage
+ ) {
+ if (statusBuilder == null) {
+ statusBuilder = (SAMLObjectBuilder<Status>)
+ builderFactory.getBuilder(Status.DEFAULT_ELEMENT_NAME);
+ }
+ if (statusCodeBuilder == null) {
+ statusCodeBuilder = (SAMLObjectBuilder<StatusCode>)
+ builderFactory.getBuilder(StatusCode.DEFAULT_ELEMENT_NAME);
+ }
+ if (statusMessageBuilder == null) {
+ statusMessageBuilder = (SAMLObjectBuilder<StatusMessage>)
+ builderFactory.getBuilder(StatusMessage.DEFAULT_ELEMENT_NAME);
+ }
+
+ Status status = statusBuilder.buildObject();
+
+ StatusCode statusCode = statusCodeBuilder.buildObject();
+ statusCode.setValue(statusCodeValue);
+ status.setStatusCode(statusCode);
+
+ if (statusMessage != null) {
+ StatusMessage statusMessageObject = statusMessageBuilder.buildObject();
+ statusMessageObject.setMessage(statusMessage);
+ status.setStatusMessage(statusMessageObject);
+ }
+
+ return status;
+ }
+
+
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/cxf-fediz/blob/617fd4e9/plugins/core/src/test/java/org/apache/cxf/fediz/core/samlsso/SAMLRequestTest.java
----------------------------------------------------------------------
diff --git a/plugins/core/src/test/java/org/apache/cxf/fediz/core/samlsso/SAMLRequestTest.java b/plugins/core/src/test/java/org/apache/cxf/fediz/core/samlsso/SAMLRequestTest.java
new file mode 100644
index 0000000..cfbc8d2
--- /dev/null
+++ b/plugins/core/src/test/java/org/apache/cxf/fediz/core/samlsso/SAMLRequestTest.java
@@ -0,0 +1,205 @@
+/**
+ * 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.InputStream;
+import java.io.InputStreamReader;
+import java.net.URL;
+import java.net.URLDecoder;
+import java.util.Map;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.xml.parsers.DocumentBuilderFactory;
+
+import org.w3c.dom.Document;
+
+import org.apache.cxf.fediz.common.SecurityTestUtil;
+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.processor.FedizProcessor;
+import org.apache.cxf.fediz.core.processor.RedirectionResponse;
+import org.apache.cxf.fediz.core.processor.SAMLProcessorImpl;
+import org.apache.cxf.fediz.core.util.DOMUtils;
+import org.apache.wss4j.common.saml.OpenSAMLUtil;
+import org.apache.xml.security.utils.Base64;
+import org.easymock.EasyMock;
+import org.junit.AfterClass;
+import org.junit.Assert;
+import org.junit.BeforeClass;
+import org.opensaml.saml2.core.AuthnRequest;
+
+/**
+ * Some tests for creating SAMLRequests using the SAMLProcessorImpl
+ */
+public class SAMLRequestTest {
+ 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 FedizConfigurator configurator;
+ private static DocumentBuilderFactory docBuilderFactory;
+
+ static {
+ docBuilderFactory = DocumentBuilderFactory.newInstance();
+ docBuilderFactory.setNamespaceAware(true);
+ }
+
+
+ @BeforeClass
+ public static void init() {
+ getFederationConfigurator();
+ 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 createSAMLRequest() throws Exception {
+ // Mock up a Request
+ FedizContext config = getFederationConfigurator().getFedizContext("ROOT");
+
+ HttpServletRequest req = EasyMock.createMock(HttpServletRequest.class);
+ EasyMock.expect(req.getRequestURL()).andReturn(new StringBuffer(TEST_REQUEST_URL)).times(1, 2);
+ EasyMock.expect(req.getContextPath()).andReturn(TEST_REQUEST_URI);
+ EasyMock.expect(req.getRequestURI()).andReturn(TEST_REQUEST_URI).times(1, 2);
+ EasyMock.replay(req);
+
+ FedizProcessor wfProc = new SAMLProcessorImpl();
+ RedirectionResponse response = wfProc.createSignInRequest(req, config);
+
+ String redirectionURL = response.getRedirectionURL();
+ Assert.assertTrue(redirectionURL.startsWith(TEST_IDP_ISSUER));
+ Assert.assertTrue(redirectionURL.contains("SAMLRequest="));
+ Assert.assertTrue(redirectionURL.contains("RelayState="));
+
+ Map<String, String> headers = response.getHeaders();
+ Assert.assertNotNull(headers);
+ Assert.assertFalse(headers.isEmpty());
+ Assert.assertTrue(headers.containsKey("Set-Cookie"));
+ Assert.assertTrue("no-cache, no-store".equals(headers.get("Cache-Control")));
+ Assert.assertTrue("no-cache".equals(headers.get("Pragma")));
+ }
+
+ @org.junit.Test
+ public void testRelayState() throws Exception {
+ // Mock up a Request
+ FedizContext config = getFederationConfigurator().getFedizContext("ROOT");
+
+ HttpServletRequest req = EasyMock.createMock(HttpServletRequest.class);
+ EasyMock.expect(req.getRequestURL()).andReturn(new StringBuffer(TEST_REQUEST_URL)).times(1, 2);
+ EasyMock.expect(req.getContextPath()).andReturn(TEST_REQUEST_URI);
+ EasyMock.expect(req.getRequestURI()).andReturn(TEST_REQUEST_URI).times(1, 2);
+ EasyMock.replay(req);
+
+ FedizProcessor wfProc = new SAMLProcessorImpl();
+ RedirectionResponse response = wfProc.createSignInRequest(req, config);
+
+ String redirectionURL = response.getRedirectionURL();
+ String relayState =
+ redirectionURL.substring(redirectionURL.indexOf("RelayState=") + "RelayState=".length());
+
+ // Now retrieve the RequestState corresponding to the RelayState
+ RequestState requestState =
+ ((SAMLProtocol)config.getProtocol()).getStateManager().removeRequestState(relayState);
+ Assert.assertNotNull(requestState);
+
+ Assert.assertEquals(TEST_IDP_ISSUER, requestState.getIdpServiceAddress());
+ Assert.assertEquals(TEST_REQUEST_URL, requestState.getIssuerId());
+ Assert.assertEquals(TEST_REQUEST_URL, requestState.getTargetAddress());
+ }
+
+ @org.junit.Test
+ public void testSAMLRequest() throws Exception {
+ // Mock up a Request
+ FedizContext config = getFederationConfigurator().getFedizContext("ROOT");
+
+ HttpServletRequest req = EasyMock.createMock(HttpServletRequest.class);
+ EasyMock.expect(req.getRequestURL()).andReturn(new StringBuffer(TEST_REQUEST_URL)).times(1, 2);
+ EasyMock.expect(req.getContextPath()).andReturn(TEST_REQUEST_URI);
+ EasyMock.expect(req.getRequestURI()).andReturn(TEST_REQUEST_URI).times(1, 2);
+ EasyMock.replay(req);
+
+ FedizProcessor wfProc = new SAMLProcessorImpl();
+ RedirectionResponse response = wfProc.createSignInRequest(req, config);
+
+ String redirectionURL = response.getRedirectionURL();
+ String samlRequest =
+ redirectionURL.substring(redirectionURL.indexOf("SAMLRequest=") + "SAMLRequest=".length(),
+ redirectionURL.indexOf("RelayState=") - 1);
+
+ byte[] deflatedToken = Base64.decode(URLDecoder.decode(samlRequest, "UTF-8"));
+ InputStream tokenStream = CompressionUtils.inflate(deflatedToken);
+
+ Document requestDoc = DOMUtils.readXml(new InputStreamReader(tokenStream, "UTF-8"));
+ AuthnRequest request =
+ (AuthnRequest)OpenSAMLUtil.fromDom(requestDoc.getDocumentElement());
+
+ Assert.assertEquals(TEST_REQUEST_URL, request.getIssuer().getValue());
+ Assert.assertEquals(TEST_REQUEST_URL, request.getAssertionConsumerServiceURL());
+ }
+
+ @org.junit.Test
+ public void testSignedSAMLRequest() throws Exception {
+ // Mock up a Request
+ FedizContext config = getFederationConfigurator().getFedizContext("SIGNED_ROOT");
+
+ HttpServletRequest req = EasyMock.createMock(HttpServletRequest.class);
+ EasyMock.expect(req.getRequestURL()).andReturn(new StringBuffer(TEST_REQUEST_URL)).times(1, 2);
+ EasyMock.expect(req.getContextPath()).andReturn(TEST_REQUEST_URI);
+ EasyMock.expect(req.getRequestURI()).andReturn(TEST_REQUEST_URI).times(1, 2);
+ EasyMock.replay(req);
+
+ FedizProcessor wfProc = new SAMLProcessorImpl();
+ RedirectionResponse response = wfProc.createSignInRequest(req, config);
+
+ String redirectionURL = response.getRedirectionURL();
+ String signature =
+ redirectionURL.substring(redirectionURL.indexOf("Signature=") + "Signature=".length());
+ Assert.assertTrue(signature != null && signature.length() > 0);
+ }
+
+}
\ No newline at end of file
[4/4] git commit: Adding unit tests for SAML SSO
Posted by co...@apache.org.
Adding 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/617fd4e9
Tree: http://git-wip-us.apache.org/repos/asf/cxf-fediz/tree/617fd4e9
Diff: http://git-wip-us.apache.org/repos/asf/cxf-fediz/diff/617fd4e9
Branch: refs/heads/master
Commit: 617fd4e95f61194a76eb734b1132f82b27d06102
Parents: 909e640
Author: Colm O hEigeartaigh <co...@apache.org>
Authored: Wed Jul 23 17:23:43 2014 +0100
Committer: Colm O hEigeartaigh <co...@apache.org>
Committed: Wed Jul 23 17:23:43 2014 +0100
----------------------------------------------------------------------
plugins/core/pom.xml | 6 +
.../fediz/core/AbstractSAMLCallbackHandler.java | 19 +-
.../apache/cxf/fediz/core/CustomValidator.java | 51 -
.../cxf/fediz/core/FederationMetaDataTest.java | 117 --
.../cxf/fediz/core/FederationProcessorTest.java | 1340 -----------------
.../fediz/core/SAMLTokenValidatorOldTest.java | 392 -----
.../fediz/core/federation/CustomValidator.java | 54 +
.../core/federation/FederationMetaDataTest.java | 117 ++
.../federation/FederationProcessorTest.java | 1350 +++++++++++++++++
.../federation/SAMLTokenValidatorOldTest.java | 399 +++++
.../samlsso/SAML2PResponseComponentBuilder.java | 126 ++
.../cxf/fediz/core/samlsso/SAMLRequestTest.java | 205 +++
.../fediz/core/samlsso/SAMLResponseTest.java | 1378 ++++++++++++++++++
.../fediz/core/samlsso/SAMLSSOTestUtils.java | 41 +
.../src/test/resources/fediz_test_config.xml | 2 +-
.../test/resources/fediz_test_config_saml.xml | 196 +++
pom.xml | 1 +
17 files changed, 3889 insertions(+), 1905 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/cxf-fediz/blob/617fd4e9/plugins/core/pom.xml
----------------------------------------------------------------------
diff --git a/plugins/core/pom.xml b/plugins/core/pom.xml
index 0c85b21..fc53ba5 100644
--- a/plugins/core/pom.xml
+++ b/plugins/core/pom.xml
@@ -67,6 +67,12 @@
<version>${servlet.version}</version>
<scope>provided</scope>
</dependency>
+ <dependency>
+ <groupId>org.easymock</groupId>
+ <artifactId>easymock</artifactId>
+ <version>${easymock.version}</version>
+ <scope>test</scope>
+ </dependency>
</dependencies>
<build>
<plugins>
http://git-wip-us.apache.org/repos/asf/cxf-fediz/blob/617fd4e9/plugins/core/src/test/java/org/apache/cxf/fediz/core/AbstractSAMLCallbackHandler.java
----------------------------------------------------------------------
diff --git a/plugins/core/src/test/java/org/apache/cxf/fediz/core/AbstractSAMLCallbackHandler.java b/plugins/core/src/test/java/org/apache/cxf/fediz/core/AbstractSAMLCallbackHandler.java
index 3ff69f0..78629b0 100644
--- a/plugins/core/src/test/java/org/apache/cxf/fediz/core/AbstractSAMLCallbackHandler.java
+++ b/plugins/core/src/test/java/org/apache/cxf/fediz/core/AbstractSAMLCallbackHandler.java
@@ -73,6 +73,7 @@ public abstract class AbstractSAMLCallbackHandler implements CallbackHandler {
protected String confirmationMethod;
protected X509Certificate[] certs;
protected Statement statement = Statement.AUTHN;
+ protected boolean alsoAddAuthnStatement;
protected CERT_IDENTIFIER certIdentifier = CERT_IDENTIFIER.X509_CERT;
protected byte[] ephemeralKey;
protected String issuer;
@@ -203,7 +204,7 @@ public abstract class AbstractSAMLCallbackHandler implements CallbackHandler {
*/
//CHECKSTYLE:OFF
protected void createAndSetStatement(SubjectBean subjectBean, SAMLCallback callback) {
- if (statement == Statement.AUTHN) {
+ if (alsoAddAuthnStatement || statement == Statement.AUTHN) {
AuthenticationStatementBean authBean = new AuthenticationStatementBean();
if (subjectBean != null) {
authBean.setSubject(subjectBean);
@@ -216,7 +217,9 @@ public abstract class AbstractSAMLCallbackHandler implements CallbackHandler {
}
authBean.setAuthenticationMethod("Password");
callback.setAuthenticationStatementData(Collections.singletonList(authBean));
- } else if (statement == Statement.ATTR) {
+ }
+
+ if (statement == Statement.ATTR) {
AttributeStatementBean attrStateBean = new AttributeStatementBean();
if (subjectBean != null) {
attrStateBean.setSubject(subjectBean);
@@ -357,7 +360,7 @@ public abstract class AbstractSAMLCallbackHandler implements CallbackHandler {
attrStateBean.setSamlAttributes(attributeList);
callback.setAttributeStatementData(Collections.singletonList(attrStateBean));
- } else {
+ } else if (statement == Statement.AUTHZ) {
AuthDecisionStatementBean authzBean = new AuthDecisionStatementBean();
if (subjectBean != null) {
authzBean.setSubject(subjectBean);
@@ -374,7 +377,7 @@ public abstract class AbstractSAMLCallbackHandler implements CallbackHandler {
protected KeyInfoBean createKeyInfo() throws Exception {
KeyInfoBean keyInfo = new KeyInfoBean();
- if (statement == Statement.AUTHN) {
+ if (alsoAddAuthnStatement || statement == Statement.AUTHN) {
keyInfo.setCertificate(certs[0]);
keyInfo.setCertIdentifer(certIdentifier);
} else if (statement == Statement.ATTR) {
@@ -417,4 +420,12 @@ public abstract class AbstractSAMLCallbackHandler implements CallbackHandler {
int i = claimType.lastIndexOf("/");
return claimType.substring(i + 1);
}
+
+ public boolean isAlsoAddAuthnStatement() {
+ return alsoAddAuthnStatement;
+ }
+
+ public void setAlsoAddAuthnStatement(boolean alsoAddAuthnStatement) {
+ this.alsoAddAuthnStatement = alsoAddAuthnStatement;
+ }
}
http://git-wip-us.apache.org/repos/asf/cxf-fediz/blob/617fd4e9/plugins/core/src/test/java/org/apache/cxf/fediz/core/CustomValidator.java
----------------------------------------------------------------------
diff --git a/plugins/core/src/test/java/org/apache/cxf/fediz/core/CustomValidator.java b/plugins/core/src/test/java/org/apache/cxf/fediz/core/CustomValidator.java
deleted file mode 100644
index f67edae..0000000
--- a/plugins/core/src/test/java/org/apache/cxf/fediz/core/CustomValidator.java
+++ /dev/null
@@ -1,51 +0,0 @@
-/**
- * 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;
-
-import org.w3c.dom.Element;
-import org.apache.cxf.fediz.core.config.FedizContext;
-
-
-public class CustomValidator implements TokenValidator {
-
- @Override
- public boolean canHandleTokenType(String tokenType) {
- return true;
- }
-
- @Override
- public boolean canHandleToken(Element token) {
- return true;
- }
-
- @Override
- public TokenValidatorResponse validateAndProcessToken(
- TokenValidatorRequest request,
- FedizContext config
- ) {
- return new TokenValidatorResponse(null,
- FederationProcessorTest.TEST_USER,
- FederationProcessorTest.TEST_RSTR_ISSUER,
- null,
- null,
- FederationProcessorTest.TEST_AUDIENCE);
- }
-
-}
http://git-wip-us.apache.org/repos/asf/cxf-fediz/blob/617fd4e9/plugins/core/src/test/java/org/apache/cxf/fediz/core/FederationMetaDataTest.java
----------------------------------------------------------------------
diff --git a/plugins/core/src/test/java/org/apache/cxf/fediz/core/FederationMetaDataTest.java b/plugins/core/src/test/java/org/apache/cxf/fediz/core/FederationMetaDataTest.java
deleted file mode 100644
index 150eb08..0000000
--- a/plugins/core/src/test/java/org/apache/cxf/fediz/core/FederationMetaDataTest.java
+++ /dev/null
@@ -1,117 +0,0 @@
-/**
- * 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;
-
-import java.io.File;
-import java.net.URL;
-
-import javax.xml.transform.TransformerException;
-
-import org.w3c.dom.Document;
-import org.apache.cxf.fediz.common.SecurityTestUtil;
-import org.apache.cxf.fediz.core.config.FedizConfigurator;
-import org.apache.cxf.fediz.core.config.FedizContext;
-import org.apache.cxf.fediz.core.exception.ProcessingException;
-import org.apache.cxf.fediz.core.processor.FederationProcessorImpl;
-import org.apache.cxf.fediz.core.processor.FedizProcessor;
-import org.apache.cxf.fediz.core.util.DOMUtils;
-import org.junit.AfterClass;
-import org.junit.Assert;
-
-import static org.junit.Assert.fail;
-
-public class FederationMetaDataTest {
- private static final String CONFIG_FILE = "fediz_meta_test_config.xml";
-
- @AfterClass
- public static void cleanup() {
- SecurityTestUtil.cleanup();
- }
-
-
- private FedizContext loadConfig(String context) {
- try {
- FedizConfigurator configurator = new FedizConfigurator();
- final URL resource = Thread.currentThread().getContextClassLoader()
- .getResource(CONFIG_FILE);
- File f = new File(resource.toURI());
- configurator.loadConfig(f);
- return configurator.getFedizContext(context);
- } catch (Exception e) {
- e.printStackTrace();
- return null;
- }
- }
-
-
- @org.junit.Test
- public void validateMetaDataWithAlias() throws ProcessingException {
-
- FedizContext config = loadConfig("ROOT");
-
- FedizProcessor wfProc = new FederationProcessorImpl();
- Document doc = wfProc.getMetaData(config);
- Assert.assertNotNull(doc);
-
- try {
- DOMUtils.writeXml(doc, System.out);
- } catch (TransformerException e) {
- fail("Exception not expected: " + e.getMessage());
- }
-
- }
-
- @org.junit.Test
- public void validateMetaDataNoAlias() throws ProcessingException {
-
- try {
- FedizContext config = loadConfig("ROOT_NO_KEY");
-
- FedizProcessor wfProc = new FederationProcessorImpl();
- Document doc;
-
- doc = wfProc.getMetaData(config);
- Assert.assertNull(doc);
- } catch (ProcessingException ex) {
- //Expected as signing store contains more than one certificate
- }
-
-
- }
-
- @org.junit.Test
- public void validateMetaDataNoSigningKey() throws ProcessingException {
-
- FedizContext config = loadConfig("ROOT_NO_SIGNINGKEY");
-
- FedizProcessor wfProc = new FederationProcessorImpl();
- Document doc = wfProc.getMetaData(config);
- Assert.assertNotNull(doc);
-
- try {
- DOMUtils.writeXml(doc, System.out);
- } catch (TransformerException e) {
- fail("Exception not expected: " + e.getMessage());
- }
-
- }
-
-
-}
http://git-wip-us.apache.org/repos/asf/cxf-fediz/blob/617fd4e9/plugins/core/src/test/java/org/apache/cxf/fediz/core/FederationProcessorTest.java
----------------------------------------------------------------------
diff --git a/plugins/core/src/test/java/org/apache/cxf/fediz/core/FederationProcessorTest.java b/plugins/core/src/test/java/org/apache/cxf/fediz/core/FederationProcessorTest.java
deleted file mode 100644
index cc533a9..0000000
--- a/plugins/core/src/test/java/org/apache/cxf/fediz/core/FederationProcessorTest.java
+++ /dev/null
@@ -1,1340 +0,0 @@
-/**
- * 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;
-
-import java.io.File;
-import java.io.IOException;
-import java.math.BigInteger;
-import java.net.URL;
-import java.security.cert.X509Certificate;
-import java.util.Collections;
-import java.util.List;
-
-import javax.security.auth.callback.CallbackHandler;
-import javax.security.auth.callback.UnsupportedCallbackException;
-
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-import org.w3c.dom.Node;
-import org.apache.cxf.fediz.common.STSUtil;
-import org.apache.cxf.fediz.common.SecurityTestUtil;
-import org.apache.cxf.fediz.core.AbstractSAMLCallbackHandler.MultiValue;
-import org.apache.cxf.fediz.core.config.FederationProtocol;
-import org.apache.cxf.fediz.core.config.FedizConfigurator;
-import org.apache.cxf.fediz.core.config.FedizContext;
-import org.apache.cxf.fediz.core.config.jaxb.AudienceUris;
-import org.apache.cxf.fediz.core.config.jaxb.CertificateStores;
-import org.apache.cxf.fediz.core.config.jaxb.ContextConfig;
-import org.apache.cxf.fediz.core.config.jaxb.FederationProtocolType;
-import org.apache.cxf.fediz.core.config.jaxb.KeyStoreType;
-import org.apache.cxf.fediz.core.config.jaxb.TrustManagersType;
-import org.apache.cxf.fediz.core.config.jaxb.TrustedIssuerType;
-import org.apache.cxf.fediz.core.config.jaxb.TrustedIssuers;
-import org.apache.cxf.fediz.core.config.jaxb.ValidationType;
-import org.apache.cxf.fediz.core.exception.ProcessingException;
-import org.apache.cxf.fediz.core.exception.ProcessingException.TYPE;
-import org.apache.cxf.fediz.core.processor.FederationProcessorImpl;
-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.wss4j.common.WSEncryptionPart;
-import org.apache.wss4j.common.crypto.Crypto;
-import org.apache.wss4j.common.crypto.CryptoFactory;
-import org.apache.wss4j.common.crypto.CryptoType;
-import org.apache.wss4j.common.ext.WSPasswordCallback;
-import org.apache.wss4j.common.ext.WSSecurityException;
-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.builder.SAML1Constants;
-import org.apache.wss4j.common.saml.builder.SAML2Constants;
-import org.apache.wss4j.common.util.DOM2Writer;
-import org.apache.wss4j.dom.WSConstants;
-import org.apache.wss4j.dom.message.WSSecEncrypt;
-import org.joda.time.DateTime;
-import org.junit.AfterClass;
-import org.junit.Assert;
-import org.junit.BeforeClass;
-
-import static org.junit.Assert.fail;
-
-public class FederationProcessorTest {
- static final String TEST_USER = "alice";
- static final String TEST_RSTR_ISSUER = "FedizSTSIssuer";
- static final String TEST_AUDIENCE = "https://localhost/fedizhelloworld";
-
- private static final String CONFIG_FILE = "fediz_test_config.xml";
-
- private static Crypto crypto;
- private static CallbackHandler cbPasswordHandler;
- private static FedizConfigurator configurator;
-
-
- @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;
- }
- }
-
-
- /**
- * Validate RSTR without RequestedSecurityToken element
- */
- @org.junit.Test
- public void validateRSTRWithoutToken() throws Exception {
- Document doc = STSUtil.toSOAPPart(STSUtil.SAMPLE_RSTR_COLL_MSG);
-
- FedizRequest wfReq = new FedizRequest();
- wfReq.setAction(FederationConstants.ACTION_SIGNIN);
- wfReq.setResponseToken(DOM2Writer.nodeToString(doc));
-
- configurator = null;
- FedizContext config = getFederationConfigurator().getFedizContext("ROOT");
-
- FedizProcessor wfProc = new FederationProcessorImpl();
- try {
- wfProc.processRequest(wfReq, config);
- fail("Failure expected on missing security token in RSTR");
- } catch (ProcessingException ex) {
- if (!TYPE.BAD_REQUEST.equals(ex.getType())) {
- fail("Expected ProcessingException with BAD_REQUEST type");
- }
- }
- }
-
- /**
- * Validate FederationRequest with unknown action
- */
- @org.junit.Test
- public void validateRequestUnknownAction() throws Exception {
- Document doc = STSUtil.toSOAPPart(STSUtil.SAMPLE_RSTR_COLL_MSG);
-
- FedizRequest wfReq = new FedizRequest();
- wfReq.setAction("gugus");
- wfReq.setResponseToken(DOM2Writer.nodeToString(doc));
-
- configurator = null;
- FedizContext config = getFederationConfigurator().getFedizContext("ROOT");
-
- FedizProcessor wfProc = new FederationProcessorImpl();
- try {
- wfProc.processRequest(wfReq, config);
- fail("Failure expected due to invalid action");
- } catch (ProcessingException ex) {
- if (!TYPE.INVALID_REQUEST.equals(ex.getType())) {
- fail("Expected ProcessingException with INVALID_REQUEST type");
- }
- }
- }
-
- /**
- *Validate FederationRequest with invalid RSTR/wresult
- */
- @org.junit.Test
- public void validateSignInInvalidWResult() throws Exception {
- FedizRequest wfReq = new FedizRequest();
- wfReq.setAction(FederationConstants.ACTION_SIGNIN);
- wfReq.setResponseToken("gugus");
-
- configurator = null;
- FedizContext config = getFederationConfigurator().getFedizContext("ROOT");
-
- FedizProcessor wfProc = new FederationProcessorImpl();
- try {
- wfProc.processRequest(wfReq, config);
- fail("Failure expected due to invalid wresult");
- } catch (ProcessingException ex) {
- if (!TYPE.INVALID_REQUEST.equals(ex.getType())) {
- fail("Expected ProcessingException with INVALID_REQUEST type");
- }
- }
- }
-
- @org.junit.Test
- public void validateTokenAndCreateMetadata() throws Exception {
- validateSAML2Token();
- FederationMetaDataTest other = new FederationMetaDataTest();
- other.validateMetaDataWithAlias();
- }
-
- /**
- * Validate SAML 2 token which includes the role attribute with 2 values
- * Roles are encoded as a multi-value saml attribute
- */
- @org.junit.Test
- public void validateSAML2Token() throws Exception {
- SAML2CallbackHandler callbackHandler = new SAML2CallbackHandler();
- callbackHandler.setStatement(SAML2CallbackHandler.Statement.ATTR);
- callbackHandler.setConfirmationMethod(SAML2Constants.CONF_BEARER);
- callbackHandler.setIssuer(TEST_RSTR_ISSUER);
- callbackHandler.setSubjectName(TEST_USER);
- ConditionsBean cp = new ConditionsBean();
- AudienceRestrictionBean audienceRestriction = new AudienceRestrictionBean();
- audienceRestriction.getAudienceURIs().add(TEST_AUDIENCE);
- cp.setAudienceRestrictions(Collections.singletonList(audienceRestriction));
- callbackHandler.setConditions(cp);
-
- SAMLCallback samlCallback = new SAMLCallback();
- SAMLUtil.doSAMLCallback(callbackHandler, samlCallback);
- SamlAssertionWrapper assertion = new SamlAssertionWrapper(samlCallback);
- String rstr = createSamlToken(assertion, "mystskey", true);
-
- FedizRequest wfReq = new FedizRequest();
- wfReq.setAction(FederationConstants.ACTION_SIGNIN);
- wfReq.setResponseToken(rstr);
-
- configurator = null;
- FedizContext config = getFederationConfigurator().getFedizContext("ROOT");
-
- FedizProcessor wfProc = new FederationProcessorImpl();
- FedizResponse wfRes = wfProc.processRequest(wfReq, config);
-
- Assert.assertEquals("Principal name wrong", TEST_USER,
- wfRes.getUsername());
- Assert.assertEquals("Issuer wrong", TEST_RSTR_ISSUER, wfRes.getIssuer());
- Assert.assertEquals("Two roles must be found", 2, wfRes.getRoles()
- .size());
- Assert.assertEquals("Audience wrong", TEST_AUDIENCE, wfRes.getAudience());
- assertClaims(wfRes.getClaims(), callbackHandler.getRoleAttributeName());
-
- }
-
- /**
- * Validate SAML 2 token which includes the role attribute with 2 values
- * Roles are encoded as a multi-value saml attribute
- * Not RequestedSecurityTokenCollection in this test, default in all others
- */
- @org.junit.Test
- public void validateSAML2TokenRSTR() throws Exception {
- SAML2CallbackHandler callbackHandler = new SAML2CallbackHandler();
- callbackHandler.setStatement(SAML2CallbackHandler.Statement.ATTR);
- callbackHandler.setConfirmationMethod(SAML2Constants.CONF_BEARER);
- callbackHandler.setIssuer(TEST_RSTR_ISSUER);
- callbackHandler.setSubjectName(TEST_USER);
- ConditionsBean cp = new ConditionsBean();
- AudienceRestrictionBean audienceRestriction = new AudienceRestrictionBean();
- audienceRestriction.getAudienceURIs().add(TEST_AUDIENCE);
- cp.setAudienceRestrictions(Collections.singletonList(audienceRestriction));
- callbackHandler.setConditions(cp);
-
- SAMLCallback samlCallback = new SAMLCallback();
- SAMLUtil.doSAMLCallback(callbackHandler, samlCallback);
- SamlAssertionWrapper assertion = new SamlAssertionWrapper(samlCallback);
- String rstr = createSamlToken(assertion, "mystskey", true, STSUtil.SAMPLE_RSTR_MSG);
-
- FedizRequest wfReq = new FedizRequest();
- wfReq.setAction(FederationConstants.ACTION_SIGNIN);
- wfReq.setResponseToken(rstr);
-
- configurator = null;
- FedizContext config = getFederationConfigurator().getFedizContext("ROOT");
-
- FedizProcessor wfProc = new FederationProcessorImpl();
- FedizResponse wfRes = wfProc.processRequest(wfReq, config);
-
- Assert.assertEquals("Principal name wrong", TEST_USER,
- wfRes.getUsername());
- Assert.assertEquals("Issuer wrong", TEST_RSTR_ISSUER, wfRes.getIssuer());
- Assert.assertEquals("Two roles must be found", 2, wfRes.getRoles()
- .size());
- Assert.assertEquals("Audience wrong", TEST_AUDIENCE, wfRes.getAudience());
- }
-
- /**
- * Validate SAML 2 token which doesn't include the role SAML attribute
- */
- @org.junit.Test
- public void validateSAML2TokenWithoutRoles() throws Exception {
- SAML2CallbackHandler callbackHandler = new SAML2CallbackHandler();
- callbackHandler.setStatement(SAML2CallbackHandler.Statement.ATTR);
- callbackHandler.setConfirmationMethod(SAML2Constants.CONF_BEARER);
- callbackHandler.setIssuer(TEST_RSTR_ISSUER);
- callbackHandler.setSubjectName(TEST_USER);
- callbackHandler.setRoles(null);
- ConditionsBean cp = new ConditionsBean();
- AudienceRestrictionBean audienceRestriction = new AudienceRestrictionBean();
- audienceRestriction.getAudienceURIs().add(TEST_AUDIENCE);
- cp.setAudienceRestrictions(Collections.singletonList(audienceRestriction));
- callbackHandler.setConditions(cp);
-
- SAMLCallback samlCallback = new SAMLCallback();
- SAMLUtil.doSAMLCallback(callbackHandler, samlCallback);
- SamlAssertionWrapper assertion = new SamlAssertionWrapper(samlCallback);
- String rstr = createSamlToken(assertion, "mystskey", true);
-
- FedizRequest wfReq = new FedizRequest();
- wfReq.setAction(FederationConstants.ACTION_SIGNIN);
- wfReq.setResponseToken(rstr);
-
- configurator = null;
- FedizContext config = getFederationConfigurator().getFedizContext("ROOT");
-
- FedizProcessor wfProc = new FederationProcessorImpl();
- FedizResponse wfRes = wfProc.processRequest(wfReq, config);
-
- Assert.assertEquals("Principal name wrong", TEST_USER,
- wfRes.getUsername());
- Assert.assertEquals("Issuer wrong", TEST_RSTR_ISSUER, wfRes.getIssuer());
- Assert.assertEquals("No roles must be found", null, wfRes.getRoles());
- Assert.assertEquals("Audience wrong", TEST_AUDIENCE, wfRes.getAudience());
- }
-
- /**
- * Validate SAML 2 token where role information is provided
- * within another SAML attribute
- */
- @org.junit.Test
- public void validateSAML2TokenDifferentRoleURI() throws Exception {
- SAML2CallbackHandler callbackHandler = new SAML2CallbackHandler();
- callbackHandler.setStatement(SAML2CallbackHandler.Statement.ATTR);
- callbackHandler.setConfirmationMethod(SAML2Constants.CONF_BEARER);
- callbackHandler.setIssuer(TEST_RSTR_ISSUER);
- callbackHandler.setSubjectName(TEST_USER);
- callbackHandler.setRoleAttributeName("http://schemas.mycompany.com/claims/role");
- ConditionsBean cp = new ConditionsBean();
- AudienceRestrictionBean audienceRestriction = new AudienceRestrictionBean();
- audienceRestriction.getAudienceURIs().add(TEST_AUDIENCE);
- cp.setAudienceRestrictions(Collections.singletonList(audienceRestriction));
- callbackHandler.setConditions(cp);
-
- SAMLCallback samlCallback = new SAMLCallback();
- SAMLUtil.doSAMLCallback(callbackHandler, samlCallback);
- SamlAssertionWrapper assertion = new SamlAssertionWrapper(samlCallback);
- String rstr = createSamlToken(assertion, "mystskey", true);
-
- FedizRequest wfReq = new FedizRequest();
- wfReq.setAction(FederationConstants.ACTION_SIGNIN);
- wfReq.setResponseToken(rstr);
-
- configurator = null;
- FedizContext config = getFederationConfigurator().getFedizContext("CUSTOMROLEURI");
-
- FedizProcessor wfProc = new FederationProcessorImpl();
- FedizResponse wfRes = wfProc.processRequest(wfReq, config);
-
- Assert.assertEquals("Principal name wrong", TEST_USER, wfRes.getUsername());
- Assert.assertEquals("Issuer wrong", TEST_RSTR_ISSUER, wfRes.getIssuer());
- Assert.assertEquals("Two roles must be found", 2, wfRes.getRoles().size());
- Assert.assertEquals("Audience wrong", TEST_AUDIENCE, wfRes.getAudience());
- assertClaims(wfRes.getClaims(), callbackHandler.getRoleAttributeName());
- }
-
- /**
- * Validate SAML 2 token where role information is provided
- * within another SAML attribute
- */
- @org.junit.Test
- public void validateSAML1TokenDifferentRoleURI() throws Exception {
- SAML1CallbackHandler callbackHandler = new SAML1CallbackHandler();
- callbackHandler.setStatement(SAML1CallbackHandler.Statement.ATTR);
- callbackHandler.setConfirmationMethod(SAML2Constants.CONF_BEARER);
- callbackHandler.setIssuer(TEST_RSTR_ISSUER);
- callbackHandler.setSubjectName(TEST_USER);
- callbackHandler.setRoleAttributeName("http://schemas.mycompany.com/claims/role");
- ConditionsBean cp = new ConditionsBean();
- AudienceRestrictionBean audienceRestriction = new AudienceRestrictionBean();
- audienceRestriction.getAudienceURIs().add(TEST_AUDIENCE);
- cp.setAudienceRestrictions(Collections.singletonList(audienceRestriction));
- callbackHandler.setConditions(cp);
-
- SAMLCallback samlCallback = new SAMLCallback();
- SAMLUtil.doSAMLCallback(callbackHandler, samlCallback);
- SamlAssertionWrapper assertion = new SamlAssertionWrapper(samlCallback);
- String rstr = createSamlToken(assertion, "mystskey", true);
-
- FedizRequest wfReq = new FedizRequest();
- wfReq.setAction(FederationConstants.ACTION_SIGNIN);
- wfReq.setResponseToken(rstr);
-
- configurator = null;
- FedizContext config = getFederationConfigurator().getFedizContext("CUSTOMROLEURI");
-
- FedizProcessor wfProc = new FederationProcessorImpl();
- FedizResponse wfRes = wfProc.processRequest(wfReq, config);
-
- Assert.assertEquals("Principal name wrong", TEST_USER, wfRes.getUsername());
- Assert.assertEquals("Issuer wrong", TEST_RSTR_ISSUER, wfRes.getIssuer());
- Assert.assertEquals("Two roles must be found", 2, wfRes.getRoles().size());
- Assert.assertEquals("Audience wrong", TEST_AUDIENCE, wfRes.getAudience());
- assertClaims(wfRes.getClaims(), callbackHandler.getRoleAttributeName());
- }
-
- /**
- * Validate SAML 2 token which includes role attribute
- * but RoleURI is not configured
- */
- @org.junit.Test
- public void validateSAML2TokenRoleURINotConfigured() throws Exception {
- SAML2CallbackHandler callbackHandler = new SAML2CallbackHandler();
- callbackHandler.setStatement(SAML2CallbackHandler.Statement.ATTR);
- callbackHandler.setConfirmationMethod(SAML2Constants.CONF_BEARER);
- callbackHandler.setIssuer(TEST_RSTR_ISSUER);
- callbackHandler.setSubjectName(TEST_USER);
- ConditionsBean cp = new ConditionsBean();
- AudienceRestrictionBean audienceRestriction = new AudienceRestrictionBean();
- audienceRestriction.getAudienceURIs().add(TEST_AUDIENCE);
- cp.setAudienceRestrictions(Collections.singletonList(audienceRestriction));
- callbackHandler.setConditions(cp);
-
- SAMLCallback samlCallback = new SAMLCallback();
- SAMLUtil.doSAMLCallback(callbackHandler, samlCallback);
- SamlAssertionWrapper assertion = new SamlAssertionWrapper(samlCallback);
- String rstr = createSamlToken(assertion, "mystskey", true);
-
- FedizRequest wfReq = new FedizRequest();
- wfReq.setAction(FederationConstants.ACTION_SIGNIN);
- wfReq.setResponseToken(rstr);
-
- configurator = null;
- FedizContext config = getFederationConfigurator().getFedizContext("ROOT");
- ((FederationProtocol)config.getProtocol()).setRoleURI(null);
-
- FedizProcessor wfProc = new FederationProcessorImpl();
- FedizResponse wfRes = wfProc.processRequest(wfReq, config);
-
- Assert.assertEquals("Principal name wrong", TEST_USER,
- wfRes.getUsername());
- Assert.assertEquals("Issuer wrong", TEST_RSTR_ISSUER, wfRes.getIssuer());
- Assert.assertEquals("Two roles must be found", null, wfRes.getRoles());
- Assert.assertEquals("Audience wrong", TEST_AUDIENCE, wfRes.getAudience());
- }
-
- /**
- * Validate SAML 1.1 token which includes the role attribute with 2 values
- * Roles are encoded as a multi-value saml attribute
- */
- @org.junit.Test
- public void validateSAML1Token() throws Exception {
- SAML1CallbackHandler callbackHandler = new SAML1CallbackHandler();
- callbackHandler.setStatement(SAML1CallbackHandler.Statement.ATTR);
- callbackHandler.setConfirmationMethod(SAML1Constants.CONF_BEARER);
- callbackHandler.setIssuer(TEST_RSTR_ISSUER);
- callbackHandler.setSubjectName(TEST_USER);
- ConditionsBean cp = new ConditionsBean();
- AudienceRestrictionBean audienceRestriction = new AudienceRestrictionBean();
- audienceRestriction.getAudienceURIs().add(TEST_AUDIENCE);
- cp.setAudienceRestrictions(Collections.singletonList(audienceRestriction));
- callbackHandler.setConditions(cp);
-
- SAMLCallback samlCallback = new SAMLCallback();
- SAMLUtil.doSAMLCallback(callbackHandler, samlCallback);
- SamlAssertionWrapper assertion = new SamlAssertionWrapper(samlCallback);
- String rstr = createSamlToken(assertion, "mystskey", true);
-
- FedizRequest wfReq = new FedizRequest();
- wfReq.setAction(FederationConstants.ACTION_SIGNIN);
- wfReq.setResponseToken(rstr);
-
- configurator = null;
- FedizContext config = getFederationConfigurator().getFedizContext("ROOT");
-
- FedizProcessor wfProc = new FederationProcessorImpl();
- FedizResponse wfRes = wfProc.processRequest(wfReq, config);
-
- Assert.assertEquals("Principal name wrong", TEST_USER,
- wfRes.getUsername());
- Assert.assertEquals("Issuer wrong", TEST_RSTR_ISSUER, wfRes.getIssuer());
- Assert.assertEquals("Two roles must be found", 2, wfRes.getRoles()
- .size());
- Assert.assertEquals("Audience wrong", TEST_AUDIENCE, wfRes.getAudience());
- assertClaims(wfRes.getClaims(), callbackHandler.getRoleAttributeName());
- }
-
- /**
- * Validate SAML 1.1 token which includes the role attribute with 2 values
- * Roles are encoded as a multi-value saml attribute
- * Token embedded in RSTR 2005/02 - WS Federation 1.0
- */
- @org.junit.Test
- public void validateSAML1TokenWSFed10() throws Exception {
- SAML1CallbackHandler callbackHandler = new SAML1CallbackHandler();
- callbackHandler.setStatement(SAML1CallbackHandler.Statement.ATTR);
- callbackHandler.setConfirmationMethod(SAML1Constants.CONF_BEARER);
- callbackHandler.setIssuer(TEST_RSTR_ISSUER);
- callbackHandler.setSubjectName(TEST_USER);
- ConditionsBean cp = new ConditionsBean();
- AudienceRestrictionBean audienceRestriction = new AudienceRestrictionBean();
- audienceRestriction.getAudienceURIs().add(TEST_AUDIENCE);
- cp.setAudienceRestrictions(Collections.singletonList(audienceRestriction));
- callbackHandler.setConditions(cp);
-
- SAMLCallback samlCallback = new SAMLCallback();
- SAMLUtil.doSAMLCallback(callbackHandler, samlCallback);
- SamlAssertionWrapper assertion = new SamlAssertionWrapper(samlCallback);
- String rstr = createSamlToken(assertion, "mystskey", true, STSUtil.SAMPLE_RSTR_2005_02_MSG);
- FedizRequest wfReq = new FedizRequest();
- wfReq.setAction(FederationConstants.ACTION_SIGNIN);
- wfReq.setResponseToken(rstr);
-
- configurator = null;
- FedizContext config = getFederationConfigurator().getFedizContext("ROOT");
-
- FedizProcessor wfProc = new FederationProcessorImpl();
- FedizResponse wfRes = wfProc.processRequest(wfReq, config);
-
- Assert.assertEquals("Principal name wrong", TEST_USER,
- wfRes.getUsername());
- Assert.assertEquals("Issuer wrong", TEST_RSTR_ISSUER, wfRes.getIssuer());
- Assert.assertEquals("Two roles must be found", 2, wfRes.getRoles()
- .size());
- Assert.assertEquals("Audience wrong", TEST_AUDIENCE, wfRes.getAudience());
- }
-
- /**
- * Validate SAML 2 token which includes the role attribute with 2 values
- * Roles are encoded as a multiple saml attributes with the same name
- */
- @org.junit.Test
- public void validateSAML2TokenRoleMultiAttributes() throws Exception {
- SAML2CallbackHandler callbackHandler = new SAML2CallbackHandler();
- callbackHandler.setStatement(SAML2CallbackHandler.Statement.ATTR);
- callbackHandler.setConfirmationMethod(SAML2Constants.CONF_BEARER);
- callbackHandler.setIssuer(TEST_RSTR_ISSUER);
- callbackHandler.setSubjectName(TEST_USER);
- callbackHandler.setMultiValueType(MultiValue.MULTI_ATTR);
- ConditionsBean cp = new ConditionsBean();
- AudienceRestrictionBean audienceRestriction = new AudienceRestrictionBean();
- audienceRestriction.getAudienceURIs().add(TEST_AUDIENCE);
- cp.setAudienceRestrictions(Collections.singletonList(audienceRestriction));
- callbackHandler.setConditions(cp);
-
- SAMLCallback samlCallback = new SAMLCallback();
- SAMLUtil.doSAMLCallback(callbackHandler, samlCallback);
- SamlAssertionWrapper assertion = new SamlAssertionWrapper(samlCallback);
- String rstr = createSamlToken(assertion, "mystskey", true);
-
- FedizRequest wfReq = new FedizRequest();
- wfReq.setAction(FederationConstants.ACTION_SIGNIN);
- wfReq.setResponseToken(rstr);
-
- configurator = null;
- FedizContext config = getFederationConfigurator().getFedizContext("ROOT");
-
- FedizProcessor wfProc = new FederationProcessorImpl();
- FedizResponse wfRes = wfProc.processRequest(wfReq, config);
-
- Assert.assertEquals("Principal name wrong", TEST_USER,
- wfRes.getUsername());
- Assert.assertEquals("Issuer wrong", TEST_RSTR_ISSUER, wfRes.getIssuer());
- Assert.assertEquals("Two roles must be found", 2, wfRes.getRoles()
- .size());
- assertClaims(wfRes.getClaims(), callbackHandler.getRoleAttributeName());
- }
-
- /**
- * Validate SAML 2 token which includes the role attribute with 2 values
- * Roles are encoded as a single saml attribute with encoded value
- */
- @org.junit.Test
- public void validateSAML2TokenRoleEncodedValue() throws Exception {
- SAML2CallbackHandler callbackHandler = new SAML2CallbackHandler();
- callbackHandler.setStatement(SAML2CallbackHandler.Statement.ATTR);
- callbackHandler.setConfirmationMethod(SAML2Constants.CONF_BEARER);
- callbackHandler.setIssuer(TEST_RSTR_ISSUER);
- callbackHandler.setSubjectName(TEST_USER);
- callbackHandler.setMultiValueType(MultiValue.ENC_VALUE);
- ConditionsBean cp = new ConditionsBean();
- AudienceRestrictionBean audienceRestriction = new AudienceRestrictionBean();
- audienceRestriction.getAudienceURIs().add(TEST_AUDIENCE);
- cp.setAudienceRestrictions(Collections.singletonList(audienceRestriction));
- callbackHandler.setConditions(cp);
-
- SAMLCallback samlCallback = new SAMLCallback();
- SAMLUtil.doSAMLCallback(callbackHandler, samlCallback);
- SamlAssertionWrapper assertion = new SamlAssertionWrapper(samlCallback);
- String rstr = createSamlToken(assertion, "mystskey", true);
-
- FedizRequest wfReq = new FedizRequest();
- wfReq.setAction(FederationConstants.ACTION_SIGNIN);
- wfReq.setResponseToken(rstr);
-
- configurator = null;
- FedizContext config = getFederationConfigurator().getFedizContext("ROOT");
- FederationProtocol fp = (FederationProtocol)config.getProtocol();
- fp.setRoleDelimiter(",");
-
- FedizProcessor wfProc = new FederationProcessorImpl();
- FedizResponse wfRes = wfProc.processRequest(wfReq, config);
-
- Assert.assertEquals("Principal name wrong", TEST_USER,
- wfRes.getUsername());
- Assert.assertEquals("Issuer wrong", TEST_RSTR_ISSUER, wfRes.getIssuer());
- Assert.assertEquals("Two roles must be found", 2, wfRes.getRoles()
- .size());
- assertClaims(wfRes.getClaims(), callbackHandler.getRoleAttributeName());
- }
-
- /**
- * Validate SAML 2 token which includes the role attribute with 2 values
- * The configured subject of the trusted issuer doesn't match with
- * the issuer of the SAML token
- *
- * Ignored because PeerTrust ignores subject attribute
- */
- @org.junit.Test
- @org.junit.Ignore
- public void validateSAML2TokenUntrustedIssuer() throws Exception {
- SAML2CallbackHandler callbackHandler = new SAML2CallbackHandler();
- callbackHandler.setStatement(SAML2CallbackHandler.Statement.ATTR);
- callbackHandler.setConfirmationMethod(SAML2Constants.CONF_BEARER);
- callbackHandler.setIssuer(TEST_RSTR_ISSUER);
- callbackHandler.setSubjectName(TEST_USER);
- ConditionsBean cp = new ConditionsBean();
- AudienceRestrictionBean audienceRestriction = new AudienceRestrictionBean();
- audienceRestriction.getAudienceURIs().add(TEST_AUDIENCE);
- cp.setAudienceRestrictions(Collections.singletonList(audienceRestriction));
- callbackHandler.setConditions(cp);
-
- SAMLCallback samlCallback = new SAMLCallback();
- SAMLUtil.doSAMLCallback(callbackHandler, samlCallback);
- SamlAssertionWrapper assertion = new SamlAssertionWrapper(samlCallback);
-
- String rstr = createSamlToken(assertion, "mystskey", true);
- FedizRequest wfReq = new FedizRequest();
- wfReq.setAction(FederationConstants.ACTION_SIGNIN);
- wfReq.setResponseToken(rstr);
-
- // Load and update the config to enforce an error
- configurator = null;
- FedizContext config = getFederationConfigurator().getFedizContext("ROOT");
- config.getTrustedIssuers().get(0).setSubject("wrong-issuer-name");
-
- FedizProcessor wfProc = new FederationProcessorImpl();
- try {
- wfProc.processRequest(wfReq, config);
- Assert.fail("Processing must fail because of untrusted issuer configured");
- } catch (ProcessingException ex) {
- if (!TYPE.ISSUER_NOT_TRUSTED.equals(ex.getType())) {
- fail("Expected ProcessingException with ISSUER_NOT_TRUSTED type");
- }
- }
- }
-
- /**
- * Validate SAML 2 token which includes the role attribute with 2 values
- * The configured subject of the trusted issuer doesn't match with
- * the issuer of the SAML token
- */
- @org.junit.Test
- public void validateUnsignedSAML2Token() throws Exception {
- SAML2CallbackHandler callbackHandler = new SAML2CallbackHandler();
- callbackHandler.setStatement(SAML2CallbackHandler.Statement.ATTR);
- callbackHandler.setConfirmationMethod(SAML2Constants.CONF_BEARER);
- callbackHandler.setIssuer(TEST_RSTR_ISSUER);
- callbackHandler.setSubjectName(TEST_USER);
- ConditionsBean cp = new ConditionsBean();
- AudienceRestrictionBean audienceRestriction = new AudienceRestrictionBean();
- audienceRestriction.getAudienceURIs().add(TEST_AUDIENCE);
- cp.setAudienceRestrictions(Collections.singletonList(audienceRestriction));
- callbackHandler.setConditions(cp);
-
- SAMLCallback samlCallback = new SAMLCallback();
- SAMLUtil.doSAMLCallback(callbackHandler, samlCallback);
- SamlAssertionWrapper assertion = new SamlAssertionWrapper(samlCallback);
-
- String rstr = createSamlToken(assertion, "mystskey", false);
- FedizRequest wfReq = new FedizRequest();
- wfReq.setAction(FederationConstants.ACTION_SIGNIN);
- wfReq.setResponseToken(rstr);
-
- // Load and update the config to enforce an error
- configurator = null;
- FedizContext config = getFederationConfigurator().getFedizContext("ROOT");
-
- FedizProcessor wfProc = new FederationProcessorImpl();
- try {
- wfProc.processRequest(wfReq, config);
- Assert.fail("Processing must fail because of missing signature");
- } catch (ProcessingException ex) {
- if (!TYPE.TOKEN_NO_SIGNATURE.equals(ex.getType())) {
- fail("Expected ProcessingException with TOKEN_NO_SIGNATURE type");
- }
- }
- }
-
- /**
- * Validate SAML 2 token twice which causes an exception
- * due to replay attack
- */
- @org.junit.Test
- public void testReplayAttack() throws Exception {
- SAML2CallbackHandler callbackHandler = new SAML2CallbackHandler();
- callbackHandler.setStatement(SAML2CallbackHandler.Statement.ATTR);
- callbackHandler.setConfirmationMethod(SAML2Constants.CONF_BEARER);
- callbackHandler.setIssuer(TEST_RSTR_ISSUER);
- callbackHandler.setSubjectName(TEST_USER);
- ConditionsBean cp = new ConditionsBean();
- AudienceRestrictionBean audienceRestriction = new AudienceRestrictionBean();
- audienceRestriction.getAudienceURIs().add(TEST_AUDIENCE);
- cp.setAudienceRestrictions(Collections.singletonList(audienceRestriction));
- callbackHandler.setConditions(cp);
-
- SAMLCallback samlCallback = new SAMLCallback();
- SAMLUtil.doSAMLCallback(callbackHandler, samlCallback);
- SamlAssertionWrapper assertion = new SamlAssertionWrapper(samlCallback);
-
- String rstr = createSamlToken(assertion, "mystskey", true);
-
- FedizRequest wfReq = new FedizRequest();
- wfReq.setAction(FederationConstants.ACTION_SIGNIN);
- wfReq.setResponseToken(rstr);
-
- configurator = null;
- FedizContext config = getFederationConfigurator().getFedizContext("ROOT");
-
- FedizProcessor wfProc = new FederationProcessorImpl();
- FedizResponse wfRes = wfProc.processRequest(wfReq, config);
- Assert.assertEquals("Principal name wrong", TEST_USER,
- wfRes.getUsername());
- Assert.assertEquals("Issuer wrong", TEST_RSTR_ISSUER, wfRes.getIssuer());
-
- wfProc = new FederationProcessorImpl();
- try {
- wfProc.processRequest(wfReq, config);
- fail("Failure expected on a replay attack");
- } catch (ProcessingException ex) {
- if (!TYPE.TOKEN_REPLAY.equals(ex.getType())) {
- fail("Expected ProcessingException with TOKEN_REPLAY type");
- }
- }
- }
-
-
- /**
- * Validate SAML 2 token which includes the role attribute with 2 values
- * The configured subject of the trusted issuer doesn't match with
- * the issuer of the SAML token
- */
- @org.junit.Test
- public void validateSAML2TokenSeveralCertStore() throws Exception {
- SAML2CallbackHandler callbackHandler = new SAML2CallbackHandler();
- callbackHandler.setStatement(SAML2CallbackHandler.Statement.ATTR);
- callbackHandler.setConfirmationMethod(SAML2Constants.CONF_BEARER);
- callbackHandler.setIssuer(TEST_RSTR_ISSUER);
- callbackHandler.setSubjectName(TEST_USER);
- ConditionsBean cp = new ConditionsBean();
- AudienceRestrictionBean audienceRestriction = new AudienceRestrictionBean();
- audienceRestriction.getAudienceURIs().add(TEST_AUDIENCE);
- cp.setAudienceRestrictions(Collections.singletonList(audienceRestriction));
- callbackHandler.setConditions(cp);
-
- SAMLCallback samlCallback = new SAMLCallback();
- SAMLUtil.doSAMLCallback(callbackHandler, samlCallback);
- SamlAssertionWrapper assertion = new SamlAssertionWrapper(samlCallback);
-
- String rstr = createSamlToken(assertion, "mystskey", true);
- FedizRequest wfReq = new FedizRequest();
- wfReq.setAction(FederationConstants.ACTION_SIGNIN);
- wfReq.setResponseToken(rstr);
-
- // Load and update the config to enforce an error
- configurator = null;
- FedizContext config = getFederationConfigurator().getFedizContext("ROOT2");
-
- FedizProcessor wfProc = new FederationProcessorImpl();
- FedizResponse wfRes = wfProc.processRequest(wfReq, config);
-
- Assert.assertEquals("Principal name wrong", TEST_USER,
- wfRes.getUsername());
- Assert.assertEquals("Issuer wrong", TEST_RSTR_ISSUER, wfRes.getIssuer());
- Assert.assertEquals("Two roles must be found", 2, wfRes.getRoles()
- .size());
- }
-
- /**
- * Validate SAML 2 token which includes the role attribute with 2 values
- * The configured subject of the trusted issuer doesn't match with
- * the issuer of the SAML token
- */
- @org.junit.Test
- public void validateSAML2TokenSeveralCertStoreTrustedIssuer() throws Exception {
- SAML2CallbackHandler callbackHandler = new SAML2CallbackHandler();
- callbackHandler.setStatement(SAML2CallbackHandler.Statement.ATTR);
- callbackHandler.setConfirmationMethod(SAML2Constants.CONF_BEARER);
- callbackHandler.setIssuer(TEST_RSTR_ISSUER);
- callbackHandler.setSubjectName(TEST_USER);
- ConditionsBean cp = new ConditionsBean();
- AudienceRestrictionBean audienceRestriction = new AudienceRestrictionBean();
- audienceRestriction.getAudienceURIs().add(TEST_AUDIENCE);
- cp.setAudienceRestrictions(Collections.singletonList(audienceRestriction));
- callbackHandler.setConditions(cp);
-
- SAMLCallback samlCallback = new SAMLCallback();
- SAMLUtil.doSAMLCallback(callbackHandler, samlCallback);
- SamlAssertionWrapper assertion = new SamlAssertionWrapper(samlCallback);
-
- String rstr = createSamlToken(assertion, "mystskey", true);
- FedizRequest wfReq = new FedizRequest();
- wfReq.setAction(FederationConstants.ACTION_SIGNIN);
- wfReq.setResponseToken(rstr);
-
- // Load and update the config to enforce an error
- configurator = null;
- FedizContext config = getFederationConfigurator().getFedizContext("ROOT3");
-
- FedizProcessor wfProc = new FederationProcessorImpl();
- FedizResponse wfRes = wfProc.processRequest(wfReq, config);
-
- Assert.assertEquals("Principal name wrong", TEST_USER,
- wfRes.getUsername());
- Assert.assertEquals("Issuer wrong", TEST_RSTR_ISSUER, wfRes.getIssuer());
- Assert.assertEquals("Two roles must be found", 2, wfRes.getRoles()
- .size());
- }
-
- /**
- * Validate SAML 2 token which is expired
- */
- @org.junit.Test
- public void validateSAML2TokenExpired() throws Exception {
- SAML2CallbackHandler callbackHandler = new SAML2CallbackHandler();
- callbackHandler.setStatement(SAML2CallbackHandler.Statement.ATTR);
- callbackHandler.setConfirmationMethod(SAML2Constants.CONF_BEARER);
- callbackHandler.setIssuer(TEST_RSTR_ISSUER);
- callbackHandler.setSubjectName(TEST_USER);
- ConditionsBean cp = new ConditionsBean();
- DateTime currentTime = new DateTime();
- currentTime = currentTime.minusSeconds(60);
- cp.setNotAfter(currentTime);
- currentTime = new DateTime();
- currentTime = currentTime.minusSeconds(300);
- cp.setNotBefore(currentTime);
- AudienceRestrictionBean audienceRestriction = new AudienceRestrictionBean();
- audienceRestriction.getAudienceURIs().add(TEST_AUDIENCE);
- cp.setAudienceRestrictions(Collections.singletonList(audienceRestriction));
- callbackHandler.setConditions(cp);
-
- SAMLCallback samlCallback = new SAMLCallback();
- SAMLUtil.doSAMLCallback(callbackHandler, samlCallback);
- SamlAssertionWrapper assertion = new SamlAssertionWrapper(samlCallback);
-
- String rstr = createSamlToken(assertion, "mystskey", true);
-
- FedizRequest wfReq = new FedizRequest();
- wfReq.setAction(FederationConstants.ACTION_SIGNIN);
- wfReq.setResponseToken(rstr);
-
- configurator = null;
- FedizContext config = getFederationConfigurator().getFedizContext("ROOT");
-
- FedizProcessor wfProc = new FederationProcessorImpl();
- try {
- wfProc.processRequest(wfReq, config);
- fail("Failure expected on expired SAML token");
- } catch (ProcessingException ex) {
- if (!TYPE.TOKEN_EXPIRED.equals(ex.getType())) {
- fail("Expected ProcessingException with TOKEN_EXPIRED type");
- }
- }
- }
-
- /**
- * Validate SAML 2 token which is not yet valid (in 30 seconds)
- * but within the maximum clock skew range (60 seconds)
- */
- @org.junit.Test
- public void validateSAML2TokenClockSkewRange() throws Exception {
- SAML2CallbackHandler callbackHandler = new SAML2CallbackHandler();
- callbackHandler.setStatement(SAML2CallbackHandler.Statement.ATTR);
- callbackHandler.setConfirmationMethod(SAML2Constants.CONF_BEARER);
- callbackHandler.setIssuer(TEST_RSTR_ISSUER);
- callbackHandler.setSubjectName(TEST_USER);
- ConditionsBean cp = new ConditionsBean();
- DateTime currentTime = new DateTime();
- currentTime = currentTime.plusSeconds(300);
- cp.setNotAfter(currentTime);
- currentTime = new DateTime();
- currentTime = currentTime.plusSeconds(30);
- cp.setNotBefore(currentTime);
- AudienceRestrictionBean audienceRestriction = new AudienceRestrictionBean();
- audienceRestriction.getAudienceURIs().add(TEST_AUDIENCE);
- cp.setAudienceRestrictions(Collections.singletonList(audienceRestriction));
- callbackHandler.setConditions(cp);
-
- SAMLCallback samlCallback = new SAMLCallback();
- SAMLUtil.doSAMLCallback(callbackHandler, samlCallback);
- SamlAssertionWrapper assertion = new SamlAssertionWrapper(samlCallback);
-
- String rstr = createSamlToken(assertion, "mystskey", true);
-
- FedizRequest wfReq = new FedizRequest();
- wfReq.setAction(FederationConstants.ACTION_SIGNIN);
- wfReq.setResponseToken(rstr);
-
- configurator = null;
- FedizContext config = getFederationConfigurator().getFedizContext("ROOT");
- config.setMaximumClockSkew(BigInteger.valueOf(60));
-
- FedizProcessor wfProc = new FederationProcessorImpl();
- FedizResponse wfRes = wfProc.processRequest(wfReq, config);
-
- Assert.assertEquals("Principal name wrong", TEST_USER,
- wfRes.getUsername());
- Assert.assertEquals("Issuer wrong", TEST_RSTR_ISSUER, wfRes.getIssuer());
- Assert.assertEquals("Two roles must be found", 2, wfRes.getRoles()
- .size());
- }
-
- /**
- * "Validate" SAML 2 token with a custom token validator
- * If a validator is configured it precedes the SAMLTokenValidator as part of Fediz
- */
- @org.junit.Test
- public void validateSAML2TokenCustomValidator() throws Exception {
- SAML2CallbackHandler callbackHandler = new SAML2CallbackHandler();
- callbackHandler.setStatement(SAML2CallbackHandler.Statement.ATTR);
- callbackHandler.setConfirmationMethod(SAML2Constants.CONF_BEARER);
- callbackHandler.setIssuer(TEST_RSTR_ISSUER);
- callbackHandler.setSubjectName(TEST_USER);
- ConditionsBean cp = new ConditionsBean();
- AudienceRestrictionBean audienceRestriction = new AudienceRestrictionBean();
- audienceRestriction.getAudienceURIs().add(TEST_AUDIENCE);
- cp.setAudienceRestrictions(Collections.singletonList(audienceRestriction));
- callbackHandler.setConditions(cp);
-
- SAMLCallback samlCallback = new SAMLCallback();
- SAMLUtil.doSAMLCallback(callbackHandler, samlCallback);
- SamlAssertionWrapper assertion = new SamlAssertionWrapper(samlCallback);
-
- String rstr = createSamlToken(assertion, "mystskey", true);
-
- FedizRequest wfReq = new FedizRequest();
- wfReq.setAction(FederationConstants.ACTION_SIGNIN);
- wfReq.setResponseToken(rstr);
-
- configurator = null;
- FedizContext config = getFederationConfigurator().getFedizContext("CUSTTOK");
- FederationProtocol fp = (FederationProtocol)config.getProtocol();
- List<TokenValidator> validators = fp.getTokenValidators();
- Assert.assertEquals("Two validators must be found", 2, validators.size());
- Assert.assertEquals("First validator must be custom validator",
- CustomValidator.class.getName(), validators.get(0).getClass().getName());
-
- FedizProcessor wfProc = new FederationProcessorImpl();
- FedizResponse wfRes = wfProc.processRequest(wfReq, config);
-
- Assert.assertEquals("Principal name wrong", TEST_USER,
- wfRes.getUsername());
- Assert.assertEquals("Issuer wrong", TEST_RSTR_ISSUER, wfRes.getIssuer());
- }
-
- /**
- * "Validate" SAML 2 token with a custom token validator
- * If a validator is configured it precedes the SAMLTokenValidator as part of Fediz
- */
- @org.junit.Test
- public void validateSAML2TokenMaxClockSkewNotDefined() throws Exception {
- SAML2CallbackHandler callbackHandler = new SAML2CallbackHandler();
- callbackHandler.setStatement(SAML2CallbackHandler.Statement.ATTR);
- callbackHandler.setConfirmationMethod(SAML2Constants.CONF_BEARER);
- callbackHandler.setIssuer(TEST_RSTR_ISSUER);
- callbackHandler.setSubjectName(TEST_USER);
- ConditionsBean cp = new ConditionsBean();
- AudienceRestrictionBean audienceRestriction = new AudienceRestrictionBean();
- audienceRestriction.getAudienceURIs().add(TEST_AUDIENCE);
- cp.setAudienceRestrictions(Collections.singletonList(audienceRestriction));
- callbackHandler.setConditions(cp);
-
- SAMLCallback samlCallback = new SAMLCallback();
- SAMLUtil.doSAMLCallback(callbackHandler, samlCallback);
- SamlAssertionWrapper assertion = new SamlAssertionWrapper(samlCallback);
-
- String rstr = createSamlToken(assertion, "mystskey", true);
-
- FedizRequest wfReq = new FedizRequest();
- wfReq.setAction(FederationConstants.ACTION_SIGNIN);
- wfReq.setResponseToken(rstr);
-
- configurator = null;
- FedizContext config = getFederationConfigurator().getFedizContext("NOCLOCKSKEW");
-
- FedizProcessor wfProc = new FederationProcessorImpl();
- FedizResponse wfRes = wfProc.processRequest(wfReq, config);
-
- Assert.assertEquals("Principal name wrong", TEST_USER,
- wfRes.getUsername());
- Assert.assertEquals("Issuer wrong", TEST_RSTR_ISSUER, wfRes.getIssuer());
- Assert.assertEquals("Two roles must be found", 2, wfRes.getRoles()
- .size());
- Assert.assertEquals("Audience wrong", TEST_AUDIENCE, wfRes.getAudience());
- }
-
- /**
- * Validate an encrypted SAML 2 token which includes the role attribute with 2 values
- * Roles are encoded as a multi-value saml attribute
- */
- @org.junit.Test
- public void validateEncryptedSAML2Token() throws Exception {
- SAML2CallbackHandler callbackHandler = new SAML2CallbackHandler();
- callbackHandler.setStatement(SAML2CallbackHandler.Statement.ATTR);
- callbackHandler.setConfirmationMethod(SAML2Constants.CONF_BEARER);
- callbackHandler.setIssuer(TEST_RSTR_ISSUER);
- callbackHandler.setSubjectName(TEST_USER);
- ConditionsBean cp = new ConditionsBean();
- AudienceRestrictionBean audienceRestriction = new AudienceRestrictionBean();
- audienceRestriction.getAudienceURIs().add(TEST_AUDIENCE);
- cp.setAudienceRestrictions(Collections.singletonList(audienceRestriction));
- callbackHandler.setConditions(cp);
-
- SAMLCallback samlCallback = new SAMLCallback();
- SAMLUtil.doSAMLCallback(callbackHandler, samlCallback);
- SamlAssertionWrapper assertion = new SamlAssertionWrapper(samlCallback);
-
- String rstr = encryptAndSignToken(assertion);
-
- FedizRequest wfReq = new FedizRequest();
- wfReq.setAction(FederationConstants.ACTION_SIGNIN);
- wfReq.setResponseToken(rstr);
-
- configurator = null;
- FedizContext config =
- getFederationConfigurator().getFedizContext("ROOT_DECRYPTION");
-
- FedizProcessor wfProc = new FederationProcessorImpl();
- FedizResponse wfRes = wfProc.processRequest(wfReq, config);
-
- Assert.assertEquals("Principal name wrong", TEST_USER,
- wfRes.getUsername());
- Assert.assertEquals("Issuer wrong", TEST_RSTR_ISSUER, wfRes.getIssuer());
- Assert.assertEquals("Two roles must be found", 2, wfRes.getRoles()
- .size());
- Assert.assertEquals("Audience wrong", TEST_AUDIENCE, wfRes.getAudience());
- assertClaims(wfRes.getClaims(), callbackHandler.getRoleAttributeName());
- }
-
- /**
- * Validate a HolderOfKey SAML 2 token
- */
- @org.junit.Test
- public void validateHOKSAML2Token() throws Exception {
- SAML2CallbackHandler callbackHandler = new SAML2CallbackHandler();
- callbackHandler.setStatement(SAML2CallbackHandler.Statement.AUTHN);
- callbackHandler.setConfirmationMethod(SAML2Constants.CONF_HOLDER_KEY);
- callbackHandler.setIssuer(TEST_RSTR_ISSUER);
- callbackHandler.setSubjectName(TEST_USER);
- ConditionsBean cp = new ConditionsBean();
- AudienceRestrictionBean audienceRestriction = new AudienceRestrictionBean();
- audienceRestriction.getAudienceURIs().add(TEST_AUDIENCE);
- cp.setAudienceRestrictions(Collections.singletonList(audienceRestriction));
- callbackHandler.setConditions(cp);
-
- Crypto clientCrypto = CryptoFactory.getInstance("client-crypto.properties");
- CryptoType cryptoType = new CryptoType(CryptoType.TYPE.ALIAS);
- cryptoType.setAlias("myclientkey");
- X509Certificate[] certs = clientCrypto.getX509Certificates(cryptoType);
- callbackHandler.setCerts(certs);
-
- 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);
-
- Document doc = STSUtil.toSOAPPart(STSUtil.SAMPLE_RSTR_COLL_MSG);
- Element token = assertion.toDOM(doc);
-
- Element e = FederationProcessorTest.findElement(doc, "RequestedSecurityToken",
- FederationConstants.WS_TRUST_13_NS);
- if (e == null) {
- e = FederationProcessorTest.findElement(doc, "RequestedSecurityToken",
- FederationConstants.WS_TRUST_2005_02_NS);
- }
- e.appendChild(token);
-
- String rstr = DOM2Writer.nodeToString(doc);
-
- FedizRequest wfReq = new FedizRequest();
- wfReq.setAction(FederationConstants.ACTION_SIGNIN);
- wfReq.setResponseToken(rstr);
-
- configurator = null;
- FedizContext config =
- getFederationConfigurator().getFedizContext("ROOT_DECRYPTION");
-
- FedizProcessor wfProc = new FederationProcessorImpl();
- try {
- wfProc.processRequest(wfReq, config);
- fail("Failure expected on missing client certs");
- } catch (ProcessingException ex) {
- // expected
- }
-
- // Now set client certs
- wfReq.setCerts(certs);
- wfProc.processRequest(wfReq, config);
- }
-
- @org.junit.Test
- public void validateSAML2TokenWithConfigCreatedWithAPI() throws Exception {
-
- ContextConfig config = new ContextConfig();
-
- config.setName("whatever");
-
- // Configure certificate store
- CertificateStores certStores = new CertificateStores();
- TrustManagersType tm0 = new TrustManagersType();
- KeyStoreType ks0 = new KeyStoreType();
- ks0.setType("JKS");
- ks0.setPassword("storepass");
- ks0.setFile("ststrust.jks");
- tm0.setKeyStore(ks0);
- certStores.getTrustManager().add(tm0);
- config.setCertificateStores(certStores);
-
- // Configure trusted IDP
- TrustedIssuers trustedIssuers = new TrustedIssuers();
- TrustedIssuerType ti0 = new TrustedIssuerType();
- ti0.setCertificateValidation(ValidationType.CHAIN_TRUST);
- ti0.setName("FedizSTSIssuer");
- ti0.setSubject(".*CN=www.sts.com.*");
- trustedIssuers.getIssuer().add(ti0);
- config.setTrustedIssuers(trustedIssuers);
-
- FederationProtocolType protocol = new FederationProtocolType();
- config.setProtocol(protocol);
-
- AudienceUris audienceUris = new AudienceUris();
- audienceUris.getAudienceItem().add("https://localhost/fedizhelloworld");
- config.setAudienceUris(audienceUris);
-
- protocol.setRoleURI("http://schemas.xmlsoap.org/ws/2005/05/identity/claims/role");
-
- FedizContext fedContext = new FedizContext(config);
- fedContext.init();
-
- SAML2CallbackHandler callbackHandler = new SAML2CallbackHandler();
- callbackHandler.setStatement(SAML2CallbackHandler.Statement.ATTR);
- callbackHandler.setConfirmationMethod(SAML2Constants.CONF_BEARER);
- callbackHandler.setIssuer(TEST_RSTR_ISSUER);
- callbackHandler.setSubjectName(TEST_USER);
- ConditionsBean cp = new ConditionsBean();
- AudienceRestrictionBean audienceRestriction = new AudienceRestrictionBean();
- audienceRestriction.getAudienceURIs().add(TEST_AUDIENCE);
- cp.setAudienceRestrictions(Collections.singletonList(audienceRestriction));
- callbackHandler.setConditions(cp);
-
- SAMLCallback samlCallback = new SAMLCallback();
- SAMLUtil.doSAMLCallback(callbackHandler, samlCallback);
- SamlAssertionWrapper assertion = new SamlAssertionWrapper(samlCallback);
-
- String rstr = createSamlToken(assertion, "mystskey", true, STSUtil.SAMPLE_RSTR_MSG);
-
- FedizRequest wfReq = new FedizRequest();
- wfReq.setAction(FederationConstants.ACTION_SIGNIN);
- wfReq.setResponseToken(rstr);
-
- FedizProcessor wfProc = new FederationProcessorImpl();
- FedizResponse wfRes = wfProc.processRequest(wfReq, fedContext);
-
- Assert.assertEquals("Principal name wrong", TEST_USER,
- wfRes.getUsername());
- Assert.assertEquals("Issuer wrong", TEST_RSTR_ISSUER, wfRes.getIssuer());
- Assert.assertEquals("Two roles must be found", 2, wfRes.getRoles()
- .size());
- Assert.assertEquals("Audience wrong", TEST_AUDIENCE, wfRes.getAudience());
-
- fedContext.close();
-
- }
-
-
- private String encryptAndSignToken(
- SamlAssertionWrapper assertion
- ) throws Exception {
-
- WSPasswordCallback[] cb = {
- new WSPasswordCallback("mystskey", WSPasswordCallback.SIGNATURE)
- };
- cbPasswordHandler.handle(cb);
- String password = cb[0].getPassword();
-
- assertion.signAssertion("mystskey", password, crypto, false);
-
- Document doc = STSUtil.toSOAPPart(STSUtil.SAMPLE_RSTR_COLL_MSG);
- Element token = assertion.toDOM(doc);
-
- Element e = FederationProcessorTest.findElement(doc, "RequestedSecurityToken",
- FederationConstants.WS_TRUST_13_NS);
- if (e == null) {
- e = FederationProcessorTest.findElement(doc, "RequestedSecurityToken",
- FederationConstants.WS_TRUST_2005_02_NS);
- }
- e.appendChild(token);
-
- WSSecEncrypt builder = new WSSecEncrypt();
- builder.setUserInfo("mystskey");
-
- builder.setKeyIdentifierType(WSConstants.ISSUER_SERIAL);
- builder.setSymmetricEncAlgorithm(WSConstants.AES_128);
- builder.setKeyEncAlgo(WSConstants.KEYTRANSPORT_RSA15);
- builder.setEmbedEncryptedKey(true);
-
- WSEncryptionPart encryptionPart = new WSEncryptionPart(assertion.getId(), "Element");
- encryptionPart.setElement(token);
-
- Crypto encrCrypto = CryptoFactory.getInstance("signature.properties");
- builder.prepare(token.getOwnerDocument(), encrCrypto);
- builder.encryptForRef(null, Collections.singletonList(encryptionPart));
-
- // return doc.getDocumentElement();
- return DOM2Writer.nodeToString(doc);
- }
-
- private String createSamlToken(SamlAssertionWrapper assertion, String alias, boolean sign)
- throws IOException, UnsupportedCallbackException, WSSecurityException, Exception {
- return createSamlToken(assertion, alias, sign, STSUtil.SAMPLE_RSTR_COLL_MSG);
- }
-
- private String createSamlToken(SamlAssertionWrapper assertion, String alias, boolean sign, String rstr)
- 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);
- }
- Document doc = STSUtil.toSOAPPart(rstr);
- Element token = assertion.toDOM(doc);
-
- Element e = FederationProcessorTest.findElement(doc, "RequestedSecurityToken",
- FederationConstants.WS_TRUST_13_NS);
- if (e == null) {
- e = FederationProcessorTest.findElement(doc, "RequestedSecurityToken",
- FederationConstants.WS_TRUST_2005_02_NS);
- }
- e.appendChild(token);
- return DOM2Writer.nodeToString(doc);
- }
-
-
-
-
- /**
- * 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 void assertClaims(List<Claim> claims, String roleClaimType) {
- for (Claim c : claims) {
- Assert.assertTrue("Invalid ClaimType URI: " + c.getClaimType(),
- c.getClaimType().equals(roleClaimType)
- || c.getClaimType().equals(ClaimTypes.COUNTRY)
- || c.getClaimType().equals(AbstractSAMLCallbackHandler.CLAIM_TYPE_LANGUAGE)
- );
- }
- }
-
-
-}