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 2127c3a KNOX-2461 - Move JWT token display utility to module shared by server and client modules (#379) 2127c3a is described below commit 2127c3a14bcc1344e3dcc4142941e8964abd2b74 Author: Phil Zampino <pzamp...@apache.org> AuthorDate: Thu Oct 1 09:17:37 2020 -0400 KNOX-2461 - Move JWT token display utility to module shared by server and client modules (#379) --- .../test/knoxtoken/KnoxTokenWorkerThread.java | 6 ++-- .../federation/jwt/filter/AbstractJWTFilter.java | 3 +- .../jwt/filter/AccessTokenFederationFilter.java | 3 +- .../gateway/service/knoxtoken/TokenResource.java | 21 +++++------ .../services/security/token/TokenUtils.java | 13 ------- .../java/org/apache/knox/gateway/util/Tokens.java | 42 ++++++++++++++++++++++ 6 files changed, 60 insertions(+), 28 deletions(-) diff --git a/gateway-performance-test/src/main/java/org/apache/knox/gateway/performance/test/knoxtoken/KnoxTokenWorkerThread.java b/gateway-performance-test/src/main/java/org/apache/knox/gateway/performance/test/knoxtoken/KnoxTokenWorkerThread.java index ae3a91b..893a200 100644 --- a/gateway-performance-test/src/main/java/org/apache/knox/gateway/performance/test/knoxtoken/KnoxTokenWorkerThread.java +++ b/gateway-performance-test/src/main/java/org/apache/knox/gateway/performance/test/knoxtoken/KnoxTokenWorkerThread.java @@ -33,7 +33,6 @@ import org.apache.knox.gateway.i18n.messages.MessagesFactory; import org.apache.knox.gateway.performance.test.PerformanceTestConfiguration; import org.apache.knox.gateway.performance.test.PerformanceTestMessages; import org.apache.knox.gateway.performance.test.ResponseTimeCache; -import org.apache.knox.gateway.services.security.token.TokenUtils; import org.apache.knox.gateway.shell.ErrorResponse; import org.apache.knox.gateway.shell.KnoxSession; import org.apache.knox.gateway.shell.KnoxShellException; @@ -42,6 +41,7 @@ import org.apache.knox.gateway.shell.knox.token.Get; import org.apache.knox.gateway.shell.knox.token.Token; import org.apache.knox.gateway.shell.knox.token.TokenLifecycleResponse; import org.apache.knox.gateway.util.JsonUtils; +import org.apache.knox.gateway.util.Tokens; @SuppressWarnings("PMD.DoNotUseThreads") public class KnoxTokenWorkerThread implements Runnable { @@ -139,7 +139,7 @@ public class KnoxTokenWorkerThread implements Runnable { private void renewKnoxToken(KnoxSession knoxSession) throws Exception { final String knoxTokenToRenew = this.knoxTokenCache.getKnoxToken(); if (knoxTokenToRenew != null) { - LOG.renewKnoxToken(TokenUtils.getTokenDisplayText(knoxTokenToRenew)); + LOG.renewKnoxToken(Tokens.getTokenDisplayText(knoxTokenToRenew)); final long renewStart = System.currentTimeMillis(); final TokenLifecycleResponse renewResponse = Token.renew(knoxSession, knoxTokenToRenew).now(); final long renewResponseTime = System.currentTimeMillis() - renewStart; @@ -160,7 +160,7 @@ public class KnoxTokenWorkerThread implements Runnable { try { final String knoxToken = this.knoxTokenCache.getKnoxToken(); if (knoxToken != null) { - LOG.useKnoxToken(TokenUtils.getTokenDisplayText(knoxToken)); + LOG.useKnoxToken(Tokens.getTokenDisplayText(knoxToken)); Hdfs.ls(knoxSession).knoxToken(knoxToken).now(); } else { LOG.nothingToUse(); diff --git a/gateway-provider-security-jwt/src/main/java/org/apache/knox/gateway/provider/federation/jwt/filter/AbstractJWTFilter.java b/gateway-provider-security-jwt/src/main/java/org/apache/knox/gateway/provider/federation/jwt/filter/AbstractJWTFilter.java index dc222bf..5473ed2 100644 --- a/gateway-provider-security-jwt/src/main/java/org/apache/knox/gateway/provider/federation/jwt/filter/AbstractJWTFilter.java +++ b/gateway-provider-security-jwt/src/main/java/org/apache/knox/gateway/provider/federation/jwt/filter/AbstractJWTFilter.java @@ -64,6 +64,7 @@ import org.apache.knox.gateway.services.security.token.impl.JWT; import org.apache.knox.gateway.services.security.token.impl.JWTToken; import com.nimbusds.jose.JWSHeader; +import org.apache.knox.gateway.util.Tokens; public abstract class AbstractJWTFilter implements Filter { /** @@ -290,7 +291,7 @@ public abstract class AbstractJWTFilter implements Filter { } final String tokenId = TokenUtils.getTokenId(token); - final String displayableToken = TokenUtils.getTokenDisplayText(token.toString()); + final String displayableToken = Tokens.getTokenDisplayText(token.toString()); if (verified) { // confirm that issue matches intended target if (expectedIssuer.equals(token.getIssuer())) { diff --git a/gateway-provider-security-jwt/src/main/java/org/apache/knox/gateway/provider/federation/jwt/filter/AccessTokenFederationFilter.java b/gateway-provider-security-jwt/src/main/java/org/apache/knox/gateway/provider/federation/jwt/filter/AccessTokenFederationFilter.java index 4daae0f..ea67c01 100644 --- a/gateway-provider-security-jwt/src/main/java/org/apache/knox/gateway/provider/federation/jwt/filter/AccessTokenFederationFilter.java +++ b/gateway-provider-security-jwt/src/main/java/org/apache/knox/gateway/provider/federation/jwt/filter/AccessTokenFederationFilter.java @@ -28,6 +28,7 @@ import org.apache.knox.gateway.services.security.token.TokenStateService; import org.apache.knox.gateway.services.security.token.TokenUtils; import org.apache.knox.gateway.services.security.token.UnknownTokenException; import org.apache.knox.gateway.services.security.token.impl.JWTToken; +import org.apache.knox.gateway.util.Tokens; import javax.security.auth.Subject; import javax.servlet.Filter; @@ -91,7 +92,7 @@ public class AccessTokenFederationFilter implements Filter { } final String tokenId = TokenUtils.getTokenId(token); - final String displayableToken = TokenUtils.getTokenDisplayText(token.toString()); + final String displayableToken = Tokens.getTokenDisplayText(token.toString()); if (verified) { try { if (!isExpired(token)) { 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 57a6996..59fbc28 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 @@ -56,6 +56,7 @@ import org.apache.knox.gateway.services.security.token.UnknownTokenException; import org.apache.knox.gateway.services.security.token.impl.JWT; import org.apache.knox.gateway.services.security.token.impl.JWTToken; import org.apache.knox.gateway.util.JsonUtils; +import org.apache.knox.gateway.util.Tokens; import static javax.ws.rs.core.MediaType.APPLICATION_JSON; import static javax.ws.rs.core.MediaType.APPLICATION_XML; @@ -247,10 +248,10 @@ public class TokenResource { // If the token state service is disabled, then return the expiration from the specified token try { JWTToken jwt = new JWTToken(token); - log.renewalDisabled(getTopologyName(), TokenUtils.getTokenDisplayText(token), TokenUtils.getTokenId(jwt)); + log.renewalDisabled(getTopologyName(), Tokens.getTokenDisplayText(token), TokenUtils.getTokenId(jwt)); expiration = Long.parseLong(jwt.getExpires()); } catch (ParseException e) { - log.invalidToken(getTopologyName(), TokenUtils.getTokenDisplayText(token), e); + log.invalidToken(getTopologyName(), Tokens.getTokenDisplayText(token), e); error = safeGetMessage(e); } catch (Exception e) { error = safeGetMessage(e); @@ -264,11 +265,11 @@ public class TokenResource { expiration = tokenStateService.renewToken(jwt, renewInterval.orElse(tokenStateService.getDefaultRenewInterval())); log.renewedToken(getTopologyName(), - TokenUtils.getTokenDisplayText(token), + Tokens.getTokenDisplayText(token), TokenUtils.getTokenId(jwt), renewer); } catch (ParseException e) { - log.invalidToken(getTopologyName(), TokenUtils.getTokenDisplayText(token), e); + log.invalidToken(getTopologyName(), Tokens.getTokenDisplayText(token), e); error = safeGetMessage(e); } catch (Exception e) { error = safeGetMessage(e); @@ -284,7 +285,7 @@ public class TokenResource { .entity("{\n \"renewed\": \"true\",\n \"expires\": \"" + expiration + "\"\n}\n") .build(); } else { - log.badRenewalRequest(getTopologyName(), TokenUtils.getTokenDisplayText(token), error); + log.badRenewalRequest(getTopologyName(), Tokens.getTokenDisplayText(token), error); resp = Response.status(errorStatus) .entity("{\n \"renewed\": \"false\",\n \"error\": \"" + error + "\"\n}\n") .build(); @@ -311,11 +312,11 @@ public class TokenResource { JWTToken jwt = new JWTToken(token); tokenStateService.revokeToken(jwt); log.revokedToken(getTopologyName(), - TokenUtils.getTokenDisplayText(token), + Tokens.getTokenDisplayText(token), TokenUtils.getTokenId(jwt), renewer); } catch (ParseException e) { - log.invalidToken(getTopologyName(), TokenUtils.getTokenDisplayText(token), e); + log.invalidToken(getTopologyName(), Tokens.getTokenDisplayText(token), e); error = safeGetMessage(e); } catch (UnknownTokenException e) { error = safeGetMessage(e); @@ -331,7 +332,7 @@ public class TokenResource { .entity("{\n \"revoked\": \"true\"\n}\n") .build(); } else { - log.badRevocationRequest(getTopologyName(), TokenUtils.getTokenDisplayText(token), error); + log.badRevocationRequest(getTopologyName(), Tokens.getTokenDisplayText(token), error); resp = Response.status(errorStatus) .entity("{\n \"revoked\": \"false\",\n \"error\": \"" + error + "\"\n}\n") .build(); @@ -397,7 +398,7 @@ public class TokenResource { if (token != null) { String accessToken = token.toString(); String tokenId = TokenUtils.getTokenId(token); - log.issuedToken(getTopologyName(), TokenUtils.getTokenDisplayText(accessToken), tokenId); + log.issuedToken(getTopologyName(), Tokens.getTokenDisplayText(accessToken), tokenId); HashMap<String, Object> map = new HashMap<>(); map.put(ACCESS_TOKEN, accessToken); @@ -421,7 +422,7 @@ public class TokenResource { System.currentTimeMillis(), expires, maxTokenLifetime.orElse(tokenStateService.getDefaultMaxLifetimeDuration())); - log.storedToken(getTopologyName(), TokenUtils.getTokenDisplayText(accessToken), tokenId); + log.storedToken(getTopologyName(), Tokens.getTokenDisplayText(accessToken), tokenId); } return Response.ok().entity(jsonResponse).build(); diff --git a/gateway-spi/src/main/java/org/apache/knox/gateway/services/security/token/TokenUtils.java b/gateway-spi/src/main/java/org/apache/knox/gateway/services/security/token/TokenUtils.java index dd054d9..00bfebd 100644 --- a/gateway-spi/src/main/java/org/apache/knox/gateway/services/security/token/TokenUtils.java +++ b/gateway-spi/src/main/java/org/apache/knox/gateway/services/security/token/TokenUtils.java @@ -22,24 +22,11 @@ import org.apache.knox.gateway.services.security.token.impl.JWTToken; import javax.servlet.FilterConfig; import javax.servlet.ServletContext; -import java.util.Locale; public class TokenUtils { /** - * Get a String derived from a JWT String, which is suitable for presentation (e.g., logging) without compromising - * security. - * - * @param token A BASE64-encoded JWT String. - * - * @return An abbreviated form of the specified JWT String. - */ - public static String getTokenDisplayText(final String token) { - return String.format(Locale.ROOT, "%s...%s", token.substring(0, 6), token.substring(token.length() - 6)); - } - - /** * Extract the unique Knox token identifier from the specified JWT's claim set. * * @param token A JWT diff --git a/gateway-util-common/src/main/java/org/apache/knox/gateway/util/Tokens.java b/gateway-util-common/src/main/java/org/apache/knox/gateway/util/Tokens.java new file mode 100644 index 0000000..77e2918 --- /dev/null +++ b/gateway-util-common/src/main/java/org/apache/knox/gateway/util/Tokens.java @@ -0,0 +1,42 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with this + * work for additional information regarding copyright ownership. The ASF + * licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package org.apache.knox.gateway.util; + +import java.util.Locale; + +public class Tokens { + + /** + * Get a String derived from a JWT String, which is suitable for presentation (e.g., logging) without compromising + * security. + * + * @param token A BASE64-encoded JWT String. + * + * @return An abbreviated form of the specified JWT String. + */ + public static String getTokenDisplayText(final String token) { + String displayText = null; + if (token !=null) { + if (token.length() >= 7) { // Avoid empty or otherwise invalid values that would break this + displayText = + String.format(Locale.ROOT, "%s...%s", token.substring(0, 6), token.substring(token.length() - 6)); + } + } + return displayText; + } + +}