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/10/01 09:52:37 UTC

[4/8] git commit: Added support for some more options for the SAML protocol

Added support for some more options for the SAML protocol


Project: http://git-wip-us.apache.org/repos/asf/cxf-fediz/repo
Commit: http://git-wip-us.apache.org/repos/asf/cxf-fediz/commit/5966160a
Tree: http://git-wip-us.apache.org/repos/asf/cxf-fediz/tree/5966160a
Diff: http://git-wip-us.apache.org/repos/asf/cxf-fediz/diff/5966160a

Branch: refs/heads/master
Commit: 5966160a29a38bdd6ba5ff670d3596a87b0ee1f0
Parents: 7d4abd3
Author: Colm O hEigeartaigh <co...@apache.org>
Authored: Tue Sep 30 10:06:30 2014 +0100
Committer: Colm O hEigeartaigh <co...@apache.org>
Committed: Tue Sep 30 10:06:30 2014 +0100

----------------------------------------------------------------------
 .../apache/cxf/fediz/core/config/Protocol.java  |   2 +-
 .../cxf/fediz/core/config/SAMLProtocol.java     |  16 +++
 .../fediz/core/processor/SAMLProcessorImpl.java |  14 +-
 .../core/samlsso/SAMLSSOResponseValidator.java  |   3 +-
 .../src/main/resources/schemas/FedizConfig.xsd  |   4 +
 .../samlsso/SAMLResponseConformanceTest.java    | 141 +++++++++++++++++++
 .../fediz/integrationtests/AbstractTests.java   |   2 +-
 7 files changed, 176 insertions(+), 6 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cxf-fediz/blob/5966160a/plugins/core/src/main/java/org/apache/cxf/fediz/core/config/Protocol.java
----------------------------------------------------------------------
diff --git a/plugins/core/src/main/java/org/apache/cxf/fediz/core/config/Protocol.java b/plugins/core/src/main/java/org/apache/cxf/fediz/core/config/Protocol.java
index 6900891..8f82cdf 100644
--- a/plugins/core/src/main/java/org/apache/cxf/fediz/core/config/Protocol.java
+++ b/plugins/core/src/main/java/org/apache/cxf/fediz/core/config/Protocol.java
@@ -164,7 +164,7 @@ public abstract class Protocol {
     }
     
     protected Object loadCallbackType(CallbackType cbt, String name) {
-        if (cbt == null) {
+        if (cbt == null || cbt.getValue() == null) {
             return null;
         }
         if (cbt.getType() == null || cbt.getType().equals(ArgumentType.STRING)) {

http://git-wip-us.apache.org/repos/asf/cxf-fediz/blob/5966160a/plugins/core/src/main/java/org/apache/cxf/fediz/core/config/SAMLProtocol.java
----------------------------------------------------------------------
diff --git a/plugins/core/src/main/java/org/apache/cxf/fediz/core/config/SAMLProtocol.java b/plugins/core/src/main/java/org/apache/cxf/fediz/core/config/SAMLProtocol.java
index adeb1f6..ee59a70 100644
--- a/plugins/core/src/main/java/org/apache/cxf/fediz/core/config/SAMLProtocol.java
+++ b/plugins/core/src/main/java/org/apache/cxf/fediz/core/config/SAMLProtocol.java
@@ -90,5 +90,21 @@ public class SAMLProtocol extends Protocol {
         this.authnRequestBuilder = authnRequestBuilder;
     }
     
+    public boolean isDisableDeflateEncoding() {
+        return getSAMLProtocol().isDisableDeflateEncoding();
+    }
+
+    public void setDisableDeflateEncoding(boolean disableDeflateEncoding) {
+        getSAMLProtocol().setDisableDeflateEncoding(disableDeflateEncoding);
+    }
+    
+    public boolean isDoNotEnforceKnownIssuer() {
+        return getSAMLProtocol().isDoNotEnforceKnownIssuer();
+    }
+
+    public void setDoNotEnforceKnownIssuer(boolean doNotEnforceKnownIssuer) {
+        getSAMLProtocol().setDoNotEnforceKnownIssuer(doNotEnforceKnownIssuer);
+    }
+    
     
 }

http://git-wip-us.apache.org/repos/asf/cxf-fediz/blob/5966160a/plugins/core/src/main/java/org/apache/cxf/fediz/core/processor/SAMLProcessorImpl.java
----------------------------------------------------------------------
diff --git a/plugins/core/src/main/java/org/apache/cxf/fediz/core/processor/SAMLProcessorImpl.java b/plugins/core/src/main/java/org/apache/cxf/fediz/core/processor/SAMLProcessorImpl.java
index 304b6cb..0bb1fd8 100644
--- a/plugins/core/src/main/java/org/apache/cxf/fediz/core/processor/SAMLProcessorImpl.java
+++ b/plugins/core/src/main/java/org/apache/cxf/fediz/core/processor/SAMLProcessorImpl.java
@@ -19,6 +19,7 @@
 
 package org.apache.cxf.fediz.core.processor;
 
+import java.io.ByteArrayInputStream;
 import java.io.IOException;
 import java.io.InputStream;
 import java.net.URLEncoder;
@@ -126,13 +127,17 @@ public class SAMLProcessorImpl extends AbstractFedizProcessor {
         InputStream tokenStream = null;
         try {
             byte[] deflatedToken = Base64.decode(request.getResponseToken());
-            tokenStream = CompressionUtils.inflate(deflatedToken); 
+            if (protocol.isDisableDeflateEncoding()) {
+                tokenStream = new ByteArrayInputStream(deflatedToken);
+            } else {
+                tokenStream = CompressionUtils.inflate(deflatedToken);
+            }
         } catch (DataFormatException ex) {
             throw new ProcessingException(TYPE.INVALID_REQUEST);
         } catch (Base64DecodingException e) {
             throw new ProcessingException(TYPE.INVALID_REQUEST);
         }
-
+        
         Document doc = null;
         Element el = null;
         try {
@@ -247,12 +252,15 @@ public class SAMLProcessorImpl extends AbstractFedizProcessor {
             String requestURL = request.getRequestURL().toString();
             ssoResponseValidator.setAssertionConsumerURL(requestURL);
             ssoResponseValidator.setClientAddress(request.getRemoteAddr());
+            
+            boolean doNotEnforceKnownIssuer = 
+                ((SAMLProtocol)config.getProtocol()).isDoNotEnforceKnownIssuer();
+            ssoResponseValidator.setEnforceKnownIssuer(!doNotEnforceKnownIssuer);
 
             ssoResponseValidator.setIssuerIDP(requestState.getIdpServiceAddress());
             ssoResponseValidator.setRequestId(requestState.getRequestId());
             ssoResponseValidator.setSpIdentifier(requestState.getIssuerId());
             ssoResponseValidator.setEnforceAssertionsSigned(true);
-            ssoResponseValidator.setEnforceKnownIssuer(true);
             ssoResponseValidator.setReplayCache(config.getTokenReplayCache());
 
             return ssoResponseValidator.validateSamlResponse(samlResponse, false);

http://git-wip-us.apache.org/repos/asf/cxf-fediz/blob/5966160a/plugins/core/src/main/java/org/apache/cxf/fediz/core/samlsso/SAMLSSOResponseValidator.java
----------------------------------------------------------------------
diff --git a/plugins/core/src/main/java/org/apache/cxf/fediz/core/samlsso/SAMLSSOResponseValidator.java b/plugins/core/src/main/java/org/apache/cxf/fediz/core/samlsso/SAMLSSOResponseValidator.java
index 92cf01d..86bb005 100644
--- a/plugins/core/src/main/java/org/apache/cxf/fediz/core/samlsso/SAMLSSOResponseValidator.java
+++ b/plugins/core/src/main/java/org/apache/cxf/fediz/core/samlsso/SAMLSSOResponseValidator.java
@@ -245,7 +245,8 @@ public class SAMLSSOResponseValidator {
         
         // InResponseTo must match the AuthnRequest request Id
         if (requestId != null && !requestId.equals(subjectConfData.getInResponseTo())) {
-            LOG.debug("The InResponseTo String does match the original request id " + requestId);
+            LOG.debug("The InResponseTo String " + subjectConfData.getInResponseTo() 
+                     + " does match the original request id " + requestId);
             throw new WSSecurityException(WSSecurityException.ErrorCode.FAILURE, "invalidSAMLsecurity");
         }
         

http://git-wip-us.apache.org/repos/asf/cxf-fediz/blob/5966160a/plugins/core/src/main/resources/schemas/FedizConfig.xsd
----------------------------------------------------------------------
diff --git a/plugins/core/src/main/resources/schemas/FedizConfig.xsd b/plugins/core/src/main/resources/schemas/FedizConfig.xsd
index 4d4c1f9..d26ad25 100644
--- a/plugins/core/src/main/resources/schemas/FedizConfig.xsd
+++ b/plugins/core/src/main/resources/schemas/FedizConfig.xsd
@@ -111,6 +111,8 @@
 				<xs:sequence>
 					<xs:element ref="signRequest" />
 					<xs:element ref="authnRequestBuilder"/>
+					<xs:element ref="disableDeflateEncoding"/>
+					<xs:element ref="doNotEnforceKnownIssuer"/>
 				</xs:sequence>
 				<xs:attribute name="version" use="required" type="xs:string" />
 			</xs:extension>
@@ -125,6 +127,8 @@
 
 	<xs:element name="signRequest" type="xs:boolean" />
 	<xs:element name="authnRequestBuilder" type="xs:string" />
+	<xs:element name="disableDeflateEncoding" type="xs:boolean"/>
+	<xs:element name="doNotEnforceKnownIssuer" type="xs:boolean"/>
 	
 	<xs:complexType name="protocolType" abstract="true">
 	    <xs:sequence>

http://git-wip-us.apache.org/repos/asf/cxf-fediz/blob/5966160a/plugins/core/src/test/java/org/apache/cxf/fediz/core/samlsso/SAMLResponseConformanceTest.java
----------------------------------------------------------------------
diff --git a/plugins/core/src/test/java/org/apache/cxf/fediz/core/samlsso/SAMLResponseConformanceTest.java b/plugins/core/src/test/java/org/apache/cxf/fediz/core/samlsso/SAMLResponseConformanceTest.java
index 08c3090..1c698c6 100644
--- a/plugins/core/src/test/java/org/apache/cxf/fediz/core/samlsso/SAMLResponseConformanceTest.java
+++ b/plugins/core/src/test/java/org/apache/cxf/fediz/core/samlsso/SAMLResponseConformanceTest.java
@@ -41,6 +41,7 @@ import org.apache.cxf.fediz.core.RequestState;
 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;
@@ -974,6 +975,146 @@ public class SAMLResponseConformanceTest {
         }
     }
     
+    @org.junit.Test
+    public void testIssuerEnforcementFailure() throws Exception {
+        // Mock up a Request
+        FedizContext config = getFederationConfigurator().getFedizContext("ROOT");
+        
+        String requestId = URLEncoder.encode(UUID.randomUUID().toString(), "UTF-8");
+        
+        String relayState = 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,
+                                                     relayState,
+                                                     System.currentTimeMillis());
+        
+        // Create SAML Response
+        SAML2CallbackHandler callbackHandler = new SAML2CallbackHandler();
+        callbackHandler.setAlsoAddAuthnStatement(true);
+        callbackHandler.setStatement(SAML2CallbackHandler.Statement.ATTR);
+        callbackHandler.setConfirmationMethod(SAML2Constants.CONF_BEARER);
+        callbackHandler.setIssuer(TEST_IDP_ISSUER + "/other-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);
+        
+        Issuer issuer =
+            SAML2PResponseComponentBuilder.createIssuer(assertion.getIssuerString());
+        
+        Element response = createSamlResponse(assertion, "mystskey", true, requestId, issuer);
+        String responseStr = encodeResponse(response);
+        
+        HttpServletRequest req = EasyMock.createMock(HttpServletRequest.class);
+        EasyMock.expect(req.getRequestURL()).andReturn(new StringBuffer(TEST_REQUEST_URL));
+        EasyMock.expect(req.getRemoteAddr()).andReturn(TEST_CLIENT_ADDRESS);
+        EasyMock.replay(req);
+        
+        FedizRequest wfReq = new FedizRequest();
+        wfReq.setResponseToken(responseStr);
+        wfReq.setState(relayState);
+        wfReq.setRequest(req);
+        wfReq.setRequestState(requestState);
+        
+        // Failure expected on an unknown issuer value
+        FedizProcessor wfProc = new SAMLProcessorImpl();
+        try {
+            wfProc.processRequest(wfReq, config);
+            fail("Failure expected");
+        } catch (ProcessingException ex) {
+            if (!TYPE.INVALID_REQUEST.equals(ex.getType())) {
+                fail("Expected ProcessingException with INVALID_REQUEST type");
+            }
+        }
+    }
+    
+    @org.junit.Test
+    public void testIssuerEnforcementDisable() throws Exception {
+        // Mock up a Request
+        FedizContext config = getFederationConfigurator().getFedizContext("ROOT");
+        
+        String requestId = URLEncoder.encode(UUID.randomUUID().toString(), "UTF-8");
+        
+        String relayState = 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,
+                                                     relayState,
+                                                     System.currentTimeMillis());
+        
+        // Create SAML Response
+        SAML2CallbackHandler callbackHandler = new SAML2CallbackHandler();
+        callbackHandler.setAlsoAddAuthnStatement(true);
+        callbackHandler.setStatement(SAML2CallbackHandler.Statement.ATTR);
+        callbackHandler.setConfirmationMethod(SAML2Constants.CONF_BEARER);
+        callbackHandler.setIssuer(TEST_IDP_ISSUER + "/other-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);
+        
+        Issuer issuer =
+            SAML2PResponseComponentBuilder.createIssuer(assertion.getIssuerString());
+        
+        Element response = createSamlResponse(assertion, "mystskey", true, requestId, issuer);
+        String responseStr = encodeResponse(response);
+        
+        HttpServletRequest req = EasyMock.createMock(HttpServletRequest.class);
+        EasyMock.expect(req.getRequestURL()).andReturn(new StringBuffer(TEST_REQUEST_URL));
+        EasyMock.expect(req.getRemoteAddr()).andReturn(TEST_CLIENT_ADDRESS);
+        EasyMock.replay(req);
+        
+        FedizRequest wfReq = new FedizRequest();
+        wfReq.setResponseToken(responseStr);
+        wfReq.setState(relayState);
+        wfReq.setRequest(req);
+        wfReq.setRequestState(requestState);
+        
+        // Disable the issuer enforcement check
+        FedizProcessor wfProc = new SAMLProcessorImpl();
+        ((SAMLProtocol)config.getProtocol()).setDoNotEnforceKnownIssuer(true);
+        Assert.assertTrue(((SAMLProtocol)config.getProtocol()).isDoNotEnforceKnownIssuer());
+        FedizResponse wfRes = wfProc.processRequest(wfReq, config);
+        Assert.assertEquals("Principal name wrong", TEST_USER, wfRes.getUsername());
+        
+    }
     
     private Element createSamlResponse(SamlAssertionWrapper assertion, String alias, 
                                       boolean sign, String requestID, Issuer issuer)

http://git-wip-us.apache.org/repos/asf/cxf-fediz/blob/5966160a/systests/tests/src/test/java/org/apache/cxf/fediz/integrationtests/AbstractTests.java
----------------------------------------------------------------------
diff --git a/systests/tests/src/test/java/org/apache/cxf/fediz/integrationtests/AbstractTests.java b/systests/tests/src/test/java/org/apache/cxf/fediz/integrationtests/AbstractTests.java
index 0892d9e..af799f5 100644
--- a/systests/tests/src/test/java/org/apache/cxf/fediz/integrationtests/AbstractTests.java
+++ b/systests/tests/src/test/java/org/apache/cxf/fediz/integrationtests/AbstractTests.java
@@ -313,7 +313,7 @@ public abstract class AbstractTests {
 
         final XmlPage rpPage = webClient.getPage(url);
         final String xmlContent = rpPage.asXml();
-        Assert.assertTrue(xmlContent.startsWith("<EntityDescriptor"));
+        Assert.assertTrue(xmlContent.startsWith("<md:EntityDescriptor"));
         
         // Now validate the Signature
         Document doc = rpPage.getXmlDocument();