From 2c251293a1abb484441ca6db593e64572d8cb009 Mon Sep 17 00:00:00 2001 From: Joaquin Santana Date: Mon, 13 May 2024 17:09:34 +0200 Subject: [PATCH 1/2] Update InvalidateLeastUsedServerMaximumSessionsExceededHandler.java this change prevents from deleting the current session to, creating the need to log in two times. --- .../InvalidateLeastUsedServerMaximumSessionsExceededHandler.java | 1 + 1 file changed, 1 insertion(+) diff --git a/web/src/main/java/org/springframework/security/web/server/authentication/InvalidateLeastUsedServerMaximumSessionsExceededHandler.java b/web/src/main/java/org/springframework/security/web/server/authentication/InvalidateLeastUsedServerMaximumSessionsExceededHandler.java index 28446df993e..7f1c9fb7efb 100644 --- a/web/src/main/java/org/springframework/security/web/server/authentication/InvalidateLeastUsedServerMaximumSessionsExceededHandler.java +++ b/web/src/main/java/org/springframework/security/web/server/authentication/InvalidateLeastUsedServerMaximumSessionsExceededHandler.java @@ -54,6 +54,7 @@ public Mono handle(MaximumSessionsContext context) { maximumSessionsExceededBy); return Flux.fromIterable(leastRecentlyUsedSessionsToInvalidate) + .filter(toInvalidate -> !toInvalidate.getSessionId().equals(context.getCurrentSession().getId())) .flatMap((toInvalidate) -> toInvalidate.invalidate().thenReturn(toInvalidate)) .flatMap((toInvalidate) -> this.webSessionStore.removeSession(toInvalidate.getSessionId())) .then(); From 72ba6a486a66ce1d5dab8918472c0101e9d9855d Mon Sep 17 00:00:00 2001 From: Joaquin Santana Date: Mon, 13 May 2024 18:08:58 +0200 Subject: [PATCH 2/2] more elegant --- ...dServerMaximumSessionsExceededHandler.java | 39 +++++++++++-------- 1 file changed, 22 insertions(+), 17 deletions(-) diff --git a/web/src/main/java/org/springframework/security/web/server/authentication/InvalidateLeastUsedServerMaximumSessionsExceededHandler.java b/web/src/main/java/org/springframework/security/web/server/authentication/InvalidateLeastUsedServerMaximumSessionsExceededHandler.java index 7f1c9fb7efb..84d180b6d57 100644 --- a/web/src/main/java/org/springframework/security/web/server/authentication/InvalidateLeastUsedServerMaximumSessionsExceededHandler.java +++ b/web/src/main/java/org/springframework/security/web/server/authentication/InvalidateLeastUsedServerMaximumSessionsExceededHandler.java @@ -16,15 +16,17 @@ package org.springframework.security.web.server.authentication; -import java.util.ArrayList; -import java.util.Comparator; -import java.util.List; - +import org.springframework.security.core.session.ReactiveSessionInformation; +import org.springframework.security.web.server.authentication.MaximumSessionsContext; +import org.springframework.security.web.server.authentication.ServerMaximumSessionsExceededHandler; +import org.springframework.web.server.session.WebSessionStore; import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; -import org.springframework.security.core.session.ReactiveSessionInformation; -import org.springframework.web.server.session.WebSessionStore; +import java.util.ArrayList; +import java.util.Comparator; +import java.util.List; +import java.util.stream.Collectors; /** * Implementation of {@link ServerMaximumSessionsExceededHandler} that invalidates the @@ -47,17 +49,20 @@ public InvalidateLeastUsedServerMaximumSessionsExceededHandler(WebSessionStore w @Override public Mono handle(MaximumSessionsContext context) { - List sessions = new ArrayList<>(context.getSessions()); - sessions.sort(Comparator.comparing(ReactiveSessionInformation::getLastAccessTime)); - int maximumSessionsExceededBy = sessions.size() - context.getMaximumSessionsAllowed() + 1; - List leastRecentlyUsedSessionsToInvalidate = sessions.subList(0, - maximumSessionsExceededBy); - - return Flux.fromIterable(leastRecentlyUsedSessionsToInvalidate) - .filter(toInvalidate -> !toInvalidate.getSessionId().equals(context.getCurrentSession().getId())) - .flatMap((toInvalidate) -> toInvalidate.invalidate().thenReturn(toInvalidate)) - .flatMap((toInvalidate) -> this.webSessionStore.removeSession(toInvalidate.getSessionId())) - .then(); + List sessions = context.getSessions().stream() + .filter(toFilter -> !toFilter.getSessionId().equals(context.getCurrentSession().getId())) + .sorted(Comparator.comparing(ReactiveSessionInformation::getLastAccessTime)) + .collect(Collectors.toCollection(ArrayList::new)); + + int maximumSessionsExceededBy = sessions.size() - context.getMaximumSessionsAllowed() + 1; + + List leastRecentlyUsedSessionsToInvalidate = sessions.subList(0, + maximumSessionsExceededBy); + + return Flux.fromIterable(leastRecentlyUsedSessionsToInvalidate) + .flatMap(toInvalidate -> toInvalidate.invalidate().thenReturn(toInvalidate)) + .flatMap(toInvalidate -> this.webSessionStore.removeSession(toInvalidate.getSessionId())) + .then(); } }