You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@knox.apache.org by lm...@apache.org on 2013/11/30 19:07:44 UTC

git commit: KNOX-220 Fix JWT Expiration Processing

Updated Branches:
  refs/heads/master 40abc86cd -> b5f302065


KNOX-220 Fix JWT Expiration Processing

Project: http://git-wip-us.apache.org/repos/asf/incubator-knox/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-knox/commit/b5f30206
Tree: http://git-wip-us.apache.org/repos/asf/incubator-knox/tree/b5f30206
Diff: http://git-wip-us.apache.org/repos/asf/incubator-knox/diff/b5f30206

Branch: refs/heads/master
Commit: b5f3020659fe082ae7b7ad63556ef468e764de4a
Parents: 40abc86
Author: Larry McCay <lm...@hortonworks.com>
Authored: Sat Nov 30 13:07:28 2013 -0500
Committer: Larry McCay <lm...@hortonworks.com>
Committed: Sat Nov 30 13:07:28 2013 -0500

----------------------------------------------------------------------
 .../provider/federation/jwt/JWTMessages.java    |  6 +++
 .../jwt/filter/AccessTokenFederationFilter.java | 49 +++++++++++---------
 .../filter/JWTAccessTokenAssertionFilter.java   |  2 +-
 .../impl/DefaultTokenAuthorityService.java      | 13 +++++-
 .../security/token/JWTokenAuthority.java        | 11 +++--
 5 files changed, 52 insertions(+), 29 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-knox/blob/b5f30206/gateway-provider-security-jwt/src/main/java/org/apache/hadoop/gateway/provider/federation/jwt/JWTMessages.java
----------------------------------------------------------------------
diff --git a/gateway-provider-security-jwt/src/main/java/org/apache/hadoop/gateway/provider/federation/jwt/JWTMessages.java b/gateway-provider-security-jwt/src/main/java/org/apache/hadoop/gateway/provider/federation/jwt/JWTMessages.java
index 1f3b302..7438a25 100644
--- a/gateway-provider-security-jwt/src/main/java/org/apache/hadoop/gateway/provider/federation/jwt/JWTMessages.java
+++ b/gateway-provider-security-jwt/src/main/java/org/apache/hadoop/gateway/provider/federation/jwt/JWTMessages.java
@@ -28,4 +28,10 @@ public interface JWTMessages {
 
   @Message( level = MessageLevel.INFO, text = "Failed to verify the token signature." )
   void failedToVerifyTokenSignature();
+
+  @Message( level = MessageLevel.INFO, text = "Access token has expired; a new one must be acquired." )
+  void tokenHasExpired();
+
+  @Message( level = MessageLevel.INFO, text = "Expected Bearer token is missing." )
+  void missingBearerToken();
 }

http://git-wip-us.apache.org/repos/asf/incubator-knox/blob/b5f30206/gateway-provider-security-jwt/src/main/java/org/apache/hadoop/gateway/provider/federation/jwt/filter/AccessTokenFederationFilter.java
----------------------------------------------------------------------
diff --git a/gateway-provider-security-jwt/src/main/java/org/apache/hadoop/gateway/provider/federation/jwt/filter/AccessTokenFederationFilter.java b/gateway-provider-security-jwt/src/main/java/org/apache/hadoop/gateway/provider/federation/jwt/filter/AccessTokenFederationFilter.java
index e2856be..a4ac454 100644
--- a/gateway-provider-security-jwt/src/main/java/org/apache/hadoop/gateway/provider/federation/jwt/filter/AccessTokenFederationFilter.java
+++ b/gateway-provider-security-jwt/src/main/java/org/apache/hadoop/gateway/provider/federation/jwt/filter/AccessTokenFederationFilter.java
@@ -36,6 +36,7 @@ import javax.servlet.http.HttpServletResponse;
 
 import org.apache.hadoop.gateway.i18n.messages.MessagesFactory;
 import org.apache.hadoop.gateway.provider.federation.jwt.JWTMessages;
+import org.apache.hadoop.gateway.security.PrimaryPrincipal;
 import org.apache.hadoop.gateway.services.GatewayServices;
 import org.apache.hadoop.gateway.services.security.token.JWTokenAuthority;
 import org.apache.hadoop.gateway.services.security.token.impl.JWTToken;
@@ -64,32 +65,41 @@ public class AccessTokenFederationFilter implements Filter {
       JWTToken token = JWTToken.parseToken(wireToken);
       boolean verified = authority.verifyToken(token);
       if (verified) {
-        // TODO: validate expiration
-        // TODO: confirm that audience matches intended target
-        if (((HttpServletRequest) request).getRequestURL().indexOf(token.getAudience().toLowerCase()) != -1) {
-          // TODO: verify that the user requesting access to the service/resource is authorized for it - need scopes?
-          Subject subject = createSubjectFromToken(token);
-          continueWithEstablishedSecurityContext(subject, (HttpServletRequest)request, (HttpServletResponse)response, chain);
+        long expires = Long.parseLong(token.getExpires());
+        if (expires > System.currentTimeMillis()) {
+          if (((HttpServletRequest) request).getRequestURL().indexOf(token.getAudience().toLowerCase()) != -1) {
+            Subject subject = createSubjectFromToken(token);
+            continueWithEstablishedSecurityContext(subject, (HttpServletRequest)request, (HttpServletResponse)response, chain);
+          }
+          else {
+            log.failedToValidateAudience();
+            sendUnauthorized(response);
+            return; // break the chain
+          }
         }
         else {
-          log.failedToValidateAudience();
-          ((HttpServletResponse) response).sendError(HttpServletResponse.SC_UNAUTHORIZED);
-          return; //break filter chain
+          log.tokenHasExpired();
+          sendUnauthorized(response);
+          return; // break the chain
         }
       }
       else {
         log.failedToVerifyTokenSignature();
-        ((HttpServletResponse) response).sendError(HttpServletResponse.SC_UNAUTHORIZED);
-        return; //break filter chain
+        sendUnauthorized(response);
+        return; // break the chain
       }
     }
     else {
-      // no token provided in header
-      // TODO: may have to check cookie and url as well before sending error
-      ((HttpServletResponse) response).sendError(HttpServletResponse.SC_UNAUTHORIZED);
-      return; //break filter chain
+      log.missingBearerToken();
+      sendUnauthorized(response);
+      return; // break the chain
     }
   }
+
+  private void sendUnauthorized(ServletResponse response) throws IOException {
+    ((HttpServletResponse) response).sendError(HttpServletResponse.SC_UNAUTHORIZED);
+    return;
+  }
   
   private void continueWithEstablishedSecurityContext(Subject subject, final HttpServletRequest request, final HttpServletResponse response, final FilterChain chain) throws IOException, ServletException {
     try {
@@ -123,18 +133,13 @@ public class AccessTokenFederationFilter implements Filter {
 
     HashSet emptySet = new HashSet();
     Set<Principal> principals = new HashSet<Principal>();
-    Principal p = new Principal() {
-      @Override
-      public String getName() {
-        return principal;
-      }
-    };
+    Principal p = new PrimaryPrincipal(principal);
     principals.add(p);
     
 //        The newly constructed Sets check whether this Subject has been set read-only 
 //        before permitting subsequent modifications. The newly created Sets also prevent 
 //        illegal modifications by ensuring that callers have sufficient permissions.
- //
+//
 //        To modify the Principals Set, the caller must have AuthPermission("modifyPrincipals"). 
 //        To modify the public credential Set, the caller must have AuthPermission("modifyPublicCredentials"). 
 //        To modify the private credential Set, the caller must have AuthPermission("modifyPrivateCredentials").

http://git-wip-us.apache.org/repos/asf/incubator-knox/blob/b5f30206/gateway-provider-security-jwt/src/main/java/org/apache/hadoop/gateway/provider/federation/jwt/filter/JWTAccessTokenAssertionFilter.java
----------------------------------------------------------------------
diff --git a/gateway-provider-security-jwt/src/main/java/org/apache/hadoop/gateway/provider/federation/jwt/filter/JWTAccessTokenAssertionFilter.java b/gateway-provider-security-jwt/src/main/java/org/apache/hadoop/gateway/provider/federation/jwt/filter/JWTAccessTokenAssertionFilter.java
index 45d2b9d..f4d0ae8 100644
--- a/gateway-provider-security-jwt/src/main/java/org/apache/hadoop/gateway/provider/federation/jwt/filter/JWTAccessTokenAssertionFilter.java
+++ b/gateway-provider-security-jwt/src/main/java/org/apache/hadoop/gateway/provider/federation/jwt/filter/JWTAccessTokenAssertionFilter.java
@@ -132,7 +132,7 @@ public class JWTAccessTokenAssertionFilter extends AbstractIdentityAssertionFilt
         return principalName;
       }
     };
-    JWTToken token = authority.issueToken(p, serviceName, "RS256");
+    JWTToken token = authority.issueToken(p, serviceName, "RS256", expires);
     accessToken = token.toString();
     
     return accessToken;

http://git-wip-us.apache.org/repos/asf/incubator-knox/blob/b5f30206/gateway-server/src/main/java/org/apache/hadoop/gateway/services/token/impl/DefaultTokenAuthorityService.java
----------------------------------------------------------------------
diff --git a/gateway-server/src/main/java/org/apache/hadoop/gateway/services/token/impl/DefaultTokenAuthorityService.java b/gateway-server/src/main/java/org/apache/hadoop/gateway/services/token/impl/DefaultTokenAuthorityService.java
index 21cef3f..b72912a 100644
--- a/gateway-server/src/main/java/org/apache/hadoop/gateway/services/token/impl/DefaultTokenAuthorityService.java
+++ b/gateway-server/src/main/java/org/apache/hadoop/gateway/services/token/impl/DefaultTokenAuthorityService.java
@@ -50,11 +50,15 @@ public class DefaultTokenAuthorityService implements JWTokenAuthority, Service {
     return issueToken(p, null, algorithm);
   }
   
+  public JWTToken issueToken(Principal p, String audience, String algorithm) {
+    return issueToken(p, audience, algorithm, -1);
+  }
+  
   /* (non-Javadoc)
    * @see org.apache.hadoop.gateway.provider.federation.jwt.JWTokenAuthority#issueToken(java.security.Principal, java.lang.String, java.lang.String)
    */
   @Override
-  public JWTToken issueToken(Principal p, String audience, String algorithm) {
+  public JWTToken issueToken(Principal p, String audience, String algorithm, long expires) {
     String[] claimArray = new String[4];
     claimArray[0] = "HSSO";
     claimArray[1] = p.getName();
@@ -63,7 +67,12 @@ public class DefaultTokenAuthorityService implements JWTokenAuthority, Service {
     }
     claimArray[2] = audience;
     // TODO: make the validity period configurable
-    claimArray[3] = Long.toString( ( System.currentTimeMillis()/1000 ) + 300);
+    if (expires == -1) {
+      claimArray[3] = Long.toString( ( System.currentTimeMillis() ) + 30000);
+    }
+    else {
+      claimArray[3] = String.valueOf(expires);
+    }
 
     JWTToken token = null;
     if ("RS256".equals(algorithm)) {

http://git-wip-us.apache.org/repos/asf/incubator-knox/blob/b5f30206/gateway-spi/src/main/java/org/apache/hadoop/gateway/services/security/token/JWTokenAuthority.java
----------------------------------------------------------------------
diff --git a/gateway-spi/src/main/java/org/apache/hadoop/gateway/services/security/token/JWTokenAuthority.java b/gateway-spi/src/main/java/org/apache/hadoop/gateway/services/security/token/JWTokenAuthority.java
index e603ff3..f2e4a3d 100644
--- a/gateway-spi/src/main/java/org/apache/hadoop/gateway/services/security/token/JWTokenAuthority.java
+++ b/gateway-spi/src/main/java/org/apache/hadoop/gateway/services/security/token/JWTokenAuthority.java
@@ -25,12 +25,15 @@ import org.apache.hadoop.gateway.services.security.token.impl.JWTToken;
 
 public interface JWTokenAuthority {
 
-  public abstract JWTToken issueToken(Subject subject, String algorithm);
+  JWTToken issueToken(Subject subject, String algorithm);
 
-  public abstract JWTToken issueToken(Principal p, String algorithm);
+  JWTToken issueToken(Principal p, String algorithm);
 
-  public abstract JWTToken issueToken(Principal p, String audience,
+  JWTToken issueToken(Principal p, String audience,
       String algorithm);
 
-  public abstract boolean verifyToken(JWTToken token);
+  boolean verifyToken(JWTToken token);
+
+  JWTToken issueToken(Principal p, String audience, String algorithm,
+      long expires);
 }
\ No newline at end of file