/** * 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.URI; 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.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.FedizConfigurator; import org.apache.cxf.fediz.core.config.FedizContext; import org.apache.cxf.fediz.core.config.Protocol; 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.common.util.XMLUtils; import org.apache.wss4j.dom.WSConstants; import org.apache.wss4j.dom.message.WSSecEncrypt; import org.joda.time.DateTime; import org.joda.time.DateTimeZone; 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 FederationResponseTest { public static final String SAMPLE_MULTIPLE_RSTR_COLL_MSG = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" + "<RequestSecurityTokenResponseCollection " + "xmlns=\"http://docs.oasis-open.org/ws-sx/ws-trust/200512\"> " + "<RequestSecurityTokenResponse>" + "<RequestedSecurityToken>" + "</RequestedSecurityToken>" + "</RequestSecurityTokenResponse>" + "<RequestSecurityTokenResponse>" + "<RequestedSecurityToken>" + "</RequestedSecurityToken>" + "</RequestSecurityTokenResponse>" + "</RequestSecurityTokenResponseCollection>"; 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()); } @org.junit.Test public void testChainTrust() 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); // Test successful trust validation (subject cert constraint) configurator = null; FedizContext config = getFederationConfigurator().getFedizContext("CHAIN_TRUST"); 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("Audience wrong", TEST_AUDIENCE, wfRes.getAudience()); // Test unsuccessful trust validation (bad subject cert constraint) configurator = null; config = getFederationConfigurator().getFedizContext("CHAIN_TRUST2"); wfProc = new FederationProcessorImpl(); try { wfRes = wfProc.processRequest(wfReq, config); Assert.fail("Processing must fail because of invalid subject cert constraint"); } catch (ProcessingException ex) { // expected } } /** * 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()); } @org.junit.Test public void validateSAML2TokenSubjectWithComment() throws Exception { SAML2CallbackHandler callbackHandler = new SAML2CallbackHandler(); callbackHandler.setStatement(SAML2CallbackHandler.Statement.ATTR); callbackHandler.setConfirmationMethod(SAML2Constants.CONF_BEARER); callbackHandler.setIssuer(TEST_RSTR_ISSUER); String subject = "alice<!---->o=example.com"; callbackHandler.setSubjectName(subject); 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", subject, 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 1 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"); 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"); Protocol protocol = config.getProtocol(); protocol.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()); } @org.junit.Test public void validateSAML2TokenEmptyRole() 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(Collections.singletonList("")); 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"); Protocol protocol = config.getProtocol(); protocol.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(1, wfRes.getRoles().size()); Assert.assertEquals("", wfRes.getRoles().get(0)); } @org.junit.Test public void validateSAML2TokenNoRoleValue() 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.setAddRoleValue(false); 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"); Protocol protocol = config.getProtocol(); protocol.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(null, wfRes.getRoles()); } /** * 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"); } } } @org.junit.Test public void testUnsignedAssertionAfterSignedAssertion() throws Exception { // First assertion 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 assertion1 = new SamlAssertionWrapper(samlCallback); // Second assertion SAML2CallbackHandler callbackHandler2 = new SAML2CallbackHandler(); callbackHandler2.setStatement(SAML2CallbackHandler.Statement.ATTR); callbackHandler2.setConfirmationMethod(SAML2Constants.CONF_BEARER); callbackHandler2.setIssuer(TEST_RSTR_ISSUER); callbackHandler2.setSubjectName("bob"); ConditionsBean cp2 = new ConditionsBean(); AudienceRestrictionBean audienceRestriction2 = new AudienceRestrictionBean(); audienceRestriction2.getAudienceURIs().add(TEST_AUDIENCE); cp2.setAudienceRestrictions(Collections.singletonList(audienceRestriction2)); callbackHandler2.setConditions(cp2); SAMLCallback samlCallback2 = new SAMLCallback(); SAMLUtil.doSAMLCallback(callbackHandler2, samlCallback2); SamlAssertionWrapper assertion2 = new SamlAssertionWrapper(samlCallback2); Element rstrElement = createResponseWithMultipleAssertions(assertion1, true, assertion2, false, "mystskey"); String rstr = DOM2Writer.nodeToString(rstrElement); 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(); FedizResponse fedizResponse = wfProc.processRequest(wfReq, config); Assert.assertEquals(TEST_USER, fedizResponse.getUsername()); } @org.junit.Test public void testSignedAssertionAfterUnsignedAssertion() throws Exception { // First assertion 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 assertion1 = new SamlAssertionWrapper(samlCallback); // Second assertion SAML2CallbackHandler callbackHandler2 = new SAML2CallbackHandler(); callbackHandler2.setStatement(SAML2CallbackHandler.Statement.ATTR); callbackHandler2.setConfirmationMethod(SAML2Constants.CONF_BEARER); callbackHandler2.setIssuer(TEST_RSTR_ISSUER); callbackHandler2.setSubjectName("bob"); ConditionsBean cp2 = new ConditionsBean(); AudienceRestrictionBean audienceRestriction2 = new AudienceRestrictionBean(); audienceRestriction2.getAudienceURIs().add(TEST_AUDIENCE); cp2.setAudienceRestrictions(Collections.singletonList(audienceRestriction2)); callbackHandler2.setConditions(cp2); SAMLCallback samlCallback2 = new SAMLCallback(); SAMLUtil.doSAMLCallback(callbackHandler2, samlCallback2); SamlAssertionWrapper assertion2 = new SamlAssertionWrapper(samlCallback2); Element rstrElement = createResponseWithMultipleAssertions(assertion2, false, assertion1, true, "mystskey"); String rstr = DOM2Writer.nodeToString(rstrElement); 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"); } } } @org.junit.Test public void testWrappingAttack() throws Exception { // First assertion 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 assertion1 = new SamlAssertionWrapper(samlCallback); // Second assertion SAML2CallbackHandler callbackHandler2 = new SAML2CallbackHandler(); callbackHandler2.setStatement(SAML2CallbackHandler.Statement.ATTR); callbackHandler2.setConfirmationMethod(SAML2Constants.CONF_BEARER); callbackHandler2.setIssuer(TEST_RSTR_ISSUER); callbackHandler2.setSubjectName("bob"); ConditionsBean cp2 = new ConditionsBean(); AudienceRestrictionBean audienceRestriction2 = new AudienceRestrictionBean(); audienceRestriction2.getAudienceURIs().add(TEST_AUDIENCE); cp2.setAudienceRestrictions(Collections.singletonList(audienceRestriction2)); callbackHandler2.setConditions(cp2); SAMLCallback samlCallback2 = new SAMLCallback(); SAMLUtil.doSAMLCallback(callbackHandler2, samlCallback2); SamlAssertionWrapper assertion2 = new SamlAssertionWrapper(samlCallback2); WSPasswordCallback[] cb = { new WSPasswordCallback("mystskey", WSPasswordCallback.SIGNATURE) }; cbPasswordHandler.handle(cb); String password = cb[0].getPassword(); assertion1.signAssertion("mystskey", password, crypto, false); assertion2.signAssertion("mystskey", password, crypto, false); Document doc = STSUtil.toSOAPPart(SAMPLE_MULTIPLE_RSTR_COLL_MSG); Element token1 = assertion2.toDOM(doc); Element token2 = assertion1.toDOM(doc); // Now modify the first Signature to point to the other Element Element sig1 = XMLUtils.findElement(token1, "Signature", WSConstants.SIG_NS); Element sig2 = XMLUtils.findElement(token2, "Signature", WSConstants.SIG_NS); sig1.getParentNode().replaceChild(sig2.cloneNode(true), sig1); List<Element> requestedTokenElements = XMLUtils.findElements(doc, "RequestedSecurityToken", FederationConstants.WS_TRUST_13_NS); Assert.assertEquals(2, requestedTokenElements.size()); requestedTokenElements.get(0).appendChild(token1); requestedTokenElements.get(1).appendChild(token2); Element rstrElement = doc.getDocumentElement(); String rstr = DOM2Writer.nodeToString(rstrElement); 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 bad signature"); } catch (ProcessingException ex) { // expected } } private Element createResponseWithMultipleAssertions(SamlAssertionWrapper assertion1, boolean signFirstAssertion, SamlAssertionWrapper assertion2, boolean signSecondAssertion, String alias) throws Exception { WSPasswordCallback[] cb = { new WSPasswordCallback(alias, WSPasswordCallback.SIGNATURE) }; cbPasswordHandler.handle(cb); String password = cb[0].getPassword(); if (signFirstAssertion) { assertion1.signAssertion(alias, password, crypto, false); } if (signSecondAssertion) { assertion2.signAssertion(alias, password, crypto, false); } Document doc = STSUtil.toSOAPPart(SAMPLE_MULTIPLE_RSTR_COLL_MSG); Element token1 = assertion1.toDOM(doc); Element token2 = assertion2.toDOM(doc); List<Element> requestedTokenElements = XMLUtils.findElements(doc, "RequestedSecurityToken", FederationConstants.WS_TRUST_13_NS); Assert.assertEquals(2, requestedTokenElements.size()); requestedTokenElements.get(0).appendChild(token1); requestedTokenElements.get(1).appendChild(token2); return doc.getDocumentElement(); } /** * 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"); Protocol protocol = config.getProtocol(); List<TokenValidator> validators = protocol.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 = XMLUtils.findElement(doc, "RequestedSecurityToken", FederationConstants.WS_TRUST_13_NS); if (e == null) { e = XMLUtils.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(); } @org.junit.Test public void testModifiedSignature() 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); 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); // Change IssueInstant attribute String issueInstance = token.getAttributeNS(null, "IssueInstant"); DateTime issueDateTime = new DateTime(issueInstance, DateTimeZone.UTC); issueDateTime = issueDateTime.plusSeconds(1); token.setAttributeNS(null, "IssueInstant", issueDateTime.toString()); Element e = XMLUtils.findElement(doc, "RequestedSecurityToken", FederationConstants.WS_TRUST_13_NS); if (e == null) { e = XMLUtils.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"); FedizProcessor wfProc = new FederationProcessorImpl(); try { wfProc.processRequest(wfReq, config); fail("Failure expected on signature validation"); } catch (ProcessingException ex) { // expected } } @org.junit.Test public void testTrustFailure() 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("CLIENT_TRUST"); FedizProcessor wfProc = new FederationProcessorImpl(); try { wfProc.processRequest(wfReq, config); fail("Failure expected on non-trusted signing cert"); } catch (ProcessingException ex) { // expected } } @org.junit.Test public void testUnableToFindTruststore() 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("BAD_KEYSTORE"); FedizProcessor wfProc = new FederationProcessorImpl(); try { wfProc.processRequest(wfReq, config); fail("Failure expected on being unable to find the truststore"); } catch (ProcessingException ex) { ex.printStackTrace(); // expected } } 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 = XMLUtils.findElement(doc, "RequestedSecurityToken", FederationConstants.WS_TRUST_13_NS); if (e == null) { e = XMLUtils.findElement(doc, "RequestedSecurityToken", FederationConstants.WS_TRUST_2005_02_NS); } e.appendChild(token); WSSecEncrypt builder = new WSSecEncrypt(token.getOwnerDocument()); builder.setUserInfo("mystskey"); builder.setKeyIdentifierType(WSConstants.ISSUER_SERIAL); builder.setSymmetricEncAlgorithm(WSConstants.AES_128); builder.setKeyEncAlgo(WSConstants.KEYTRANSPORT_RSAOAEP); builder.setEmbedEncryptedKey(true); WSEncryptionPart encryptionPart = new WSEncryptionPart(assertion.getId(), "Element"); encryptionPart.setElement(token); Crypto encrCrypto = CryptoFactory.getInstance("signature.properties"); builder.prepare(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 = XMLUtils.findElement(doc, "RequestedSecurityToken", FederationConstants.WS_TRUST_13_NS); if (e == null) { e = XMLUtils.findElement(doc, "RequestedSecurityToken", FederationConstants.WS_TRUST_2005_02_NS); } e.appendChild(token); return DOM2Writer.nodeToString(doc); } private void assertClaims(List<Claim> claims, String roleClaimType) { URI roleClaimTypeURI = URI.create(roleClaimType); for (Claim c : claims) { Assert.assertTrue("Invalid ClaimType URI: " + c.getClaimType(), c.getClaimType().equals(roleClaimTypeURI) || c.getClaimType().equals(ClaimTypes.COUNTRY) || c.getClaimType().equals(AbstractSAMLCallbackHandler.CLAIM_TYPE_LANGUAGE) ); } } }