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 <[email protected]>
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();