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 fbed6e7cf KNOX-2970 - Removing KnoxSSO cookie from the token state 
service upon logout (#806)
fbed6e7cf is described below

commit fbed6e7cf095f3e5f6328163de15e5925544372d
Author: Sandor Molnar <[email protected]>
AuthorDate: Thu Oct 19 20:00:46 2023 +0200

    KNOX-2970 - Removing KnoxSSO cookie from the token state service upon 
logout (#806)
    
    Additionally, the Token Management UI displays the 'current' KnoxSSO cookie 
row in bold.
---
 .../jwt/filter/SSOCookieFederationFilter.java      |  2 ++
 .../gateway/service/knoxsso/KnoxSSOutMessages.java |  3 +++
 .../gateway/service/knoxsso/WebSSOutResource.java  | 29 ++++++++++++++++++++++
 .../service/session/SessionInformation.java        | 11 ++++++++
 .../gateway/service/session/SessionResource.java   |  4 ++-
 .../services/security/token/TokenUtils.java        |  1 +
 .../token-management/app/session.information.ts    |  1 +
 .../app/token.management.component.html            |  8 +++---
 .../app/token.management.component.ts              | 14 +++++++++--
 9 files changed, 66 insertions(+), 7 deletions(-)

diff --git 
a/gateway-provider-security-jwt/src/main/java/org/apache/knox/gateway/provider/federation/jwt/filter/SSOCookieFederationFilter.java
 
b/gateway-provider-security-jwt/src/main/java/org/apache/knox/gateway/provider/federation/jwt/filter/SSOCookieFederationFilter.java
index 81d6e1a97..e329037de 100644
--- 
a/gateway-provider-security-jwt/src/main/java/org/apache/knox/gateway/provider/federation/jwt/filter/SSOCookieFederationFilter.java
+++ 
b/gateway-provider-security-jwt/src/main/java/org/apache/knox/gateway/provider/federation/jwt/filter/SSOCookieFederationFilter.java
@@ -22,6 +22,7 @@ import org.apache.knox.gateway.config.GatewayConfig;
 import org.apache.knox.gateway.i18n.messages.MessagesFactory;
 import org.apache.knox.gateway.provider.federation.jwt.JWTMessages;
 import org.apache.knox.gateway.security.PrimaryPrincipal;
+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.JWT;
 import org.apache.knox.gateway.services.security.token.impl.JWTToken;
@@ -165,6 +166,7 @@ public class SSOCookieFederationFilter extends 
AbstractJWTFilter {
           JWT token = new JWTToken(wireToken);
           if (validateToken(req, res, chain, token)) {
             Subject subject = createSubjectFromToken(token);
+            
request.setAttribute(TokenUtils.ATTR_CURRENT_KNOXSSO_COOKIE_TOKEN_ID, 
token.getClaim(JWTToken.KNOX_ID_CLAIM));
             continueWithEstablishedSecurityContext(subject, req, res, chain);
 
             // we found a valid cookie we don't need to keep checking anymore
diff --git 
a/gateway-service-knoxssout/src/main/java/org/apache/knox/gateway/service/knoxsso/KnoxSSOutMessages.java
 
b/gateway-service-knoxssout/src/main/java/org/apache/knox/gateway/service/knoxsso/KnoxSSOutMessages.java
index e94dab897..72ce31217 100644
--- 
a/gateway-service-knoxssout/src/main/java/org/apache/knox/gateway/service/knoxsso/KnoxSSOutMessages.java
+++ 
b/gateway-service-knoxssout/src/main/java/org/apache/knox/gateway/service/knoxsso/KnoxSSOutMessages.java
@@ -28,4 +28,7 @@ public interface KnoxSSOutMessages {
 
   @Message(level = MessageLevel.WARN, text = "Could not find cookie with the 
name: {0} in the request to be removed from the concurrent session counter for 
user: {1}. ")
   void couldNotFindCookieWithTokenToRemove(String cookieName, String username);
+
+  @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);
 }
\ No newline at end of file
diff --git 
a/gateway-service-knoxssout/src/main/java/org/apache/knox/gateway/service/knoxsso/WebSSOutResource.java
 
b/gateway-service-knoxssout/src/main/java/org/apache/knox/gateway/service/knoxsso/WebSSOutResource.java
index 0ce423760..72f2ffcc0 100644
--- 
a/gateway-service-knoxssout/src/main/java/org/apache/knox/gateway/service/knoxsso/WebSSOutResource.java
+++ 
b/gateway-service-knoxssout/src/main/java/org/apache/knox/gateway/service/knoxsso/WebSSOutResource.java
@@ -18,9 +18,15 @@
 package org.apache.knox.gateway.service.knoxsso;
 
 import org.apache.knox.gateway.i18n.messages.MessagesFactory;
+import org.apache.knox.gateway.security.SubjectUtils;
 import org.apache.knox.gateway.services.GatewayServices;
 import org.apache.knox.gateway.services.ServiceType;
+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.session.control.ConcurrentSessionVerifier;
+import org.apache.knox.gateway.util.Tokens;
 import org.apache.knox.gateway.util.Urls;
 
 import javax.annotation.PostConstruct;
@@ -35,6 +41,7 @@ import javax.ws.rs.Produces;
 import javax.ws.rs.core.Context;
 import javax.ws.rs.core.Response;
 import java.net.MalformedURLException;
+import java.text.ParseException;
 import java.util.Arrays;
 import java.util.Optional;
 
@@ -118,6 +125,7 @@ public class WebSSOutResource {
       if (gwServices != null) {
         ConcurrentSessionVerifier verifier = 
gwServices.getService(ServiceType.CONCURRENT_SESSION_VERIFIER);
         verifier.sessionEndedForUser(request.getUserPrincipal().getName(), 
ssoCookie.get().getValue());
+        removeKnoxSsoCookie(ssoCookie.get(), gwServices);
       }
     } else {
       log.couldNotFindCookieWithTokenToRemove(cookieName, 
request.getUserPrincipal().getName());
@@ -125,6 +133,27 @@ public class WebSSOutResource {
     return rc;
   }
 
+  private void removeKnoxSsoCookie(Cookie ssoCookie, GatewayServices 
gwServices) {
+    final TokenStateService tokenStateService = 
gwServices.getService(ServiceType.TOKEN_STATE_SERVICE);
+    if (tokenStateService!= null) {
+      try {
+        final JWTToken jwt = new JWTToken(ssoCookie.getValue());
+        tokenStateService.revokeToken(jwt);
+        final String revoker = SubjectUtils.getCurrentEffectivePrincipalName();
+        log.revokedToken(getTopologyName(),
+            Tokens.getTokenDisplayText(ssoCookie.getValue()),
+            Tokens.getTokenIDDisplayText(TokenUtils.getTokenId(jwt)),
+            revoker);
+      } catch (ParseException | UnknownTokenException e) {
+        // NOP: cookie maybe invalid or token management was disabled anyway
+      }
+    }
+  }
+
+  private String getTopologyName() {
+    return (String) 
context.getAttribute("org.apache.knox.gateway.gateway.cluster");
+  }
+
   private Optional<Cookie> findCookie(String cookieName) {
     Cookie[] cookies = request.getCookies();
     if (cookies != null) {
diff --git 
a/gateway-service-session/src/main/java/org/apache/knox/gateway/service/session/SessionInformation.java
 
b/gateway-service-session/src/main/java/org/apache/knox/gateway/service/session/SessionInformation.java
index 9ebba4632..d572ebf5d 100644
--- 
a/gateway-service-session/src/main/java/org/apache/knox/gateway/service/session/SessionInformation.java
+++ 
b/gateway-service-session/src/main/java/org/apache/knox/gateway/service/session/SessionInformation.java
@@ -37,6 +37,9 @@ public class SessionInformation {
   @XmlElement
   private boolean canSeeAllTokens;
 
+  @XmlElement
+  private String currentKnoxSsoCookieTokenId;
+
   public String getUser() {
     return user;
   }
@@ -77,4 +80,12 @@ public class SessionInformation {
     this.canSeeAllTokens = canSeeAllTokens;
   }
 
+  public String getCurrentKnoxSsoCookieTokenId() {
+    return currentKnoxSsoCookieTokenId;
+  }
+
+  public void setCurrentKnoxSsoCookieTokenId(String 
currentKnoxSsoCookieTokenId) {
+    this.currentKnoxSsoCookieTokenId = currentKnoxSsoCookieTokenId;
+  }
+
 }
diff --git 
a/gateway-service-session/src/main/java/org/apache/knox/gateway/service/session/SessionResource.java
 
b/gateway-service-session/src/main/java/org/apache/knox/gateway/service/session/SessionResource.java
index 1d1500294..40dda8e81 100644
--- 
a/gateway-service-session/src/main/java/org/apache/knox/gateway/service/session/SessionResource.java
+++ 
b/gateway-service-session/src/main/java/org/apache/knox/gateway/service/session/SessionResource.java
@@ -31,6 +31,7 @@ import javax.ws.rs.core.Context;
 import org.apache.knox.gateway.config.GatewayConfig;
 import org.apache.knox.gateway.i18n.messages.MessagesFactory;
 import org.apache.knox.gateway.security.SubjectUtils;
+import org.apache.knox.gateway.services.security.token.TokenUtils;
 
 @Singleton
 @Path("session/api/v1/")
@@ -57,8 +58,9 @@ public class SessionResource {
       sessionInfo.setLogoutUrl(logoutUrl);
       sessionInfo.setLogoutPageUrl(getLogoutPageUrl(config));
       sessionInfo.setGlobalLogoutPageUrl(getGlobalLogoutPageUrl(config));
-      sessionInfo.setCanSeeAllTokens(config.canSeeAllTokens(user));
     }
+    sessionInfo.setCanSeeAllTokens(config != null ? 
config.canSeeAllTokens(user) : false);
+    sessionInfo.setCurrentKnoxSsoCookieTokenId((String) 
this.request.getAttribute(TokenUtils.ATTR_CURRENT_KNOXSSO_COOKIE_TOKEN_ID));
 
     return sessionInfo;
   }
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 4ba1defb0..e9620a425 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
@@ -33,6 +33,7 @@ import java.security.interfaces.RSAPublicKey;
 import java.util.LinkedHashMap;
 
 public class TokenUtils {
+  public static final String ATTR_CURRENT_KNOXSSO_COOKIE_TOKEN_ID = 
"currentKnoxSsoCookieTokenId";
   public static final String SIGNING_HMAC_SECRET_ALIAS = 
"gateway.signing.hmac.secret";
   private static final String DEFAULT_RSA_SIG_ALG = "RS256";
   private static final String DEFAULT_HMAC_SIG_ALG = "HS256";
diff --git 
a/knox-token-management-ui/token-management/app/session.information.ts 
b/knox-token-management-ui/token-management/app/session.information.ts
index 3d748deaf..7d64b026b 100644
--- a/knox-token-management-ui/token-management/app/session.information.ts
+++ b/knox-token-management-ui/token-management/app/session.information.ts
@@ -21,4 +21,5 @@ export class SessionInformation {
     logoutPageUrl: string;
     globalLgoutPageUrl: string;
     canSeeAllTokens: boolean;
+    currentKnoxSsoCookieTokenId: string;
 }
diff --git 
a/knox-token-management-ui/token-management/app/token.management.component.html 
b/knox-token-management-ui/token-management/app/token.management.component.html
index 49a0debd4..ca93fef22 100644
--- 
a/knox-token-management-ui/token-management/app/token.management.component.html
+++ 
b/knox-token-management-ui/token-management/app/token.management.component.html
@@ -59,7 +59,7 @@
 
             <ng-container matColumnDef="tokenId">
                 <mat-header-cell *matHeaderCellDef mat-sort-header="tokenId" 
style="text-align: center; justify-content: center;">Token ID</mat-header-cell>
-                <mat-cell *matCellDef="let knoxToken" style="text-align: 
center; justify-content: center;">
+                <mat-cell *matCellDef="let knoxToken" style="text-align: 
center; justify-content: center;" 
[style.font-weight]="getFontWeight(knoxToken)">
                   <div 
*ngIf="knoxToken.metadata.enabled">{{knoxToken.tokenId}}</div>
                   <div *ngIf="!knoxToken.metadata.enabled" 
style="color:orange">{{knoxToken.tokenId}}</div>
                 </mat-cell>
@@ -67,17 +67,17 @@
 
             <ng-container matColumnDef="issued">
                 <mat-header-cell *matHeaderCellDef mat-sort-header="issueTime" 
style="text-align: center; justify-content: center;">Issued</mat-header-cell>
-                <mat-cell *matCellDef="let knoxToken" style="text-align: 
center; justify-content: 
center;">{{formatDateTime(knoxToken.issueTimeLong)}}</mat-cell>
+                <mat-cell *matCellDef="let knoxToken" style="text-align: 
center; justify-content: center;" 
[style.font-weight]="getFontWeight(knoxToken)">{{formatDateTime(knoxToken.issueTimeLong)}}</mat-cell>
             </ng-container>
 
             <ng-container matColumnDef="expires">
                 <mat-header-cell *matHeaderCellDef 
mat-sort-header="expiration" style="text-align: center; justify-content: 
center;">Expires</mat-header-cell>
-                <mat-cell *matCellDef="let knoxToken" 
[style.color]="getExpirationColor(knoxToken.expirationLong)" style="text-align: 
center; justify-content: 
center;">{{formatDateTime(knoxToken.expirationLong)}}</mat-cell>
+                <mat-cell *matCellDef="let knoxToken" 
[style.color]="getExpirationColor(knoxToken.expirationLong)" style="text-align: 
center; justify-content: center;" 
[style.font-weight]="getFontWeight(knoxToken)">{{formatDateTime(knoxToken.expirationLong)}}</mat-cell>
             </ng-container>
 
             <ng-container matColumnDef="userName">
                 <mat-header-cell *matHeaderCellDef mat-sort-header="userName" 
style="text-align: center; justify-content: center;">User Name</mat-header-cell>
-                <mat-cell *matCellDef="let knoxToken" style="text-align: 
center; justify-content: center;">{{knoxToken.metadata.userName}}</mat-cell>
+                <mat-cell *matCellDef="let knoxToken" style="text-align: 
center; justify-content: center;" 
[style.font-weight]="getFontWeight(knoxToken)">{{knoxToken.metadata.userName}}</mat-cell>
             </ng-container>
 
             <ng-container matColumnDef="impersonated">
diff --git 
a/knox-token-management-ui/token-management/app/token.management.component.ts 
b/knox-token-management-ui/token-management/app/token.management.component.ts
index edc5f3493..daa210127 100644
--- 
a/knox-token-management-ui/token-management/app/token.management.component.ts
+++ 
b/knox-token-management-ui/token-management/app/token.management.component.ts
@@ -38,6 +38,7 @@ export class TokenManagementComponent implements OnInit {
 
     userName: string;
     canSeeAllTokens: boolean;
+    currentKnoxSsoCookieTokenId: string;
     knoxTokens: MatTableDataSource<KnoxToken> = new MatTableDataSource();
     selection = new SelectionModel<KnoxToken>(true, []);
     allKnoxTokens: KnoxToken[];
@@ -104,8 +105,9 @@ export class TokenManagementComponent implements OnInit {
         console.debug('TokenManagementComponent --> ngOnInit()');
         this.tokenManagementService.getSessionInformation()
             .then(sessionInformation => {
-                 this.canSeeAllTokens = sessionInformation.canSeeAllTokens;
-                 this.setUserName(sessionInformation.user);
+              this.canSeeAllTokens = sessionInformation.canSeeAllTokens;
+              this.currentKnoxSsoCookieTokenId = 
sessionInformation.currentKnoxSsoCookieTokenId;
+              this.setUserName(sessionInformation.user);
             });
     }
 
@@ -270,4 +272,12 @@ export class TokenManagementComponent implements OnInit {
         return this.selection.selected.every(token => 
!token.metadata.knoxSsoCookie);
     }
 
+    getFontWeight(token: KnoxToken): string {
+        return this.isCurrentKnoxSsoCookietoken(token) ? 'bold' : 'normal';
+    }
+
+    private isCurrentKnoxSsoCookietoken(token: KnoxToken): boolean {
+        return this.isKnoxSsoCookie(token) && token.tokenId === 
this.currentKnoxSsoCookieTokenId;
+    }
+
 }

Reply via email to