You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@knox.apache.org by mo...@apache.org on 2017/10/25 19:20:39 UTC
[03/17] knox git commit: KNOX-1082 - Add support to validate the
"nbf" claim for JWTs
KNOX-1082 - Add support to validate the "nbf" claim for JWTs
Project: http://git-wip-us.apache.org/repos/asf/knox/repo
Commit: http://git-wip-us.apache.org/repos/asf/knox/commit/bb467b8c
Tree: http://git-wip-us.apache.org/repos/asf/knox/tree/bb467b8c
Diff: http://git-wip-us.apache.org/repos/asf/knox/diff/bb467b8c
Branch: refs/heads/KNOX-998-Package_Restructuring
Commit: bb467b8c4ecd87fc83ec1cf2863767b0330f171e
Parents: 9c7aa7e
Author: Colm O hEigeartaigh <co...@apache.org>
Authored: Tue Oct 17 12:49:04 2017 +0100
Committer: Colm O hEigeartaigh <co...@apache.org>
Committed: Tue Oct 17 12:49:04 2017 +0100
----------------------------------------------------------------------
.../provider/federation/jwt/JWTMessages.java | 3 ++
.../jwt/filter/AbstractJWTFilter.java | 9 ++++-
.../federation/AbstractJWTFilterTest.java | 40 ++++++++++++++++++--
.../services/security/token/impl/JWT.java | 3 ++
.../services/security/token/impl/JWTToken.java | 11 ++++++
5 files changed, 61 insertions(+), 5 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/knox/blob/bb467b8c/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 f6969c6..f38d13b 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
@@ -34,6 +34,9 @@ public interface JWTMessages {
@Message( level = MessageLevel.INFO, text = "Access token has expired; a new one must be acquired." )
void tokenHasExpired();
+ @Message( level = MessageLevel.INFO, text = "The NotBefore check failed." )
+ void notBeforeCheckFailed();
+
@Message( level = MessageLevel.WARN, text = "Expected Bearer token is missing." )
void missingBearerToken();
http://git-wip-us.apache.org/repos/asf/knox/blob/bb467b8c/gateway-provider-security-jwt/src/main/java/org/apache/hadoop/gateway/provider/federation/jwt/filter/AbstractJWTFilter.java
----------------------------------------------------------------------
diff --git a/gateway-provider-security-jwt/src/main/java/org/apache/hadoop/gateway/provider/federation/jwt/filter/AbstractJWTFilter.java b/gateway-provider-security-jwt/src/main/java/org/apache/hadoop/gateway/provider/federation/jwt/filter/AbstractJWTFilter.java
index deb3d5b..0d8ecb8 100644
--- a/gateway-provider-security-jwt/src/main/java/org/apache/hadoop/gateway/provider/federation/jwt/filter/AbstractJWTFilter.java
+++ b/gateway-provider-security-jwt/src/main/java/org/apache/hadoop/gateway/provider/federation/jwt/filter/AbstractJWTFilter.java
@@ -275,7 +275,14 @@ public abstract class AbstractJWTFilter implements Filter {
if (tokenIsStillValid(token)) {
boolean audValid = validateAudiences(token);
if (audValid) {
- return true;
+ Date nbf = token.getNotBeforeDate();
+ if (nbf == null || new Date().after(nbf)) {
+ return true;
+ } else {
+ log.notBeforeCheckFailed();
+ handleValidationError(request, response, HttpServletResponse.SC_BAD_REQUEST,
+ "Bad request: the NotBefore check failed");
+ }
}
else {
log.failedToValidateAudience();
http://git-wip-us.apache.org/repos/asf/knox/blob/bb467b8c/gateway-provider-security-jwt/src/test/java/org/apache/hadoop/gateway/provider/federation/AbstractJWTFilterTest.java
----------------------------------------------------------------------
diff --git a/gateway-provider-security-jwt/src/test/java/org/apache/hadoop/gateway/provider/federation/AbstractJWTFilterTest.java b/gateway-provider-security-jwt/src/test/java/org/apache/hadoop/gateway/provider/federation/AbstractJWTFilterTest.java
index b261081..54c596b 100644
--- a/gateway-provider-security-jwt/src/test/java/org/apache/hadoop/gateway/provider/federation/AbstractJWTFilterTest.java
+++ b/gateway-provider-security-jwt/src/test/java/org/apache/hadoop/gateway/provider/federation/AbstractJWTFilterTest.java
@@ -505,7 +505,7 @@ public abstract class AbstractJWTFilterTest {
handler.init(new TestFilterConfig(props));
SignedJWT jwt = getJWT(AbstractJWTFilter.JWT_DEFAULT_ISSUER, "alice", new Date(new Date().getTime() + 5000),
- privateKey, JWSAlgorithm.RS512.getName());
+ new Date(), privateKey, JWSAlgorithm.RS512.getName());
HttpServletRequest request = EasyMock.createNiceMock(HttpServletRequest.class);
setTokenOnRequest(request, jwt);
@@ -536,7 +536,7 @@ public abstract class AbstractJWTFilterTest {
handler.init(new TestFilterConfig(props));
SignedJWT jwt = getJWT(AbstractJWTFilter.JWT_DEFAULT_ISSUER, "alice", new Date(new Date().getTime() + 5000),
- privateKey, JWSAlgorithm.RS384.getName());
+ new Date(), privateKey, JWSAlgorithm.RS384.getName());
HttpServletRequest request = EasyMock.createNiceMock(HttpServletRequest.class);
setTokenOnRequest(request, jwt);
@@ -558,6 +558,37 @@ public abstract class AbstractJWTFilterTest {
}
}
+ @Test
+ public void testNotBeforeJWT() throws Exception {
+ try {
+ Properties props = getProperties();
+ handler.init(new TestFilterConfig(props));
+
+ SignedJWT jwt = getJWT(AbstractJWTFilter.JWT_DEFAULT_ISSUER, "alice",
+ new Date(new Date().getTime() + 5000),
+ new Date(new Date().getTime() + 5000), privateKey,
+ JWSAlgorithm.RS256.getName());
+
+ HttpServletRequest request = EasyMock.createNiceMock(HttpServletRequest.class);
+ setTokenOnRequest(request, jwt);
+
+ EasyMock.expect(request.getRequestURL()).andReturn(
+ new StringBuffer(SERVICE_URL)).anyTimes();
+ EasyMock.expect(request.getQueryString()).andReturn(null);
+ HttpServletResponse response = EasyMock.createNiceMock(HttpServletResponse.class);
+ EasyMock.expect(response.encodeRedirectURL(SERVICE_URL)).andReturn(
+ SERVICE_URL);
+ EasyMock.replay(request);
+
+ TestFilterChain chain = new TestFilterChain();
+ handler.doFilter(request, response, chain);
+ Assert.assertTrue("doFilterCalled should not be false.", !chain.doFilterCalled);
+ Assert.assertTrue("No Subject should be returned.", chain.subject == null);
+ } catch (ServletException se) {
+ fail("Should NOT have thrown a ServletException.");
+ }
+ }
+
protected Properties getProperties() {
Properties props = new Properties();
props.setProperty(
@@ -568,10 +599,10 @@ public abstract class AbstractJWTFilterTest {
protected SignedJWT getJWT(String issuer, String sub, Date expires, RSAPrivateKey privateKey)
throws Exception {
- return getJWT(issuer, sub, expires, privateKey, JWSAlgorithm.RS256.getName());
+ return getJWT(issuer, sub, expires, new Date(), privateKey, JWSAlgorithm.RS256.getName());
}
- protected SignedJWT getJWT(String issuer, String sub, Date expires, RSAPrivateKey privateKey,
+ protected SignedJWT getJWT(String issuer, String sub, Date expires, Date nbf, RSAPrivateKey privateKey,
String signatureAlgorithm)
throws Exception {
List<String> aud = new ArrayList<String>();
@@ -582,6 +613,7 @@ public abstract class AbstractJWTFilterTest {
.subject(sub)
.audience(aud)
.expirationTime(expires)
+ .notBeforeTime(nbf)
.claim("scope", "openid")
.build();
http://git-wip-us.apache.org/repos/asf/knox/blob/bb467b8c/gateway-spi/src/main/java/org/apache/hadoop/gateway/services/security/token/impl/JWT.java
----------------------------------------------------------------------
diff --git a/gateway-spi/src/main/java/org/apache/hadoop/gateway/services/security/token/impl/JWT.java b/gateway-spi/src/main/java/org/apache/hadoop/gateway/services/security/token/impl/JWT.java
index 1a6f4f9..fa9076e 100644
--- a/gateway-spi/src/main/java/org/apache/hadoop/gateway/services/security/token/impl/JWT.java
+++ b/gateway-spi/src/main/java/org/apache/hadoop/gateway/services/security/token/impl/JWT.java
@@ -29,6 +29,7 @@ public interface JWT {
String ISSUER = "iss";
String AUDIENCE = "aud";
String EXPIRES = "exp";
+ String NOT_BEFORE = "nbf";
String getPayload();
@@ -50,6 +51,8 @@ public interface JWT {
Date getExpiresDate();
+ Date getNotBeforeDate();
+
String getSubject();
String getHeader();
http://git-wip-us.apache.org/repos/asf/knox/blob/bb467b8c/gateway-spi/src/main/java/org/apache/hadoop/gateway/services/security/token/impl/JWTToken.java
----------------------------------------------------------------------
diff --git a/gateway-spi/src/main/java/org/apache/hadoop/gateway/services/security/token/impl/JWTToken.java b/gateway-spi/src/main/java/org/apache/hadoop/gateway/services/security/token/impl/JWTToken.java
index be2a331..f985caf 100644
--- a/gateway-spi/src/main/java/org/apache/hadoop/gateway/services/security/token/impl/JWTToken.java
+++ b/gateway-spi/src/main/java/org/apache/hadoop/gateway/services/security/token/impl/JWTToken.java
@@ -231,6 +231,17 @@ public class JWTToken implements JWT {
return date;
}
+ @Override
+ public Date getNotBeforeDate() {
+ Date date = null;
+ try {
+ date = jwt.getJWTClaimsSet().getNotBeforeTime();
+ } catch (ParseException e) {
+ log.unableToParseToken(e);
+ }
+ return date;
+ }
+
/* (non-Javadoc)
* @see org.apache.hadoop.gateway.services.security.token.impl.JWT#getPrincipal()
*/