cxf-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From serg...@apache.org
Subject cxf git commit: Some updates for JWT time claims validation code as discussed with Colm, nont final yet
Date Mon, 12 Oct 2015 13:04:18 GMT
Repository: cxf
Updated Branches:
  refs/heads/master 741a74e33 -> 8654f83ed


Some updates for JWT time claims validation code as discussed with Colm, nont final yet


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

Branch: refs/heads/master
Commit: 8654f83ed145f3be4dabd19205491b7ec5e31a64
Parents: 741a74e
Author: Sergey Beryozkin <sberyozkin@gmail.com>
Authored: Mon Oct 12 14:04:02 2015 +0100
Committer: Sergey Beryozkin <sberyozkin@gmail.com>
Committed: Mon Oct 12 14:04:02 2015 +0100

----------------------------------------------------------------------
 .../main/webapp/WEB-INF/applicationContext.xml  |  2 +-
 .../main/webapp/WEB-INF/applicationContext.xml  |  2 +-
 .../jose/jaxrs/JwtAuthenticationFilter.java     | 27 ++++-------
 .../cxf/rs/security/jose/jwt/JwtUtils.java      | 47 ++++++++-----------
 .../oidc/rp/AbstractTokenValidator.java         | 49 +++++++++++---------
 5 files changed, 58 insertions(+), 69 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cxf/blob/8654f83e/distribution/src/main/release/samples/jax_rs/basic_oidc/src/main/webapp/WEB-INF/applicationContext.xml
----------------------------------------------------------------------
diff --git a/distribution/src/main/release/samples/jax_rs/basic_oidc/src/main/webapp/WEB-INF/applicationContext.xml
b/distribution/src/main/release/samples/jax_rs/basic_oidc/src/main/webapp/WEB-INF/applicationContext.xml
index 8398d45..3fa9454 100644
--- a/distribution/src/main/release/samples/jax_rs/basic_oidc/src/main/webapp/WEB-INF/applicationContext.xml
+++ b/distribution/src/main/release/samples/jax_rs/basic_oidc/src/main/webapp/WEB-INF/applicationContext.xml
@@ -93,7 +93,7 @@
      <bean id="idTokenReader" class="org.apache.cxf.rs.security.oidc.rp.IdTokenReader">
          <property name="jwkSetClient" ref="jwkSetClient"/> 
          <property name="issuerId" value="accounts.google.com"/>
-         <property name="futureTTL" value="10"/>
+         <property name="clockOffset" value="10"/>
      </bean>
      
      <!-- WebClient for requesting an OIDC IDP JWK Set 

http://git-wip-us.apache.org/repos/asf/cxf/blob/8654f83e/distribution/src/main/release/samples/jax_rs/big_query/src/main/webapp/WEB-INF/applicationContext.xml
----------------------------------------------------------------------
diff --git a/distribution/src/main/release/samples/jax_rs/big_query/src/main/webapp/WEB-INF/applicationContext.xml
b/distribution/src/main/release/samples/jax_rs/big_query/src/main/webapp/WEB-INF/applicationContext.xml
index 13e5960..08e0d23 100644
--- a/distribution/src/main/release/samples/jax_rs/big_query/src/main/webapp/WEB-INF/applicationContext.xml
+++ b/distribution/src/main/release/samples/jax_rs/big_query/src/main/webapp/WEB-INF/applicationContext.xml
@@ -148,7 +148,7 @@
      <bean id="idTokenReader" class="org.apache.cxf.rs.security.oidc.rp.IdTokenReader">
          <property name="jwkSetClient" ref="jwkSetClient"/> 
          <property name="issuerId" value="accounts.google.com"/>
-         <property name="futureTTL" value="10"/>
+         <property name="clockOffset" value="10"/>
      </bean>
      <bean id="userInfoClient" class="org.apache.cxf.rs.security.oidc.rp.UserInfoClient">
          <property name="userInfoServiceClient" ref="userInfoServiceClient"/>

http://git-wip-us.apache.org/repos/asf/cxf/blob/8654f83e/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/JwtAuthenticationFilter.java
----------------------------------------------------------------------
diff --git a/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/JwtAuthenticationFilter.java
b/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/JwtAuthenticationFilter.java
index cc14a85..dfbbc57 100644
--- a/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/JwtAuthenticationFilter.java
+++ b/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/JwtAuthenticationFilter.java
@@ -44,8 +44,7 @@ public class JwtAuthenticationFilter extends AbstractJoseJwtConsumer implements
     
     private static final String DEFAULT_AUTH_SCHEME = "JWT";
     private String expectedAuthScheme = DEFAULT_AUTH_SCHEME;
-    private int ttl = 300;
-    private int futureTTL;
+    private int clockOffset;
     
     @Override
     public void filter(ContainerRequestContext requestContext) throws IOException {
@@ -67,30 +66,20 @@ public class JwtAuthenticationFilter extends AbstractJoseJwtConsumer implements
     protected void validateToken(JwtToken jwt) {
         // If we have no issued time then we need to have an expiry
         boolean expiredRequired = jwt.getClaims().getIssuedAt() == null;
-        JwtUtils.validateJwtExpiry(jwt.getClaims(), expiredRequired);
+        JwtUtils.validateJwtExpiry(jwt.getClaims(), clockOffset, expiredRequired);
         
-        JwtUtils.validateJwtNotBefore(jwt.getClaims(), futureTTL, false);
+        JwtUtils.validateJwtNotBefore(jwt.getClaims(), clockOffset, false);
         
         // If we have no expiry then we must have an issued at
         boolean issuedAtRequired = jwt.getClaims().getExpiryTime() == null;
-        if (issuedAtRequired) {
-            JwtUtils.validateJwtTTL(jwt.getClaims(), ttl, issuedAtRequired);
-        }
-    }
-
-    public int getTtl() {
-        return ttl;
-    }
-
-    public void setTtl(int ttl) {
-        this.ttl = ttl;
+        JwtUtils.validateJwtIssuedAt(jwt.getClaims(), clockOffset, issuedAtRequired);
     }
 
-    public int getFutureTTL() {
-        return futureTTL;
+    public int getClockOffset() {
+        return clockOffset;
     }
 
-    public void setFutureTTL(int futureTTL) {
-        this.futureTTL = futureTTL;
+    public void setClockOffset(int clockOffset) {
+        this.clockOffset = clockOffset;
     }
 }

http://git-wip-us.apache.org/repos/asf/cxf/blob/8654f83e/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwt/JwtUtils.java
----------------------------------------------------------------------
diff --git a/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwt/JwtUtils.java
b/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwt/JwtUtils.java
index 64c24e9..983ada3 100644
--- a/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwt/JwtUtils.java
+++ b/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwt/JwtUtils.java
@@ -37,7 +37,7 @@ public final class JwtUtils {
         return new JwtTokenReaderWriter().fromJsonClaims(json);
     }
     
-    public static void validateJwtExpiry(JwtClaims claims, boolean claimRequired) {
+    public static void validateJwtExpiry(JwtClaims claims, int clockOffset, boolean claimRequired)
{
         Long expiryTime = claims.getExpiryTime();
         if (expiryTime == null) {
             if (claimRequired) {
@@ -45,40 +45,39 @@ public final class JwtUtils {
             }
             return;
         }
-        
         Date rightNow = new Date();
         Date expiresDate = new Date(expiryTime * 1000L);
+        if (clockOffset != 0) {
+            expiresDate.setTime(expiresDate.getTime() + (long)clockOffset * 1000L);
+        }
         if (expiresDate.before(rightNow)) {
             throw new JwtException("The token has expired");
         }
     }
     
-    public static void validateJwtNotBefore(JwtClaims claims, int futureTimeToLive, boolean
claimRequired) {
+    public static void validateJwtNotBefore(JwtClaims claims, int clockOffset, boolean claimRequired)
{
         Long notBeforeTime = claims.getNotBefore();
-        
-        // If no NotBefore then just use the IssueAt if it exists
-        if (notBeforeTime == null && claims.getIssuedAt() != null) {
-            notBeforeTime = claims.getIssuedAt();
-        }
-        
-        if (notBeforeTime == null && claimRequired) {
-            throw new JwtException("The token cannot be accepted yet");
+        if (notBeforeTime == null) {
+            if (claimRequired) {
+                throw new JwtException("The token cannot be accepted yet");
+            }
+            return;
         }
         
         Date validCreation = new Date();
         long currentTime = validCreation.getTime();
-        if (futureTimeToLive > 0) {
-            validCreation.setTime(currentTime + (long)futureTimeToLive * 1000L);
+        if (clockOffset != 0) {
+            validCreation.setTime(currentTime + (long)clockOffset * 1000L);
         }
-        Date createdDate = new Date(notBeforeTime * 1000L);
+        Date notBeforeDate = new Date(notBeforeTime * 1000L);
 
         // Check to see if the not before time is in the future
-        if (createdDate.after(validCreation)) {
+        if (notBeforeDate.after(validCreation)) {
             throw new JwtException("The token cannot be accepted yet");
         }
     }
     
-    public static void validateJwtTTL(JwtClaims claims, int timeToLive, boolean claimRequired)
{
+    public static void validateJwtIssuedAt(JwtClaims claims, int clockOffset, boolean claimRequired)
{
         Long issuedAtInSecs = claims.getIssuedAt();
         if (issuedAtInSecs == null) {
             if (claimRequired) {
@@ -87,21 +86,15 @@ public final class JwtUtils {
             return;
         }
         
-        Date validCreation = new Date();
         Date createdDate = new Date(issuedAtInSecs * 1000L);
-        
-        int ttl = timeToLive;
-        if (ttl <= 0) {
-            ttl = 300;
+        if (clockOffset != 0) {
+            // Calculate the time that is allowed for the message to travel
+            createdDate.setTime(createdDate.getTime() - (long)clockOffset * 1000L);
         }
         
-        // Calculate the time that is allowed for the message to travel
-        long currentTime = validCreation.getTime();
-        currentTime -= (long)ttl * 1000L;
-        validCreation.setTime(currentTime);
+        Date rightNow = new Date();
 
-        // Validate the time it took the message to travel
-        if (createdDate.before(validCreation)) {
+        if (createdDate.after(rightNow)) {
             throw new JwtException("Invalid issuedAt");
         }
     }

http://git-wip-us.apache.org/repos/asf/cxf/blob/8654f83e/rt/rs/security/sso/oidc/src/main/java/org/apache/cxf/rs/security/oidc/rp/AbstractTokenValidator.java
----------------------------------------------------------------------
diff --git a/rt/rs/security/sso/oidc/src/main/java/org/apache/cxf/rs/security/oidc/rp/AbstractTokenValidator.java
b/rt/rs/security/sso/oidc/src/main/java/org/apache/cxf/rs/security/oidc/rp/AbstractTokenValidator.java
index 02a7dc2..ace0298 100644
--- a/rt/rs/security/sso/oidc/src/main/java/org/apache/cxf/rs/security/oidc/rp/AbstractTokenValidator.java
+++ b/rt/rs/security/sso/oidc/src/main/java/org/apache/cxf/rs/security/oidc/rp/AbstractTokenValidator.java
@@ -34,12 +34,19 @@ import org.apache.cxf.rs.security.oauth2.provider.AbstractOAuthJoseJwtConsumer;
 public abstract class AbstractTokenValidator extends AbstractOAuthJoseJwtConsumer {
     private static final String SELF_ISSUED_ISSUER = "https://self-issued.me";
     private String issuerId;
-    private int ttl = 300;
-    private int futureTTL;
+    private int clockOffset;
     private WebClient jwkSetClient;
     private boolean supportSelfIssuedProvider;
+    private boolean strictTimeValidation;
     private ConcurrentHashMap<String, JsonWebKey> keyMap = new ConcurrentHashMap<String,
JsonWebKey>(); 
-        
+
+    /**
+     * Validate core JWT claims
+     * @param claims the claims
+     * @param clientId OAuth2 client id
+     * @param validateClaimsAlways if set to true then enforce that the claims 
+     *                             to be validated must be set
+     */
     protected void validateJwtClaims(JwtClaims claims, String clientId, boolean validateClaimsAlways)
{
         // validate the issuer
         String issuer = claims.getIssuer();
@@ -63,16 +70,20 @@ public abstract class AbstractTokenValidator extends AbstractOAuthJoseJwtConsume
                 throw new SecurityException("Invalid audience");
             }
     
-            // If we have no issued time then we need to have an expiry
-            boolean expiredRequired = claims.getIssuedAt() == null;
-            JwtUtils.validateJwtExpiry(claims, expiredRequired);
+            // If strict time validation: if no issuedTime claim is set then an expiresAt
claim must be set
+            // Otherwise: validate only if expiresAt claim is set
+            boolean expiredRequired = 
+                validateClaimsAlways || strictTimeValidation && claims.getIssuedAt()
== null;
+            JwtUtils.validateJwtExpiry(claims, clockOffset, expiredRequired);
             
-            JwtUtils.validateJwtNotBefore(claims, futureTTL, false);
+            // If strict time validation: If no expiresAt claim is set then an issuedAt claim
must be set
+            // Otherwise: validate only if issuedAt claim is set
+            boolean issuedAtRequired = 
+                validateClaimsAlways || strictTimeValidation && claims.getExpiryTime()
== null;
+            JwtUtils.validateJwtIssuedAt(claims, clockOffset, issuedAtRequired);
             
-            // If we have no expiry then we must have an issued at
-            boolean issuedAtRequired = claims.getExpiryTime() == null;
-            if (issuedAtRequired) {
-                JwtUtils.validateJwtTTL(claims, ttl, issuedAtRequired);
+            if (strictTimeValidation) {
+                JwtUtils.validateJwtNotBefore(claims, clockOffset, strictTimeValidation);
             }
         }
     }
@@ -130,19 +141,15 @@ public abstract class AbstractTokenValidator extends AbstractOAuthJoseJwtConsume
         this.supportSelfIssuedProvider = supportSelfIssuedProvider;
     }
 
-    public int getTtl() {
-        return ttl;
-    }
-
-    public void setTtl(int ttl) {
-        this.ttl = ttl;
+    public int getClockOffset() {
+        return clockOffset;
     }
 
-    public int getFutureTTL() {
-        return futureTTL;
+    public void setClockOffset(int clockOffset) {
+        this.clockOffset = clockOffset;
     }
 
-    public void setFutureTTL(int futureTTL) {
-        this.futureTTL = futureTTL;
+    public void setStrictTimeValidation(boolean strictTimeValidation) {
+        this.strictTimeValidation = strictTimeValidation;
     }
 }


Mime
View raw message