You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ws.apache.org by co...@apache.org on 2013/09/17 17:52:42 UTC

svn commit: r1524103 - in /webservices/wss4j/trunk: ws-security-common/src/main/java/org/apache/wss4j/common/saml/bean/ ws-security-common/src/main/java/org/apache/wss4j/common/saml/builder/ ws-security-dom/src/test/java/org/apache/wss4j/dom/saml/

Author: coheigea
Date: Tue Sep 17 15:52:41 2013
New Revision: 1524103

URL: http://svn.apache.org/r1524103
Log:
[WSS-477] - Support the ability to create SAML2 Assertions with OneTimeUse + ProxyRestriction Conditions

Added:
    webservices/wss4j/trunk/ws-security-common/src/main/java/org/apache/wss4j/common/saml/bean/ProxyRestrictionBean.java
Modified:
    webservices/wss4j/trunk/ws-security-common/src/main/java/org/apache/wss4j/common/saml/bean/ConditionsBean.java
    webservices/wss4j/trunk/ws-security-common/src/main/java/org/apache/wss4j/common/saml/builder/SAML2ComponentBuilder.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/bean/ConditionsBean.java
URL: http://svn.apache.org/viewvc/webservices/wss4j/trunk/ws-security-common/src/main/java/org/apache/wss4j/common/saml/bean/ConditionsBean.java?rev=1524103&r1=1524102&r2=1524103&view=diff
==============================================================================
--- webservices/wss4j/trunk/ws-security-common/src/main/java/org/apache/wss4j/common/saml/bean/ConditionsBean.java (original)
+++ webservices/wss4j/trunk/ws-security-common/src/main/java/org/apache/wss4j/common/saml/bean/ConditionsBean.java Tue Sep 17 15:52:41 2013
@@ -31,6 +31,8 @@ public class ConditionsBean {
     private DateTime notAfter;
     private int tokenPeriodMinutes;
     private String audienceURI;
+    private boolean oneTimeUse;
+    private ProxyRestrictionBean proxyRestriction;
 
     /**
      * Constructor ConditionsBean creates a new ConditionsBean instance.
@@ -136,6 +138,30 @@ public class ConditionsBean {
     }
 
     /**
+     * Get whether to include a OneTimeUse Element or not. Only applies to SAML2.
+     * @return whether to include a OneTimeUse Element or not.
+     */
+    public boolean isOneTimeUse() {
+        return oneTimeUse;
+    }
+
+    /**
+     * Set whether to include a OneTimeUse Element or not. Only applies to SAML2.
+     * @param oneTimeUse whether to include a OneTimeUse Element or not.
+     */
+    public void setOneTimeUse(boolean oneTimeUse) {
+        this.oneTimeUse = oneTimeUse;
+    }
+    
+    public ProxyRestrictionBean getProxyRestriction() {
+        return proxyRestriction;
+    }
+
+    public void setProxyRestriction(ProxyRestrictionBean proxyRestriction) {
+        this.proxyRestriction = proxyRestriction;
+    }
+    
+    /**
      * Method equals ...
      *
      * @param o of type Object
@@ -167,6 +193,15 @@ public class ConditionsBean {
         } else if (audienceURI != null && !audienceURI.equals(that.audienceURI)) {
             return false; 
         }
+        
+        if (oneTimeUse != that.oneTimeUse) return false;
+        
+        if (proxyRestriction == null && that.proxyRestriction != null) {
+            return false;
+        } else if (proxyRestriction != null 
+            && !proxyRestriction.equals(that.proxyRestriction)) {
+            return false; 
+        }
 
         return true;
     }
@@ -186,6 +221,11 @@ public class ConditionsBean {
         if (audienceURI != null) {
             result = 31 * result + audienceURI.hashCode();
         }
+        result = 31 * result + (oneTimeUse ? 1 : 0);
+        if (proxyRestriction != null) {
+            result = 31 * result + proxyRestriction.hashCode();
+        }
         return result;
     }
+
 }

Added: webservices/wss4j/trunk/ws-security-common/src/main/java/org/apache/wss4j/common/saml/bean/ProxyRestrictionBean.java
URL: http://svn.apache.org/viewvc/webservices/wss4j/trunk/ws-security-common/src/main/java/org/apache/wss4j/common/saml/bean/ProxyRestrictionBean.java?rev=1524103&view=auto
==============================================================================
--- webservices/wss4j/trunk/ws-security-common/src/main/java/org/apache/wss4j/common/saml/bean/ProxyRestrictionBean.java (added)
+++ webservices/wss4j/trunk/ws-security-common/src/main/java/org/apache/wss4j/common/saml/bean/ProxyRestrictionBean.java Tue Sep 17 15:52:41 2013
@@ -0,0 +1,103 @@
+/**
+ * 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.wss4j.common.saml.bean;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Class ProxyRestrictionBean represents a SAML 2.0 ProxyRestrictionBean object
+ */
+public class ProxyRestrictionBean {
+    private int count;
+    private final List<String> audienceURIs = new ArrayList<String>();
+
+    /**
+     * Constructor ProxyRestrictionBean creates a new ProxyRestrictionBean instance.
+     */
+    public ProxyRestrictionBean() {
+    }
+
+    /**
+     * Constructor ProxyRestrictionBean creates a new ProxyRestrictionBean instance.
+     *
+     * @param count The count instance
+     * @param audienceURIs The audienceURI instances
+     */
+    public ProxyRestrictionBean(
+        int count,
+        List<String> audienceURIs
+    ) {
+        this.setCount(count);
+        if (audienceURIs != null) {
+            this.audienceURIs.addAll(audienceURIs);
+        }
+    }
+    
+    /**
+     * Get the audienceURI instances
+     *
+     * @return the audienceURI instances
+     */
+    public List<String> getAudienceURIs() {
+        return audienceURIs;
+    }
+
+    public int getCount() {
+        return count;
+    }
+
+    public void setCount(int count) {
+        this.count = count;
+    }
+
+    /**
+     * Method equals ...
+     *
+     * @param o of type Object
+     * @return boolean
+     */
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (!(o instanceof ProxyRestrictionBean)) return false;
+
+        ProxyRestrictionBean that = (ProxyRestrictionBean) o;
+
+        if (count != that.count) return false;
+        
+        if (!audienceURIs.equals(that.audienceURIs)) {
+            return false; 
+        }
+        
+        return true;
+    }
+
+    /**
+     * @return the hashcode of this object
+     */
+    @Override
+    public int hashCode() {
+        int result = count;
+        result = 31 * result + audienceURIs.hashCode();
+        return result;
+    }
+
+}

Modified: webservices/wss4j/trunk/ws-security-common/src/main/java/org/apache/wss4j/common/saml/builder/SAML2ComponentBuilder.java
URL: http://svn.apache.org/viewvc/webservices/wss4j/trunk/ws-security-common/src/main/java/org/apache/wss4j/common/saml/builder/SAML2ComponentBuilder.java?rev=1524103&r1=1524102&r2=1524103&view=diff
==============================================================================
--- webservices/wss4j/trunk/ws-security-common/src/main/java/org/apache/wss4j/common/saml/builder/SAML2ComponentBuilder.java (original)
+++ webservices/wss4j/trunk/ws-security-common/src/main/java/org/apache/wss4j/common/saml/builder/SAML2ComponentBuilder.java Tue Sep 17 15:52:41 2013
@@ -27,16 +27,15 @@ import org.apache.wss4j.common.saml.bean
 import org.apache.wss4j.common.saml.bean.AuthenticationStatementBean;
 import org.apache.wss4j.common.saml.bean.ConditionsBean;
 import org.apache.wss4j.common.saml.bean.KeyInfoBean;
+import org.apache.wss4j.common.saml.bean.ProxyRestrictionBean;
 import org.apache.wss4j.common.saml.bean.SubjectBean;
 import org.apache.wss4j.common.saml.bean.SubjectConfirmationDataBean;
 import org.apache.wss4j.common.saml.bean.SubjectLocalityBean;
 import org.apache.xml.security.stax.impl.util.IDGenerator;
-
 import org.joda.time.DateTime;
 import org.opensaml.Configuration;
 import org.opensaml.common.SAMLObjectBuilder;
 import org.opensaml.common.SAMLVersion;
-
 import org.opensaml.saml2.core.Action;
 import org.opensaml.saml2.core.Assertion;
 import org.opensaml.saml2.core.Attribute;
@@ -54,11 +53,12 @@ import org.opensaml.saml2.core.Evidence;
 import org.opensaml.saml2.core.Issuer;
 import org.opensaml.saml2.core.KeyInfoConfirmationDataType;
 import org.opensaml.saml2.core.NameID;
+import org.opensaml.saml2.core.OneTimeUse;
+import org.opensaml.saml2.core.ProxyRestriction;
 import org.opensaml.saml2.core.Subject;
 import org.opensaml.saml2.core.SubjectConfirmation;
 import org.opensaml.saml2.core.SubjectConfirmationData;
 import org.opensaml.saml2.core.SubjectLocality;
-
 import org.opensaml.xml.XMLObject;
 import org.opensaml.xml.XMLObjectBuilderFactory;
 import org.opensaml.xml.schema.XSString;
@@ -68,7 +68,6 @@ import org.opensaml.xml.signature.KeyInf
 import java.util.ArrayList;
 import java.util.List;
 
-
 /**
  * Class SAML2ComponentBuilder provides builder methods that can be used
  * to construct SAML v2.0 statements using the OpenSaml library.
@@ -84,6 +83,10 @@ public final class SAML2ComponentBuilder
     
     private static volatile SAMLObjectBuilder<SubjectConfirmation> subjectConfirmationBuilder;
     
+    private static volatile SAMLObjectBuilder<OneTimeUse> oneTimeUseBuilder;
+    
+    private static volatile SAMLObjectBuilder<ProxyRestriction> proxyRestrictionBuilder;
+    
     private static volatile SAMLObjectBuilder<Conditions> conditionsBuilder;
     
     private static volatile SAMLObjectBuilder<SubjectConfirmationData> subjectConfirmationDataBuilder;
@@ -213,6 +216,13 @@ public final class SAML2ComponentBuilder
             conditions.getAudienceRestrictions().add(audienceRestriction);
         }
         
+        if (conditionsBean.isOneTimeUse()) {
+            conditions.getConditions().add(createOneTimeUse());
+        }
+        
+        if (conditionsBean.getProxyRestriction() != null) {
+            conditions.getConditions().add(createProxyRestriction(conditionsBean.getProxyRestriction()));
+        }
         return conditions;
     }
 
@@ -239,6 +249,53 @@ public final class SAML2ComponentBuilder
         audienceRestriction.getAudiences().add(audience);
         return audienceRestriction;
     }
+    
+    /**
+     * Create a OneTimeUse object
+     *
+     * @return a OneTimeUse object
+     */
+    @SuppressWarnings("unchecked")
+    public static OneTimeUse createOneTimeUse() {
+        if (oneTimeUseBuilder == null) {
+            oneTimeUseBuilder = (SAMLObjectBuilder<OneTimeUse>) 
+                builderFactory.getBuilder(OneTimeUse.DEFAULT_ELEMENT_NAME);
+        }
+       
+        return oneTimeUseBuilder.buildObject();
+    }
+    
+    /**
+     * Create a ProxyRestriction object
+     *
+     * @return a ProxyRestriction object
+     */
+    @SuppressWarnings("unchecked")
+    public static ProxyRestriction createProxyRestriction(ProxyRestrictionBean proxyRestrictionBean) {
+        if (proxyRestrictionBuilder == null) {
+            proxyRestrictionBuilder = (SAMLObjectBuilder<ProxyRestriction>) 
+                builderFactory.getBuilder(ProxyRestriction.DEFAULT_ELEMENT_NAME);
+        }
+        
+        ProxyRestriction proxyRestriction = proxyRestrictionBuilder.buildObject();
+        if (proxyRestrictionBean.getCount() > 0) {
+            proxyRestriction.setProxyCount(proxyRestrictionBean.getCount());
+        }
+        
+        if (!proxyRestrictionBean.getAudienceURIs().isEmpty()) {
+            if (audienceBuilder == null) {
+                audienceBuilder = (SAMLObjectBuilder<Audience>) 
+                    builderFactory.getBuilder(Audience.DEFAULT_ELEMENT_NAME);
+            }
+            for (String audienceURI : proxyRestrictionBean.getAudienceURIs()) {
+                Audience audience = audienceBuilder.buildObject();
+                audience.setAudienceURI(audienceURI);
+                proxyRestriction.getAudiences().add(audience);
+            }
+        }
+        
+        return proxyRestriction;
+    }
 
     /**
      * Create SAML 2 Authentication Statement(s).

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=1524103&r1=1524102&r2=1524103&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 Tue Sep 17 15:52:41 2013
@@ -19,9 +19,16 @@
 
 package org.apache.wss4j.dom.saml;
 
+import java.util.ArrayList;
 import java.util.List;
 
+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.ConditionsBean;
+import org.apache.wss4j.common.saml.bean.ProxyRestrictionBean;
+import org.apache.wss4j.common.util.XMLUtils;
 import org.apache.wss4j.dom.WSConstants;
 import org.apache.wss4j.dom.WSSConfig;
 import org.apache.wss4j.dom.WSSecurityEngine;
@@ -31,11 +38,6 @@ 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.common.ext.WSSecurityException;
-import org.apache.wss4j.common.saml.SAMLCallback;
-import org.apache.wss4j.common.saml.SAMLUtil;
-import org.apache.wss4j.common.saml.bean.ConditionsBean;
-import org.apache.wss4j.common.util.XMLUtils;
 import org.apache.wss4j.dom.message.WSSecHeader;
 import org.apache.wss4j.dom.message.WSSecSAMLToken;
 import org.apache.wss4j.dom.util.WSSecurityUtil;
@@ -233,6 +235,88 @@ public class SamlConditionsTest extends 
     }
     
     /**
+     * Test that creates, sends and processes an unsigned SAML 2 authentication assertion
+     * with a OneTimeUse Element
+     */
+    @org.junit.Test
+    public void testSAML2OneTimeUse() throws Exception {
+        SAML2CallbackHandler callbackHandler = new SAML2CallbackHandler();
+        callbackHandler.setStatement(SAML2CallbackHandler.Statement.AUTHN);
+        callbackHandler.setIssuer("www.example.com");
+        
+        ConditionsBean conditions = new ConditionsBean();
+        conditions.setTokenPeriodMinutes(5);
+        conditions.setOneTimeUse(true);
+            
+        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("OneTimeUse"));
+        if (LOG.isDebugEnabled()) {
+            LOG.debug(outputString);
+        }
+        
+        verify(unsignedDoc);
+    }
+    
+    /**
+     * Test that creates, sends and processes an unsigned SAML 2 authentication assertion
+     * with a ProxyRestriction Element
+     */
+    @org.junit.Test
+    public void testSAML2ProxyRestriction() throws Exception {
+        SAML2CallbackHandler callbackHandler = new SAML2CallbackHandler();
+        callbackHandler.setStatement(SAML2CallbackHandler.Statement.AUTHN);
+        callbackHandler.setIssuer("www.example.com");
+        
+        ConditionsBean conditions = new ConditionsBean();
+        conditions.setTokenPeriodMinutes(5);
+        ProxyRestrictionBean proxyRestriction = new ProxyRestrictionBean();
+        List<String> audiences = new ArrayList<String>();
+        audiences.add("http://apache.org/one");
+        audiences.add("http://apache.org/two");
+        proxyRestriction.getAudienceURIs().addAll(audiences);
+        proxyRestriction.setCount(5);
+        conditions.setProxyRestriction(proxyRestriction);
+        
+        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("ProxyRestriction"));
+        if (LOG.isDebugEnabled()) {
+            LOG.debug(outputString);
+        }
+        
+        verify(unsignedDoc);
+    }
+    
+    /**
      * Verifies the soap envelope
      * <p/>
      *