cxf-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From cohei...@apache.org
Subject [3/4] cxf git commit: Enable automatic processing of expiry / ttl for JWT tokens
Date Fri, 09 Oct 2015 14:07:32 GMT
Enable automatic processing of expiry / ttl for JWT tokens


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

Branch: refs/heads/master
Commit: 6041c0399c35eb8c236b3d1b998b538599ef4388
Parents: f10030b
Author: Colm O hEigeartaigh <coheigea@apache.org>
Authored: Fri Oct 9 15:03:15 2015 +0100
Committer: Colm O hEigeartaigh <coheigea@apache.org>
Committed: Fri Oct 9 15:07:26 2015 +0100

----------------------------------------------------------------------
 .../jose/jaxrs/JwtAuthenticationFilter.java     | 31 ++++++++
 .../cxf/rs/security/jose/jwt/JwtUtils.java      | 79 ++++++++++++++++----
 2 files changed, 94 insertions(+), 16 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cxf/blob/6041c039/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 408ce20..269a8d4 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
@@ -34,6 +34,7 @@ import org.apache.cxf.rs.security.jose.JoseException;
 import org.apache.cxf.rs.security.jose.JoseUtils;
 import org.apache.cxf.rs.security.jose.jwt.AbstractJoseJwtConsumer;
 import org.apache.cxf.rs.security.jose.jwt.JwtToken;
+import org.apache.cxf.rs.security.jose.jwt.JwtUtils;
 import org.apache.cxf.security.SecurityContext;
 
 @PreMatching
@@ -43,6 +44,8 @@ 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 = 0;
     
     @Override
     public void filter(ContainerRequestContext requestContext) throws IOException {
@@ -60,4 +63,32 @@ public class JwtAuthenticationFilter extends AbstractJoseJwtConsumer implements
         this.expectedAuthScheme = expectedAuthScheme;
     }
     
+    @Override
+    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.validateJwtNotBefore(jwt.getClaims(), futureTTL, false);
+        
+        // If we have no expiry then we must have an issued at
+        boolean issuedAtRequired = jwt.getClaims().getExpiryTime() == null;
+        JwtUtils.validateJwtTTL(jwt.getClaims(), ttl, issuedAtRequired);
+    }
+
+    public int getTtl() {
+        return ttl;
+    }
+
+    public void setTtl(int ttl) {
+        this.ttl = ttl;
+    }
+
+    public int getFutureTTL() {
+        return futureTTL;
+    }
+
+    public void setFutureTTL(int futureTTL) {
+        this.futureTTL = futureTTL;
+    }
 }

http://git-wip-us.apache.org/repos/asf/cxf/blob/6041c039/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 c846659..64c24e9 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
@@ -18,6 +18,7 @@
  */
 package org.apache.cxf.rs.security.jose.jwt;
 
+import java.util.Date;
 
 public final class JwtUtils {
     private JwtUtils() {
@@ -36,27 +37,73 @@ public final class JwtUtils {
         return new JwtTokenReaderWriter().fromJsonClaims(json);
     }
     
-    public static void validateJwtTimeClaims(JwtClaims claims, int clockOffset, 
-                                             int issuedAtRange, boolean claimsRequired) {
-        Long currentTimeInSecs = System.currentTimeMillis() / 1000;
-        Long expiryTimeInSecs = claims.getExpiryTime();
-        if (expiryTimeInSecs == null && claimsRequired 
-            || expiryTimeInSecs != null && currentTimeInSecs > expiryTimeInSecs)
{
-            throw new JwtException("The token expired");
+    public static void validateJwtExpiry(JwtClaims claims, boolean claimRequired) {
+        Long expiryTime = claims.getExpiryTime();
+        if (expiryTime == null) {
+            if (claimRequired) {
+                throw new JwtException("The token has expired");
+            }
+            return;
         }
-        Long issuedAtInSecs = claims.getIssuedAt();
-        if (clockOffset <= 0) {
-            clockOffset = 0;
+        
+        Date rightNow = new Date();
+        Date expiresDate = new Date(expiryTime * 1000L);
+        if (expiresDate.before(rightNow)) {
+            throw new JwtException("The token has expired");
         }
-        if (issuedAtInSecs == null && claimsRequired 
-            || issuedAtInSecs != null && (issuedAtInSecs - clockOffset > currentTimeInSecs
|| issuedAtRange > 0
-            && issuedAtInSecs < currentTimeInSecs - issuedAtRange)) {
-            throw new JwtException("Invalid issuedAt");
+    }
+    
+    public static void validateJwtNotBefore(JwtClaims claims, int futureTimeToLive, 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");
+        }
+        
+        Date validCreation = new Date();
+        long currentTime = validCreation.getTime();
+        if (futureTimeToLive > 0) {
+            validCreation.setTime(currentTime + (long)futureTimeToLive * 1000L);
+        }
+        Date createdDate = new Date(notBeforeTime * 1000L);
+
+        // Check to see if the not before time is in the future
+        if (createdDate.after(validCreation)) {
+            throw new JwtException("The token cannot be accepted yet");
         }
     }
     
-    public static void validateJwtTimeClaims(JwtClaims claims) {
-        validateJwtTimeClaims(claims, 0, 0, false);
+    public static void validateJwtTTL(JwtClaims claims, int timeToLive, boolean claimRequired)
{
+        Long issuedAtInSecs = claims.getIssuedAt();
+        if (issuedAtInSecs == null) {
+            if (claimRequired) {
+                throw new JwtException("Invalid issuedAt");
+            }
+            return;
+        }
+        
+        Date validCreation = new Date();
+        Date createdDate = new Date(issuedAtInSecs * 1000L);
+        
+        int ttl = timeToLive;
+        if (ttl <= 0) {
+            ttl = 300;
+        }
+        
+        // Calculate the time that is allowed for the message to travel
+        long currentTime = validCreation.getTime();
+        currentTime -= (long)ttl * 1000L;
+        validCreation.setTime(currentTime);
+
+        // Validate the time it took the message to travel
+        if (createdDate.before(validCreation)) {
+            throw new JwtException("Invalid issuedAt");
+        }
     }
     
 }


Mime
View raw message