Author: coheigea
Date: Mon Apr 16 13:11:33 2012
New Revision: 1326597

URL: http://svn.apache.org/viewvc?rev=1326597&view=rev
Log:
Fixed a problem with STS post-dating, and added several unit tests.


Conflicts:

        
services/sts/sts-core/src/main/java/org/apache/cxf/sts/token/provider/DefaultConditionsProvider.java

Modified:
    
cxf/branches/2.5.x-fixes/services/sts/sts-core/src/main/java/org/apache/cxf/sts/token/provider/DefaultConditionsProvider.java
    
cxf/branches/2.5.x-fixes/services/sts/sts-core/src/test/java/org/apache/cxf/sts/token/provider/SAMLProviderLifetimeTest.java

Modified: 
cxf/branches/2.5.x-fixes/services/sts/sts-core/src/main/java/org/apache/cxf/sts/token/provider/DefaultConditionsProvider.java
URL: 
http://svn.apache.org/viewvc/cxf/branches/2.5.x-fixes/services/sts/sts-core/src/main/java/org/apache/cxf/sts/token/provider/DefaultConditionsProvider.java?rev=1326597&r1=1326596&r2=1326597&view=diff
==============================================================================
--- 
cxf/branches/2.5.x-fixes/services/sts/sts-core/src/main/java/org/apache/cxf/sts/token/provider/DefaultConditionsProvider.java
 (original)
+++ 
cxf/branches/2.5.x-fixes/services/sts/sts-core/src/main/java/org/apache/cxf/sts/token/provider/DefaultConditionsProvider.java
 Mon Apr 16 13:11:33 2012
@@ -42,7 +42,23 @@ public class DefaultConditionsProvider i
     private long maxLifetime = DEFAULT_MAX_LIFETIME;
     private boolean failLifetimeExceedance = true;
     private boolean acceptClientLifetime;
+    private long futureTimeToLive = 60L;
     
+    /**
+     * Get how long (in seconds) a client-supplied Created Element is allowed 
to be in the future.
+     * The default is 60 seconds to avoid common problems relating to clock 
skew.
+     */
+    public long getFutureTimeToLive() {
+        return futureTimeToLive;
+    }
+
+    /**
+     * Set how long (in seconds) a client-supplied Created Element is allowed 
to be in the future.
+     * The default is 60 seconds to avoid common problems relating to clock 
skew.
+     */
+    public void setFutureTimeToLive(long futureTimeToLive) {
+        this.futureTimeToLive = futureTimeToLive;
+    }
     
     /**
      * Set the default lifetime in seconds for issued SAML tokens
@@ -117,12 +133,26 @@ public class DefaultConditionsProvider i
         ConditionsBean conditions = new ConditionsBean();
         if (lifetime > 0) {
             Lifetime tokenLifetime = 
providerParameters.getTokenRequirements().getLifetime();
-            if (acceptClientLifetime && tokenLifetime != null) {
+            if (acceptClientLifetime && tokenLifetime != null
+                && tokenLifetime.getCreated() != null && 
tokenLifetime.getExpires() != null) {
                 try {
                     XmlSchemaDateFormat fmt = new XmlSchemaDateFormat();
                     Date creationTime = fmt.parse(tokenLifetime.getCreated());
                     Date expirationTime = 
fmt.parse(tokenLifetime.getExpires());
                     
+                    // Check to see if the created time is in the future
+                    Date validCreation = new Date();
+                    long currentTime = validCreation.getTime();
+                    if (futureTimeToLive > 0) {
+                        validCreation.setTime(currentTime + futureTimeToLive * 
1000);
+                    }
+                    if (creationTime != null && 
creationTime.after(validCreation)) {
+                        LOG.fine("The Created Time is too far in the future");
+                        throw new STSException(
+                            "The Created Time is too far in the future", 
STSException.INVALID_TIME
+                        );
+                    }
+                    
                     long requestedLifetime = expirationTime.getTime() - 
creationTime.getTime();
                     if (requestedLifetime > (getMaxLifetime() * 1000L)) {
                         StringBuilder sb = new StringBuilder();
@@ -158,5 +188,5 @@ public class DefaultConditionsProvider i
         
         return conditions;
     }
-        
+
 }

Modified: 
cxf/branches/2.5.x-fixes/services/sts/sts-core/src/test/java/org/apache/cxf/sts/token/provider/SAMLProviderLifetimeTest.java
URL: 
http://svn.apache.org/viewvc/cxf/branches/2.5.x-fixes/services/sts/sts-core/src/test/java/org/apache/cxf/sts/token/provider/SAMLProviderLifetimeTest.java?rev=1326597&r1=1326596&r2=1326597&view=diff
==============================================================================
--- 
cxf/branches/2.5.x-fixes/services/sts/sts-core/src/test/java/org/apache/cxf/sts/token/provider/SAMLProviderLifetimeTest.java
 (original)
+++ 
cxf/branches/2.5.x-fixes/services/sts/sts-core/src/test/java/org/apache/cxf/sts/token/provider/SAMLProviderLifetimeTest.java
 Mon Apr 16 13:11:33 2012
@@ -235,6 +235,128 @@ public class SAMLProviderLifetimeTest ex
         assertTrue(tokenString.contains(providerResponse.getTokenId()));
     }
     
+    /**
+     * Issue SAML 2 token with a near future Created Lifetime. This should 
pass as we allow a future
+     * dated Lifetime up to 60 seconds to avoid clock skew problems.
+     */
+    @org.junit.Test
+    public void testSaml2NearFutureCreatedLifetime() throws Exception {
+        
+        int requestedLifetime = 60;
+        SAMLTokenProvider samlTokenProvider = new SAMLTokenProvider();
+        DefaultConditionsProvider conditionsProvider = new 
DefaultConditionsProvider();
+        conditionsProvider.setAcceptClientLifetime(true);
+        samlTokenProvider.setConditionsProvider(conditionsProvider);
+               
+        TokenProviderParameters providerParameters = 
+            createProviderParameters(
+                WSConstants.WSS_SAML2_TOKEN_TYPE, 
STSConstants.BEARER_KEY_KEYTYPE
+            );
+        
+        // Set expected lifetime to 1 minute
+        Date creationTime = new Date();
+        Date expirationTime = new Date();
+        expirationTime.setTime(creationTime.getTime() + (requestedLifetime * 
1000L));
+        creationTime.setTime(creationTime.getTime() + (10 * 1000L));
+        Lifetime lifetime = new Lifetime();
+        XmlSchemaDateFormat fmt = new XmlSchemaDateFormat();
+        lifetime.setCreated(fmt.format(creationTime));
+        lifetime.setExpires(fmt.format(expirationTime));
+        providerParameters.getTokenRequirements().setLifetime(lifetime);    
+        
+        
assertTrue(samlTokenProvider.canHandleToken(WSConstants.WSS_SAML2_TOKEN_TYPE));
+        TokenProviderResponse providerResponse = 
samlTokenProvider.createToken(providerParameters);
+        assertTrue(providerResponse != null);
+        assertTrue(providerResponse.getToken() != null && 
providerResponse.getTokenId() != null);
+        assertEquals(providerResponse.getLifetime(), 60 - 10);
+        Element token = providerResponse.getToken();
+        String tokenString = DOM2Writer.nodeToString(token);
+        assertTrue(tokenString.contains(providerResponse.getTokenId()));
+    }
+    
+    /**
+     * Issue SAML 2 token with a future Created Lifetime. This should fail as 
we only allow a future
+     * dated Lifetime up to 60 seconds to avoid clock skew problems.
+     */
+    @org.junit.Test
+    public void testSaml2FarFutureCreatedLifetime() throws Exception {
+        
+        int requestedLifetime = 60;
+        SAMLTokenProvider samlTokenProvider = new SAMLTokenProvider();
+        DefaultConditionsProvider conditionsProvider = new 
DefaultConditionsProvider();
+        conditionsProvider.setAcceptClientLifetime(true);
+        samlTokenProvider.setConditionsProvider(conditionsProvider);
+               
+        TokenProviderParameters providerParameters = 
+            createProviderParameters(
+                WSConstants.WSS_SAML2_TOKEN_TYPE, 
STSConstants.BEARER_KEY_KEYTYPE
+            );
+        
+        // Set expected lifetime to 1 minute
+        Date creationTime = new Date();
+        creationTime.setTime(creationTime.getTime() + (60L * 2L * 1000L));
+        Date expirationTime = new Date();
+        expirationTime.setTime(creationTime.getTime() + (requestedLifetime * 
1000L));
+        Lifetime lifetime = new Lifetime();
+        XmlSchemaDateFormat fmt = new XmlSchemaDateFormat();
+        lifetime.setCreated(fmt.format(creationTime));
+        lifetime.setExpires(fmt.format(expirationTime));
+        providerParameters.getTokenRequirements().setLifetime(lifetime);    
+        
+        
assertTrue(samlTokenProvider.canHandleToken(WSConstants.WSS_SAML2_TOKEN_TYPE));
+        try {
+            samlTokenProvider.createToken(providerParameters);
+            fail("Failure expected on a Created Element too far in the 
future");
+        } catch (STSException ex) {
+            // expected
+        }
+        
+        // Now allow this sort of Created Element
+        conditionsProvider.setFutureTimeToLive(60L * 60L);
+        
+        TokenProviderResponse providerResponse = 
samlTokenProvider.createToken(providerParameters);
+        assertTrue(providerResponse != null);
+        assertTrue(providerResponse.getToken() != null && 
providerResponse.getTokenId() != null);
+        Element token = providerResponse.getToken();
+        String tokenString = DOM2Writer.nodeToString(token);
+        assertTrue(tokenString.contains(providerResponse.getTokenId()));
+    }
+    
+    /**
+     * Issue SAML 2 token with no Expires element. This will be rejected, but 
will default to the
+     * configured TTL and so the request will pass.
+     */
+    @org.junit.Test
+    public void testSaml2NoExpires() throws Exception {
+        
+        SAMLTokenProvider samlTokenProvider = new SAMLTokenProvider();
+        DefaultConditionsProvider conditionsProvider = new 
DefaultConditionsProvider();
+        conditionsProvider.setAcceptClientLifetime(true);
+        samlTokenProvider.setConditionsProvider(conditionsProvider);
+               
+        TokenProviderParameters providerParameters = 
+            createProviderParameters(
+                WSConstants.WSS_SAML2_TOKEN_TYPE, 
STSConstants.BEARER_KEY_KEYTYPE
+            );
+        
+        // Set expected lifetime to 1 minute
+        Date creationTime = new Date();
+        creationTime.setTime(creationTime.getTime() + (60L * 2L * 1000L));
+        Lifetime lifetime = new Lifetime();
+        XmlSchemaDateFormat fmt = new XmlSchemaDateFormat();
+        lifetime.setCreated(fmt.format(creationTime));
+        providerParameters.getTokenRequirements().setLifetime(lifetime);    
+        
+        
assertTrue(samlTokenProvider.canHandleToken(WSConstants.WSS_SAML2_TOKEN_TYPE));
+
+        TokenProviderResponse providerResponse = 
samlTokenProvider.createToken(providerParameters);
+        assertTrue(providerResponse != null);
+        assertTrue(providerResponse.getToken() != null && 
providerResponse.getTokenId() != null);
+        assertEquals(providerResponse.getLifetime(), 
conditionsProvider.getLifetime());
+        Element token = providerResponse.getToken();
+        String tokenString = DOM2Writer.nodeToString(token);
+        assertTrue(tokenString.contains(providerResponse.getTokenId()));
+    }
     
     private TokenProviderParameters createProviderParameters(
             String tokenType, String keyType


Reply via email to