You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cxf.apache.org by co...@apache.org on 2018/09/17 16:33:28 UTC

[cxf] branch master updated: CXF-6755 - Support AccessToken NotBefore property

This is an automated email from the ASF dual-hosted git repository.

coheigea pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/cxf.git


The following commit(s) were added to refs/heads/master by this push:
     new acc697f  CXF-6755 - Support AccessToken NotBefore property
acc697f is described below

commit acc697f1c88f392bd952e07d50a9ae2ce0b76411
Author: Colm O hEigeartaigh <co...@apache.org>
AuthorDate: Mon Sep 17 17:33:07 2018 +0100

    CXF-6755 - Support AccessToken NotBefore property
---
 .../apache/cxf/rs/security/oauth2/common/AccessToken.java    | 12 ++++++++++++
 .../cxf/rs/security/oauth2/common/AccessTokenValidation.java | 10 ++++++++++
 .../oauth2/filters/AccessTokenIntrospectionClient.java       |  5 ++++-
 .../rs/security/oauth2/filters/JwtAccessTokenValidator.java  |  5 ++++-
 .../cxf/rs/security/oauth2/provider/OAuthJSONProvider.java   |  8 ++++++++
 .../oauth2/services/AbstractAccessTokenValidator.java        |  6 ++++++
 .../security/oauth2/services/TokenIntrospectionService.java  |  4 +++-
 .../security/oauth2/common/JCacheOAuthDataProviderImpl.java  |  9 +++++++++
 .../security/oauth2/common/JPAOAuthDataProviderImpl.java     |  9 +++++++++
 .../jaxrs/security/oauth2/common/OAuthDataProviderImpl.java  |  9 +++++++++
 .../security/oauth2/grants/IntrospectionServiceTest.java     |  3 +++
 11 files changed, 77 insertions(+), 3 deletions(-)

diff --git a/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/common/AccessToken.java b/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/common/AccessToken.java
index 5bee11e..ebbf9a7 100644
--- a/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/common/AccessToken.java
+++ b/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/common/AccessToken.java
@@ -42,6 +42,7 @@ public abstract class AccessToken implements Serializable {
     private String refreshToken;
     private long expiresIn = -1;
     private long issuedAt = -1;
+    private long notBefore = -1;
     private String issuer;
     private String encodedToken;
 
@@ -170,4 +171,15 @@ public abstract class AccessToken implements Serializable {
     public void setEncodedToken(String encodedToken) {
         this.encodedToken = encodedToken;
     }
+
+    /**
+     * @return the Not Before" timestamp, -1 means no 'nbf' parameter was returned
+     */
+    public long getNotBefore() {
+        return notBefore;
+    }
+
+    public void setNotBefore(long notBefore) {
+        this.notBefore = notBefore;
+    }
 }
diff --git a/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/common/AccessTokenValidation.java b/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/common/AccessTokenValidation.java
index e4c1b7e..960e5c0 100644
--- a/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/common/AccessTokenValidation.java
+++ b/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/common/AccessTokenValidation.java
@@ -53,6 +53,7 @@ public class AccessTokenValidation {
     private String tokenGrantType;
     private long tokenIssuedAt;
     private long tokenLifetime;
+    private long tokenNotBefore;
     private String tokenIssuer;
     private UserSubject tokenSubject;
     private List<OAuthPermission> tokenScopes = new LinkedList<OAuthPermission>();
@@ -74,6 +75,7 @@ public class AccessTokenValidation {
         this.tokenGrantType = token.getGrantType();
         this.tokenIssuedAt = token.getIssuedAt();
         this.tokenLifetime = token.getExpiresIn();
+        this.tokenNotBefore = token.getNotBefore();
         this.tokenIssuer = token.getIssuer();
         this.tokenSubject = token.getSubject();
         this.tokenScopes = token.getScopes();
@@ -194,4 +196,12 @@ public class AccessTokenValidation {
         this.tokenIssuer = tokenIssuer;
     }
 
+    public long getTokenNotBefore() {
+        return tokenNotBefore;
+    }
+
+    public void setTokenNotBefore(long tokenNotBefore) {
+        this.tokenNotBefore = tokenNotBefore;
+    }
+
 }
diff --git a/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/filters/AccessTokenIntrospectionClient.java b/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/filters/AccessTokenIntrospectionClient.java
index 2c78938..9683b74 100644
--- a/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/filters/AccessTokenIntrospectionClient.java
+++ b/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/filters/AccessTokenIntrospectionClient.java
@@ -76,6 +76,9 @@ public class AccessTokenIntrospectionClient implements AccessTokenValidator {
         if (response.getExp() != null) {
             atv.setTokenLifetime(response.getExp() - atv.getTokenIssuedAt());
         }
+        if (response.getNbf() != null) {
+            atv.setTokenNotBefore(response.getNbf());
+        }
         if (!StringUtils.isEmpty(response.getAud())) {
             atv.setAudiences(response.getAud());
         }
@@ -96,7 +99,7 @@ public class AccessTokenIntrospectionClient implements AccessTokenValidator {
             atv.setTokenSubject(new UserSubject(response.getUsername()));
         }
         atv.getExtraProps().putAll(response.getExtensions());
-        
+
         return atv;
     }
 
diff --git a/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/filters/JwtAccessTokenValidator.java b/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/filters/JwtAccessTokenValidator.java
index a7c8717..e835f8e 100644
--- a/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/filters/JwtAccessTokenValidator.java
+++ b/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/filters/JwtAccessTokenValidator.java
@@ -89,6 +89,9 @@ public class JwtAccessTokenValidator extends JoseJwtConsumer implements AccessTo
         if (claims.getIssuer() != null) {
             atv.setTokenIssuer(claims.getIssuer());
         }
+        if (claims.getNotBefore() != null) {
+            atv.setTokenNotBefore(claims.getNotBefore());
+        }
         Object scope = claims.getClaim(OAuthConstants.SCOPE);
         if (scope != null) {
             String[] scopes = scope instanceof String
@@ -125,7 +128,7 @@ public class JwtAccessTokenValidator extends JoseJwtConsumer implements AccessTo
                 atv.getExtraProps().put(JoseConstants.HEADER_X509_THUMBPRINT_SHA256, certCnf.toString());
             }
         }
-        
+
         return atv;
     }
 
diff --git a/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/provider/OAuthJSONProvider.java b/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/provider/OAuthJSONProvider.java
index 6047c4b..6fd50e4 100644
--- a/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/provider/OAuthJSONProvider.java
+++ b/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/provider/OAuthJSONProvider.java
@@ -125,6 +125,10 @@ public class OAuthJSONProvider implements MessageBodyWriter<Object>,
                 sb.append(",");
                 appendJsonPair(sb, "exp", obj.getExp(), false);
             }
+            if (obj.getNbf() != null) {
+                sb.append(",");
+                appendJsonPair(sb, "nbf", obj.getNbf(), false);
+            }
             if (!obj.getExtensions().isEmpty()) {
                 for (Map.Entry<String, String> entry : obj.getExtensions().entrySet()) {
                     sb.append(",");
@@ -278,6 +282,10 @@ public class OAuthJSONProvider implements MessageBodyWriter<Object>,
         if (exp != null) {
             resp.setExp(exp);
         }
+        Long nbf = (Long)params.get("nbf");
+        if (nbf != null) {
+            resp.setNbf(nbf);
+        }
         Map<String, Object> cnf = CastUtils.cast((Map<?, ?>)params.get("cnf"));
         if (cnf != null) {
             String thumbprint = (String)cnf.get(JoseConstants.HEADER_X509_THUMBPRINT_SHA256);
diff --git a/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/services/AbstractAccessTokenValidator.java b/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/services/AbstractAccessTokenValidator.java
index 5286d51..dd4fd89 100644
--- a/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/services/AbstractAccessTokenValidator.java
+++ b/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/services/AbstractAccessTokenValidator.java
@@ -158,6 +158,12 @@ public abstract class AbstractAccessTokenValidator {
             }
             AuthorizationUtils.throwAuthorizationFailure(supportedSchemes, realm);
         }
+
+        // Check nbf property
+        if (accessTokenV.getTokenNotBefore() > 0
+            && accessTokenV.getTokenNotBefore() > System.currentTimeMillis() / 1000L) {
+            AuthorizationUtils.throwAuthorizationFailure(supportedSchemes, realm);
+        }
         if (maxValidationDataCacheSize > 0) {
             if (accessTokenValidations.size() >= maxValidationDataCacheSize) {
                 // or delete the ones expiring sooner than others, etc
diff --git a/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/services/TokenIntrospectionService.java b/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/services/TokenIntrospectionService.java
index 3fe5461..936c59b 100644
--- a/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/services/TokenIntrospectionService.java
+++ b/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/services/TokenIntrospectionService.java
@@ -98,7 +98,9 @@ public class TokenIntrospectionService {
         if (at.getExpiresIn() > 0) {
             response.setExp(at.getIssuedAt() + at.getExpiresIn());
         }
-
+        if (at.getNotBefore() > 0) {
+            response.setNbf(at.getNotBefore());
+        }
         response.setTokenType(at.getTokenType());
 
         if (reportExtraTokenProperties) {
diff --git a/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/oauth2/common/JCacheOAuthDataProviderImpl.java b/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/oauth2/common/JCacheOAuthDataProviderImpl.java
index fd20944..4cba419 100644
--- a/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/oauth2/common/JCacheOAuthDataProviderImpl.java
+++ b/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/oauth2/common/JCacheOAuthDataProviderImpl.java
@@ -31,6 +31,8 @@ import org.apache.cxf.BusFactory;
 import org.apache.cxf.common.util.Base64Utility;
 import org.apache.cxf.rs.security.oauth2.common.Client;
 import org.apache.cxf.rs.security.oauth2.common.OAuthPermission;
+import org.apache.cxf.rs.security.oauth2.common.ServerAccessToken;
+import org.apache.cxf.rs.security.oauth2.common.UserSubject;
 import org.apache.cxf.rs.security.oauth2.grants.code.JCacheCodeDataProvider;
 import org.apache.cxf.rs.security.oauth2.provider.OAuthServiceException;
 import org.apache.cxf.rs.security.oauth2.saml.Constants;
@@ -165,6 +167,13 @@ public class JCacheOAuthDataProviderImpl extends JCacheCodeDataProvider {
     }
 
     @Override
+    protected ServerAccessToken createNewAccessToken(Client client, UserSubject userSub) {
+        ServerAccessToken token = super.createNewAccessToken(client, userSub);
+        token.setNotBefore((System.currentTimeMillis() / 1000L) - 5L);
+        return token;
+    }
+
+    @Override
     public Client getClient(String clientId) {
         Client c = super.getClient(clientId);
         if (c == null) {
diff --git a/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/oauth2/common/JPAOAuthDataProviderImpl.java b/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/oauth2/common/JPAOAuthDataProviderImpl.java
index 3899e77..8ed473e 100644
--- a/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/oauth2/common/JPAOAuthDataProviderImpl.java
+++ b/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/oauth2/common/JPAOAuthDataProviderImpl.java
@@ -28,6 +28,8 @@ import javax.persistence.EntityManagerFactory;
 
 import org.apache.cxf.rs.security.oauth2.common.Client;
 import org.apache.cxf.rs.security.oauth2.common.OAuthPermission;
+import org.apache.cxf.rs.security.oauth2.common.ServerAccessToken;
+import org.apache.cxf.rs.security.oauth2.common.UserSubject;
 import org.apache.cxf.rs.security.oauth2.grants.code.JPACodeDataProvider;
 import org.apache.cxf.rs.security.oauth2.provider.OAuthServiceException;
 import org.apache.cxf.rs.security.oauth2.saml.Constants;
@@ -140,6 +142,13 @@ public class JPAOAuthDataProviderImpl extends JPACodeDataProvider {
     }
 
     @Override
+    protected ServerAccessToken createNewAccessToken(Client client, UserSubject userSub) {
+        ServerAccessToken token = super.createNewAccessToken(client, userSub);
+        token.setNotBefore((System.currentTimeMillis() / 1000L) - 5L);
+        return token;
+    }
+
+    @Override
     public Client getClient(String clientId) {
         Client c = super.getClient(clientId);
         if (c == null) {
diff --git a/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/oauth2/common/OAuthDataProviderImpl.java b/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/oauth2/common/OAuthDataProviderImpl.java
index 45901ab..e823313 100644
--- a/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/oauth2/common/OAuthDataProviderImpl.java
+++ b/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/oauth2/common/OAuthDataProviderImpl.java
@@ -31,6 +31,8 @@ import org.apache.cxf.BusFactory;
 import org.apache.cxf.common.util.Base64Utility;
 import org.apache.cxf.rs.security.oauth2.common.Client;
 import org.apache.cxf.rs.security.oauth2.common.OAuthPermission;
+import org.apache.cxf.rs.security.oauth2.common.ServerAccessToken;
+import org.apache.cxf.rs.security.oauth2.common.UserSubject;
 import org.apache.cxf.rs.security.oauth2.grants.code.DefaultEHCacheCodeDataProvider;
 import org.apache.cxf.rs.security.oauth2.provider.OAuthServiceException;
 import org.apache.cxf.rs.security.oauth2.saml.Constants;
@@ -165,6 +167,13 @@ public class OAuthDataProviderImpl extends DefaultEHCacheCodeDataProvider {
     }
 
     @Override
+    protected ServerAccessToken createNewAccessToken(Client client, UserSubject userSub) {
+        ServerAccessToken token = super.createNewAccessToken(client, userSub);
+        token.setNotBefore((System.currentTimeMillis() / 1000L) - 5L);
+        return token;
+    }
+
+    @Override
     public Client getClient(String clientId) {
         Client c = super.getClient(clientId);
         if (c == null) {
diff --git a/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/oauth2/grants/IntrospectionServiceTest.java b/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/oauth2/grants/IntrospectionServiceTest.java
index 6e44381..3129b96 100644
--- a/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/oauth2/grants/IntrospectionServiceTest.java
+++ b/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/oauth2/grants/IntrospectionServiceTest.java
@@ -144,6 +144,9 @@ public class IntrospectionServiceTest extends AbstractBusClientServerTestBase {
         assertEquals(tokenIntrospection.getScope(), accessToken.getApprovedScope());
         Long validity = tokenIntrospection.getExp() - tokenIntrospection.getIat();
         assertTrue(validity == accessToken.getExpiresIn());
+        Long nbf = tokenIntrospection.getNbf();
+        long now = System.currentTimeMillis() / 1000L;
+        assertTrue(nbf < now);
     }
 
     @org.junit.Test