This is an automated email from the ASF dual-hosted git repository. pzampino pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/knox.git
The following commit(s) were added to refs/heads/master by this push: new 7ca30e0 KNOX-2352 - Knox Token State Eviction Should Be Based on Expiration and Extended Default Grace Period (#321) 7ca30e0 is described below commit 7ca30e00680a4c3c41dc8269542a3f608f8c42a8 Author: Phil Zampino <pzamp...@apache.org> AuthorDate: Wed Apr 22 11:04:55 2020 -0400 KNOX-2352 - Knox Token State Eviction Should Be Based on Expiration and Extended Default Grace Period (#321) --- .../gateway/config/impl/GatewayConfigImpl.java | 2 +- .../token/impl/DefaultTokenStateService.java | 24 +++++++++++----------- .../token/impl/DefaultTokenStateServiceTest.java | 4 ++-- .../gateway/service/knoxtoken/TokenResource.java | 10 +++++++-- .../service/knoxtoken/TokenServiceMessages.java | 8 ++++---- 5 files changed, 27 insertions(+), 21 deletions(-) diff --git a/gateway-server/src/main/java/org/apache/knox/gateway/config/impl/GatewayConfigImpl.java b/gateway-server/src/main/java/org/apache/knox/gateway/config/impl/GatewayConfigImpl.java index 951d8d4..e9a9a00 100644 --- a/gateway-server/src/main/java/org/apache/knox/gateway/config/impl/GatewayConfigImpl.java +++ b/gateway-server/src/main/java/org/apache/knox/gateway/config/impl/GatewayConfigImpl.java @@ -249,7 +249,7 @@ public class GatewayConfigImpl extends Configuration implements GatewayConfig { private static final String KNOX_TOKEN_EVICTION_GRACE_PERIOD = GATEWAY_CONFIG_FILE_PREFIX + ".knox.token.eviction.grace.period"; private static final String KNOX_TOKEN_PERMISSIVE_VALIDATION_ENABLED = GATEWAY_CONFIG_FILE_PREFIX + ".knox.token.permissive.validation"; private static final long KNOX_TOKEN_EVICTION_INTERVAL_DEFAULT = TimeUnit.MINUTES.toSeconds(5); - private static final long KNOX_TOKEN_EVICTION_GRACE_PERIOD_DEFAULT = TimeUnit.MINUTES.toSeconds(5); + private static final long KNOX_TOKEN_EVICTION_GRACE_PERIOD_DEFAULT = TimeUnit.HOURS.toSeconds(24); private static final boolean KNOX_TOKEN_PERMISSIVE_VALIDATION_ENABLED_DEFAULT = false; private static final String KNOX_HOMEPAGE_HIDDEN_TOPOLOGIES = "knox.homepage.hidden.topologies"; diff --git a/gateway-server/src/main/java/org/apache/knox/gateway/services/token/impl/DefaultTokenStateService.java b/gateway-server/src/main/java/org/apache/knox/gateway/services/token/impl/DefaultTokenStateService.java index 7397a68..ad1f892 100644 --- a/gateway-server/src/main/java/org/apache/knox/gateway/services/token/impl/DefaultTokenStateService.java +++ b/gateway-server/src/main/java/org/apache/knox/gateway/services/token/impl/DefaultTokenStateService.java @@ -39,7 +39,7 @@ import java.util.concurrent.TimeUnit; */ public class DefaultTokenStateService implements TokenStateService { - protected static final long DEFAULT_RENEWAL_INTERVAL = 24 * 60 * 60 * 1000L; // 24 hours + protected static final long DEFAULT_RENEWAL_INTERVAL = TimeUnit.HOURS.toMillis(24); protected static final int MAX_RENEWALS = 7; @@ -51,11 +51,13 @@ public class DefaultTokenStateService implements TokenStateService { private final Map<String, Long> maxTokenLifetimes = new HashMap<>(); - /* token eviction interval in seconds */ + // Token eviction interval (in seconds) private long tokenEvictionInterval; - /* grace period (in seconds) after which an expired token should be evicted */ + + // Grace period (in seconds) after which an expired token should be evicted private long tokenEvictionGracePeriod; - /* should knox token fail permissively */ + + // Knox token validation permissiveness protected boolean permissiveValidationEnabled; private final ScheduledExecutorService evictionScheduler = Executors.newScheduledThreadPool(1); @@ -71,8 +73,8 @@ public class DefaultTokenStateService implements TokenStateService { @Override public void start() throws ServiceLifecycleException { if (tokenEvictionInterval > 0) { - /* run token eviction task at configured intervals */ - evictionScheduler.scheduleAtFixedRate(() -> evictExpiredTokens(), tokenEvictionInterval, tokenEvictionInterval, TimeUnit.SECONDS); + // Run token eviction task at configured interval + evictionScheduler.scheduleAtFixedRate(this::evictExpiredTokens, tokenEvictionInterval, tokenEvictionInterval, TimeUnit.SECONDS); } } @@ -311,16 +313,14 @@ public class DefaultTokenStateService implements TokenStateService { * Method that checks if a token's state is a candidate for eviction. * * @param tokenId A unique token identifier - * @throws UnknownTokenException Exception if token is not found. + * @throws UnknownTokenException if token state is not found. * * @return true, if the associated token state can be evicted; Otherwise, false. */ protected boolean needsEviction(final String tokenId) throws UnknownTokenException { - long maxLifetime = getMaxLifetime(tokenId); - if (maxLifetime <= 0) { - throw new UnknownTokenException(tokenId); - } - return ((maxLifetime + TimeUnit.SECONDS.toMillis(tokenEvictionGracePeriod)) <= System.currentTimeMillis()); + // If the expiration time(+ grace period) has already passed, it should be considered expired + long expirationWithGrace = getTokenExpiration(tokenId) + TimeUnit.SECONDS.toMillis(tokenEvictionGracePeriod); + return (expirationWithGrace <= System.currentTimeMillis()); } /** diff --git a/gateway-server/src/test/java/org/apache/knox/gateway/services/token/impl/DefaultTokenStateServiceTest.java b/gateway-server/src/test/java/org/apache/knox/gateway/services/token/impl/DefaultTokenStateServiceTest.java index d7306f2..1935da8 100644 --- a/gateway-server/src/test/java/org/apache/knox/gateway/services/token/impl/DefaultTokenStateServiceTest.java +++ b/gateway-server/src/test/java/org/apache/knox/gateway/services/token/impl/DefaultTokenStateServiceTest.java @@ -185,7 +185,7 @@ public class DefaultTokenStateServiceTest { // Sleep to allow the eviction evaluation to be performed prior to the maximum token lifetime Thread.sleep(evictionInterval + (evictionInterval / 2)); - // Renewal should succeed because there is sufficient time until max lifetime is exceeded + // Renewal should succeed because there is sufficient time until expiration + grace period is exceeded tss.renewToken(token, TimeUnit.SECONDS.toMillis(10)); assertFalse("Expected the token to have been renewed.", tss.isExpired(token)); } @@ -196,7 +196,7 @@ public class DefaultTokenStateServiceTest { final TokenStateService tss = createTokenStateService(); final long evictionInterval = TimeUnit.SECONDS.toMillis(3); - final long maxTokenLifetime = evictionInterval / 2; + final long maxTokenLifetime = evictionInterval * 3; try { tss.start(); diff --git a/gateway-service-knoxtoken/src/main/java/org/apache/knox/gateway/service/knoxtoken/TokenResource.java b/gateway-service-knoxtoken/src/main/java/org/apache/knox/gateway/service/knoxtoken/TokenResource.java index 2647420..9d5f4e2 100644 --- a/gateway-service-knoxtoken/src/main/java/org/apache/knox/gateway/service/knoxtoken/TokenResource.java +++ b/gateway-service-knoxtoken/src/main/java/org/apache/knox/gateway/service/knoxtoken/TokenResource.java @@ -253,7 +253,10 @@ public class TokenResource { // If renewal fails, it should be an exception expiration = tokenStateService.renewToken(jwt, renewInterval.orElse(tokenStateService.getDefaultRenewInterval())); - log.renewedToken(getTopologyName(), TokenUtils.getTokenDisplayText(token), TokenUtils.getTokenId(jwt)); + log.renewedToken(getTopologyName(), + TokenUtils.getTokenDisplayText(token), + TokenUtils.getTokenId(jwt), + renewer); } catch (ParseException e) { log.invalidToken(getTopologyName(), TokenUtils.getTokenDisplayText(token), e); error = safeGetMessage(e); @@ -297,7 +300,10 @@ public class TokenResource { try { JWTToken jwt = new JWTToken(token); tokenStateService.revokeToken(jwt); - log.revokedToken(getTopologyName(), TokenUtils.getTokenDisplayText(token), TokenUtils.getTokenId(jwt)); + log.revokedToken(getTopologyName(), + TokenUtils.getTokenDisplayText(token), + TokenUtils.getTokenId(jwt), + renewer); } catch (ParseException e) { log.invalidToken(getTopologyName(), TokenUtils.getTokenDisplayText(token), e); error = safeGetMessage(e); diff --git a/gateway-service-knoxtoken/src/main/java/org/apache/knox/gateway/service/knoxtoken/TokenServiceMessages.java b/gateway-service-knoxtoken/src/main/java/org/apache/knox/gateway/service/knoxtoken/TokenServiceMessages.java index 60ee4ba..afffafc 100644 --- a/gateway-service-knoxtoken/src/main/java/org/apache/knox/gateway/service/knoxtoken/TokenServiceMessages.java +++ b/gateway-service-knoxtoken/src/main/java/org/apache/knox/gateway/service/knoxtoken/TokenServiceMessages.java @@ -30,11 +30,11 @@ public interface TokenServiceMessages { @Message( level = MessageLevel.INFO, text = "Knox Token service ({0}) issued token {1} ({2})") void issuedToken(String topologyName, String tokenDisplayText, String tokenId); - @Message( level = MessageLevel.INFO, text = "Knox Token service ({0}) renewed the expiration for token {1} ({2})") - void renewedToken(String topologyName, String tokenDisplayText, String tokenId); + @Message( level = MessageLevel.INFO, text = "Knox Token service ({0}) renewed the expiration for token {1} ({2}) (renewer={3})") + void renewedToken(String topologyName, String tokenDisplayText, String tokenId, String renewer); - @Message( level = MessageLevel.INFO, text = "Knox Token service ({0}) revoked token {1} ({2})") - void revokedToken(String topologyName, String tokenDisplayText, String tokenId); + @Message( level = MessageLevel.INFO, text = "Knox Token service ({0}) revoked token {1} ({2}) (renewer={3})") + void revokedToken(String topologyName, String tokenDisplayText, String tokenId, String renewer); @Message( level = MessageLevel.ERROR, text = "Unable to issue token.") void unableToIssueToken(@StackTrace( level = MessageLevel.DEBUG) Exception e);