ws-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From cohei...@apache.org
Subject svn commit: r1652389 - in /webservices/wss4j/trunk: ws-security-common/src/main/java/org/apache/wss4j/common/saml/ ws-security-dom/src/main/java/org/apache/wss4j/dom/handler/ ws-security-dom/src/main/java/org/apache/wss4j/dom/validate/ ws-security-dom/...
Date Fri, 16 Jan 2015 11:15:39 GMT
Author: coheigea
Date: Fri Jan 16 11:15:39 2015
New Revision: 1652389

URL: http://svn.apache.org/r1652389
Log:
[WSS-523] - Add the ability to supply AudienceRestrictions when validating SAML tokens - DOM
part

Modified:
    webservices/wss4j/trunk/ws-security-common/src/main/java/org/apache/wss4j/common/saml/SamlAssertionWrapper.java
    webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/wss4j/dom/handler/RequestData.java
    webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/wss4j/dom/validate/SamlAssertionValidator.java
    webservices/wss4j/trunk/ws-security-dom/src/test/java/org/apache/wss4j/dom/saml/SamlConditionsTest.java

Modified: webservices/wss4j/trunk/ws-security-common/src/main/java/org/apache/wss4j/common/saml/SamlAssertionWrapper.java
URL: http://svn.apache.org/viewvc/webservices/wss4j/trunk/ws-security-common/src/main/java/org/apache/wss4j/common/saml/SamlAssertionWrapper.java?rev=1652389&r1=1652388&r2=1652389&view=diff
==============================================================================
--- webservices/wss4j/trunk/ws-security-common/src/main/java/org/apache/wss4j/common/saml/SamlAssertionWrapper.java
(original)
+++ webservices/wss4j/trunk/ws-security-common/src/main/java/org/apache/wss4j/common/saml/SamlAssertionWrapper.java
Fri Jan 16 11:15:39 2015
@@ -821,6 +821,65 @@ public class SamlAssertionWrapper {
                 throw new WSSecurityException(WSSecurityException.ErrorCode.FAILURE, "invalidSAMLsecurity");
             }
         }
+        
+    }
+    
+    /**
+     * Check the AudienceRestrictions of the Assertion
+     */
+    public void checkAudienceRestrictions(List<String> audienceRestrictions) throws
WSSecurityException {
+        // Now check the audience restriction conditions
+        if (audienceRestrictions == null || audienceRestrictions.isEmpty()) {
+            return;
+        }
+        
+        if (getSamlVersion().equals(SAMLVersion.VERSION_20) && getSaml2().getConditions()
!= null) {
+            org.opensaml.saml2.core.Conditions conditions = getSaml2().getConditions();
+            if (conditions != null && conditions.getAudienceRestrictions() != null)
{
+                boolean foundAddress = false;
+                for (org.opensaml.saml2.core.AudienceRestriction audienceRestriction 
+                    : conditions.getAudienceRestrictions()) {
+                    if (audienceRestriction.getAudiences() != null) {
+                        List<org.opensaml.saml2.core.Audience> audiences = 
+                            audienceRestriction.getAudiences();
+                        for (org.opensaml.saml2.core.Audience audience : audiences) {
+                            String audienceURI = audience.getAudienceURI();
+                            if (audienceRestrictions.contains(audienceURI)) {
+                                foundAddress = true;
+                                break;
+                            }
+                        }
+                    }
+                }
+                
+                if (!foundAddress) {
+                    throw new WSSecurityException(WSSecurityException.ErrorCode.FAILURE,
"invalidSAMLsecurity");
+                }
+            }
+        } else if (getSamlVersion().equals(SAMLVersion.VERSION_11) && getSaml1().getConditions()
!= null) {
+            org.opensaml.saml1.core.Conditions conditions = getSaml1().getConditions();
+            if (conditions != null && conditions.getAudienceRestrictionConditions()
!= null) {
+                boolean foundAddress = false;
+                for (org.opensaml.saml1.core.AudienceRestrictionCondition audienceRestriction

+                    : conditions.getAudienceRestrictionConditions()) {
+                    if (audienceRestriction.getAudiences() != null) {
+                        List<org.opensaml.saml1.core.Audience> audiences = 
+                            audienceRestriction.getAudiences();
+                        for (org.opensaml.saml1.core.Audience audience : audiences) {
+                            String audienceURI = audience.getUri();
+                            if (audienceRestrictions.contains(audienceURI)) {
+                                foundAddress = true;
+                                break;
+                            }
+                        }
+                    }
+                }
+                
+                if (!foundAddress) {
+                    throw new WSSecurityException(WSSecurityException.ErrorCode.FAILURE,
"invalidSAMLsecurity");
+                }
+            }
+        }
     }
     
     /**

Modified: webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/wss4j/dom/handler/RequestData.java
URL: http://svn.apache.org/viewvc/webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/wss4j/dom/handler/RequestData.java?rev=1652389&r1=1652388&r2=1652389&view=diff
==============================================================================
--- webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/wss4j/dom/handler/RequestData.java
(original)
+++ webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/wss4j/dom/handler/RequestData.java
Fri Jan 16 11:15:39 2015
@@ -93,6 +93,7 @@ public class RequestData {
     private PasswordEncryptor passwordEncryptor;
     private String derivedKeyTokenReference;
     private boolean use200512Namespace = true;
+    private final List<String> audienceRestrictions = new ArrayList<String>();
 
     public void clear() {
         soapConstants = null;
@@ -127,6 +128,7 @@ public class RequestData {
         passwordEncryptor = null;
         derivedKeyTokenReference = null;
         setUse200512Namespace(true);
+        audienceRestrictions.clear();
     }
 
     public boolean isEnableTimestampReplayCache() {
@@ -427,6 +429,22 @@ public class RequestData {
         return subjectDNPatterns;
     }
     
+    /**
+     * Set the Audience Restrictions
+     */
+    public void setAudienceRestrictions(List<String> audienceRestrictions) {
+        if (audienceRestrictions != null) {
+            this.audienceRestrictions.addAll(audienceRestrictions);
+        }
+    }
+    
+    /**
+     * Get the Audience Restrictions
+     */
+    public List<String> getAudienceRestrictions() {
+        return audienceRestrictions;
+    }
+    
     public void setIgnoredBSPRules(List<BSPRule> bspRules) {
         ignoredBSPRules.clear();
         ignoredBSPRules.addAll(bspRules);

Modified: webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/wss4j/dom/validate/SamlAssertionValidator.java
URL: http://svn.apache.org/viewvc/webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/wss4j/dom/validate/SamlAssertionValidator.java?rev=1652389&r1=1652388&r2=1652389&view=diff
==============================================================================
--- webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/wss4j/dom/validate/SamlAssertionValidator.java
(original)
+++ webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/wss4j/dom/validate/SamlAssertionValidator.java
Fri Jan 16 11:15:39 2015
@@ -100,7 +100,7 @@ public class SamlAssertionValidator exte
         verifySubjectConfirmationMethod(samlAssertion);
         
         // Check conditions
-        checkConditions(samlAssertion);
+        checkConditions(samlAssertion, data.getAudienceRestrictions());
         
         // Check the AuthnStatements of the assertion (if any)
         checkAuthnStatements(samlAssertion);
@@ -208,6 +208,16 @@ public class SamlAssertionValidator exte
     }
     
     /**
+     * Check the Conditions of the Assertion.
+     */
+    protected void checkConditions(
+        SamlAssertionWrapper samlAssertion, List<String> audienceRestrictions
+    ) throws WSSecurityException {
+        checkConditions(samlAssertion);
+        samlAssertion.checkAudienceRestrictions(audienceRestrictions);
+    }
+    
+    /**
      * Check the Conditions of the Assertion.
      */
     protected void checkConditions(SamlAssertionWrapper samlAssertion) throws WSSecurityException
{

Modified: webservices/wss4j/trunk/ws-security-dom/src/test/java/org/apache/wss4j/dom/saml/SamlConditionsTest.java
URL: http://svn.apache.org/viewvc/webservices/wss4j/trunk/ws-security-dom/src/test/java/org/apache/wss4j/dom/saml/SamlConditionsTest.java?rev=1652389&r1=1652388&r2=1652389&view=diff
==============================================================================
--- webservices/wss4j/trunk/ws-security-dom/src/test/java/org/apache/wss4j/dom/saml/SamlConditionsTest.java
(original)
+++ webservices/wss4j/trunk/ws-security-dom/src/test/java/org/apache/wss4j/dom/saml/SamlConditionsTest.java
Fri Jan 16 11:15:39 2015
@@ -41,6 +41,7 @@ import org.apache.wss4j.dom.common.SAML1
 import org.apache.wss4j.dom.common.SAML2CallbackHandler;
 import org.apache.wss4j.dom.common.SOAPUtil;
 import org.apache.wss4j.dom.common.SecurityTestUtil;
+import org.apache.wss4j.dom.handler.RequestData;
 import org.apache.wss4j.dom.message.WSSecHeader;
 import org.apache.wss4j.dom.message.WSSecSAMLToken;
 import org.joda.time.DateTime;
@@ -335,6 +336,132 @@ public class SamlConditionsTest extends
         verify(unsignedDoc);
     }
     
+    // Now test AudienceRestrictions with supplied restrictions
+    @org.junit.Test
+    public void testSAML2AudienceRestrictionVerification() throws Exception {
+        SAML2CallbackHandler callbackHandler = new SAML2CallbackHandler();
+        callbackHandler.setStatement(SAML2CallbackHandler.Statement.AUTHN);
+        callbackHandler.setIssuer("www.example.com");
+        
+        ConditionsBean conditions = new ConditionsBean();
+        conditions.setTokenPeriodMinutes(5);
+        List<String> audiences = new ArrayList<String>();
+        audiences.add("http://apache.org/one");
+        audiences.add("http://apache.org/two");
+        AudienceRestrictionBean audienceRestrictionBean = new AudienceRestrictionBean();
+        audienceRestrictionBean.setAudienceURIs(audiences);
+        conditions.setAudienceRestrictions(Collections.singletonList(audienceRestrictionBean));
+        
+        callbackHandler.setConditions(conditions);
+        
+        SAMLCallback samlCallback = new SAMLCallback();
+        SAMLUtil.doSAMLCallback(callbackHandler, samlCallback);
+        SamlAssertionWrapper samlAssertion = new SamlAssertionWrapper(samlCallback);
+
+        WSSecSAMLToken wsSign = new WSSecSAMLToken();
+
+        Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
+        WSSecHeader secHeader = new WSSecHeader();
+        secHeader.insertSecurityHeader(doc);
+        
+        Document unsignedDoc = wsSign.build(doc, samlAssertion, secHeader);
+
+        String outputString = 
+            XMLUtils.PrettyDocumentToString(unsignedDoc);
+        assertTrue(outputString.contains("AudienceRestriction"));
+        if (LOG.isDebugEnabled()) {
+            LOG.debug(outputString);
+        }
+        
+        // This should fail as the expected audience isn't in the assertion
+        audiences.clear();
+        audiences.add("http://apache.org/three");
+     
+        WSSecurityEngine newEngine = new WSSecurityEngine();
+        RequestData data = new RequestData();
+        data.setAudienceRestrictions(audiences);
+        
+        WSSConfig config = WSSConfig.getNewInstance();
+        config.setValidateSamlSubjectConfirmation(false);
+        newEngine.setWssConfig(config);
+        
+        try {
+            newEngine.processSecurityHeader(doc, "", data);
+            fail("Failure expected on a bad audience restriction");
+        } catch (WSSecurityException ex) {
+            // expected
+        }
+        
+        // Now add the correct audience back in...
+        audiences.add("http://apache.org/one");
+        data.setAudienceRestrictions(audiences);
+        
+        newEngine.processSecurityHeader(doc, "", data);
+    }
+    
+    // Now test AudienceRestrictions with supplied restrictions
+    @org.junit.Test
+    public void testSAML1AudienceRestrictionVerification() throws Exception {
+        SAML1CallbackHandler callbackHandler = new SAML1CallbackHandler();
+        callbackHandler.setStatement(SAML1CallbackHandler.Statement.AUTHN);
+        callbackHandler.setIssuer("www.example.com");
+        
+        ConditionsBean conditions = new ConditionsBean();
+        conditions.setTokenPeriodMinutes(5);
+        List<String> audiences = new ArrayList<String>();
+        audiences.add("http://apache.org/one");
+        audiences.add("http://apache.org/two");
+        AudienceRestrictionBean audienceRestrictionBean = new AudienceRestrictionBean();
+        audienceRestrictionBean.setAudienceURIs(audiences);
+        conditions.setAudienceRestrictions(Collections.singletonList(audienceRestrictionBean));
+        
+        callbackHandler.setConditions(conditions);
+        
+        SAMLCallback samlCallback = new SAMLCallback();
+        SAMLUtil.doSAMLCallback(callbackHandler, samlCallback);
+        SamlAssertionWrapper samlAssertion = new SamlAssertionWrapper(samlCallback);
+
+        WSSecSAMLToken wsSign = new WSSecSAMLToken();
+
+        Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
+        WSSecHeader secHeader = new WSSecHeader();
+        secHeader.insertSecurityHeader(doc);
+        
+        Document unsignedDoc = wsSign.build(doc, samlAssertion, secHeader);
+
+        String outputString = 
+            XMLUtils.PrettyDocumentToString(unsignedDoc);
+        assertTrue(outputString.contains("AudienceRestriction"));
+        if (LOG.isDebugEnabled()) {
+            LOG.debug(outputString);
+        }
+        
+        // This should fail as the expected audience isn't in the assertion
+        audiences.clear();
+        audiences.add("http://apache.org/three");
+     
+        WSSecurityEngine newEngine = new WSSecurityEngine();
+        RequestData data = new RequestData();
+        data.setAudienceRestrictions(audiences);
+        
+        WSSConfig config = WSSConfig.getNewInstance();
+        config.setValidateSamlSubjectConfirmation(false);
+        newEngine.setWssConfig(config);
+        
+        try {
+            newEngine.processSecurityHeader(doc, "", data);
+            fail("Failure expected on a bad audience restriction");
+        } catch (WSSecurityException ex) {
+            // expected
+        }
+        
+        // Now add the correct audience back in...
+        audiences.add("http://apache.org/one");
+        data.setAudienceRestrictions(audiences);
+        
+        newEngine.processSecurityHeader(doc, "", data);
+    }
+    
     /**
      * Test that creates, sends and processes an unsigned SAML 2 authentication assertion
      * with two AudienceRestriction Elements
@@ -384,6 +511,75 @@ public class SamlConditionsTest extends
         verify(unsignedDoc);
     }
     
+    // Now test AudienceRestrictions with supplied restrictions
+    @org.junit.Test
+    public void testSAML2AudienceRestrictionSeparateRestrictionsValidation() throws Exception
{
+        SAML2CallbackHandler callbackHandler = new SAML2CallbackHandler();
+        callbackHandler.setStatement(SAML2CallbackHandler.Statement.AUTHN);
+        callbackHandler.setIssuer("www.example.com");
+        
+        ConditionsBean conditions = new ConditionsBean();
+        conditions.setTokenPeriodMinutes(5);
+        
+        List<AudienceRestrictionBean> audiencesRestrictions = 
+            new ArrayList<AudienceRestrictionBean>();
+        AudienceRestrictionBean audienceRestrictionBean = new AudienceRestrictionBean();
+        audienceRestrictionBean.setAudienceURIs(Collections.singletonList("http://apache.org/one"));
+        audiencesRestrictions.add(audienceRestrictionBean);
+        
+        audienceRestrictionBean = new AudienceRestrictionBean();
+        audienceRestrictionBean.setAudienceURIs(Collections.singletonList("http://apache.org/two"));
+        audiencesRestrictions.add(audienceRestrictionBean);
+        
+        conditions.setAudienceRestrictions(audiencesRestrictions);
+        
+        callbackHandler.setConditions(conditions);
+        
+        SAMLCallback samlCallback = new SAMLCallback();
+        SAMLUtil.doSAMLCallback(callbackHandler, samlCallback);
+        SamlAssertionWrapper samlAssertion = new SamlAssertionWrapper(samlCallback);
+
+        WSSecSAMLToken wsSign = new WSSecSAMLToken();
+
+        Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
+        WSSecHeader secHeader = new WSSecHeader();
+        secHeader.insertSecurityHeader(doc);
+        
+        Document unsignedDoc = wsSign.build(doc, samlAssertion, secHeader);
+
+        String outputString = 
+            XMLUtils.PrettyDocumentToString(unsignedDoc);
+        assertTrue(outputString.contains("AudienceRestriction"));
+        if (LOG.isDebugEnabled()) {
+            LOG.debug(outputString);
+        }
+        
+        // This should fail as the expected audience isn't in the assertion
+        List<String> audiences = new ArrayList<String>();
+        audiences.add("http://apache.org/three");
+     
+        WSSecurityEngine newEngine = new WSSecurityEngine();
+        RequestData data = new RequestData();
+        data.setAudienceRestrictions(audiences);
+        
+        WSSConfig config = WSSConfig.getNewInstance();
+        config.setValidateSamlSubjectConfirmation(false);
+        newEngine.setWssConfig(config);
+        
+        try {
+            newEngine.processSecurityHeader(doc, "", data);
+            fail("Failure expected on a bad audience restriction");
+        } catch (WSSecurityException ex) {
+            // expected
+        }
+        
+        // Now add the correct audience back in...
+        audiences.add("http://apache.org/one");
+        data.setAudienceRestrictions(audiences);
+        
+        newEngine.processSecurityHeader(doc, "", data);
+    }
+    
     private void createAndVerifyMessage(
         CallbackHandler samlCallbackHandler, boolean success
     ) throws Exception {



Mime
View raw message