You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@knox.apache.org by sm...@apache.org on 2022/09/08 07:24:51 UTC

[knox] branch master updated: KNOX-2800 - Knox token revocation should also work for impersonated tokens (#631)

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

smolnar 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 f4c2981ea KNOX-2800 - Knox token revocation should also work for impersonated tokens (#631)
f4c2981ea is described below

commit f4c2981ea22f9fea28c90a5b33cecdd95561918e
Author: Sandor Molnar <sm...@apache.org>
AuthorDate: Thu Sep 8 09:24:45 2022 +0200

    KNOX-2800 - Knox token revocation should also work for impersonated tokens (#631)
---
 .../gateway/service/knoxtoken/TokenResource.java   |  9 ++++++--
 .../knoxtoken/TokenServiceResourceTest.java        | 26 +++++++++++++++++++++-
 2 files changed, 32 insertions(+), 3 deletions(-)

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 ee8d10047..0bcf622b7 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
@@ -624,7 +624,8 @@ public class TokenResource {
   private boolean triesToRevokeOwnToken(String tokenId, String revoker) throws UnknownTokenException {
     final TokenMetadata metadata = tokenStateService.getTokenMetadata(tokenId);
     final String tokenUserName = metadata == null ? "" : metadata.getUserName();
-    return StringUtils.isNotBlank(revoker) && revoker.equals(tokenUserName);
+    final String tokenCreatedBy =  metadata == null ? "" : metadata.getCreatedBy();
+    return StringUtils.isNotBlank(revoker) && (revoker.equals(tokenUserName) || revoker.equals(tokenCreatedBy));
   }
 
   /*
@@ -770,7 +771,11 @@ public class TokenResource {
             // userTokens is an ordered collection (by issue time) -> the first element is the oldest one
             final String oldestTokenId = userTokens.iterator().next().getTokenId();
             log.generalInfoMessage(String.format(Locale.getDefault(), "Revoking %s's oldest token %s ...", userName, Tokens.getTokenIDDisplayText(oldestTokenId)));
-            revoke(oldestTokenId);
+            final Response revocationResponse = revoke(oldestTokenId);
+            if (Response.Status.OK.getStatusCode() != revocationResponse.getStatus()) {
+              return Response.status(Response.Status.fromStatusCode(revocationResponse.getStatus()))
+                  .entity("{\n  \"error\": \"An error occurred during the oldest token revocation of " + userName + " \"\n}\n").build();
+            }
            }
         }
       }
diff --git a/gateway-service-knoxtoken/src/test/java/org/apache/knox/gateway/service/knoxtoken/TokenServiceResourceTest.java b/gateway-service-knoxtoken/src/test/java/org/apache/knox/gateway/service/knoxtoken/TokenServiceResourceTest.java
index bf0626978..64db322e8 100644
--- a/gateway-service-knoxtoken/src/test/java/org/apache/knox/gateway/service/knoxtoken/TokenServiceResourceTest.java
+++ b/gateway-service-knoxtoken/src/test/java/org/apache/knox/gateway/service/knoxtoken/TokenServiceResourceTest.java
@@ -850,6 +850,12 @@ public class TokenServiceResourceTest {
     validateSuccessfulRevocationResponse(renewalResponse);
   }
 
+  @Test
+  public void testTokenRevocation_Enabled_RevokeImpersonatedToken() throws Exception {
+    final Response renewalResponse = doTestTokenRevocation(true, null, createTestSubject(USER_NAME), "impersonatedUserName");
+    validateSuccessfulRevocationResponse(renewalResponse);
+  }
+
   @Test
   public void testKidJkuClaims() throws Exception {
     final Map<String, String> contextExpectations = new HashMap<>();
@@ -1374,6 +1380,11 @@ public class TokenServiceResourceTest {
     return doTestTokenLifecyle(TokenLifecycleOperation.Revoke, isTokenStateServerManaged, renewers, caller);
   }
 
+  private Response doTestTokenRevocation(final Boolean isTokenStateServerManaged, final String renewers, final Subject caller, String impersonatedUser)
+      throws Exception {
+    return doTestTokenLifecyle(TokenLifecycleOperation.Revoke, isTokenStateServerManaged, null, renewers, null, caller, impersonatedUser).getValue();
+  }
+
   /**
    * @param operation     A TokenLifecycleOperation
    * @param serverManaged true, if server-side token state management should be enabled; Otherwise, false or null.
@@ -1411,6 +1422,11 @@ public class TokenServiceResourceTest {
     return doTestTokenLifecyle(operation, serviceLevelConfig, null, renewers, maxTokenLifetime, caller);
   }
 
+  private Map.Entry<TestTokenStateService, Response> doTestTokenLifecyle(final TokenLifecycleOperation operation, final Boolean serviceLevelConfig,
+      final Boolean gatewayLevelConfig, final String renewers, final Long maxTokenLifetime, final Subject caller) throws Exception {
+    return doTestTokenLifecyle(operation, serviceLevelConfig, gatewayLevelConfig, renewers, maxTokenLifetime, caller, null);
+  }
+
   /**
    * @param operation          A TokenLifecycleOperation
    * @param serviceLevelConfig true, if server-side token state management should be enabled at the service level;
@@ -1430,7 +1446,8 @@ public class TokenServiceResourceTest {
                                                                          final Boolean                 gatewayLevelConfig,
                                                                          final String                  renewers,
                                                                          final Long                    maxTokenLifetime,
-                                                                         final Subject                 caller) throws Exception {
+                                                                         final Subject                 caller,
+                                                                         final String impersonatedUser) throws Exception {
 
     final Map<String, String> contextExpectations = new HashMap<>();
     contextExpectations.put("knox.token.audiences", "recipient1,recipient2");
@@ -1444,6 +1461,13 @@ public class TokenServiceResourceTest {
     }
     contextExpectations.put("knox.token.renewer.whitelist", renewers);
 
+    if (StringUtils.isNotBlank(impersonatedUser)) {
+      contextExpectations.put(TokenResource.IMPERSONATION_ENABLED_PARAM, "true");
+      contextExpectations.put(TokenResource.QUERY_PARAMETER_DOAS, impersonatedUser);
+      contextExpectations.put(TokenResource.PROXYUSER_PREFIX + "." + USER_NAME + ".users", impersonatedUser);
+      contextExpectations.put(TokenResource.PROXYUSER_PREFIX + "." + USER_NAME + ".hosts", "*");
+    }
+
     configureCommonExpectations(contextExpectations, gatewayLevelConfig);
 
     TokenResource tr = new TokenResource();