Update Max Sessions on WebFlux

Delete WebSessionStoreReactiveSessionRegistry.java and gives the responsibility to remove the sessions from the WebSessionStore to the handler

Issue gh-6192
This commit is contained in:
Marcus Hert Da Coregio
2024-02-28 10:06:45 -03:00
parent f3bcf7ed5d
commit f8ff056eb6
10 changed files with 331 additions and 580 deletions

View File

@@ -34,9 +34,8 @@ import org.springframework.security.config.annotation.web.reactive.EnableWebFlux
import org.springframework.security.config.test.SpringTestContext;
import org.springframework.security.config.test.SpringTestContextExtension;
import org.springframework.security.config.users.ReactiveAuthenticationTestConfiguration;
import org.springframework.security.core.session.ReactiveSessionInformation;
import org.springframework.security.core.session.InMemoryReactiveSessionRegistry;
import org.springframework.security.core.session.ReactiveSessionRegistry;
import org.springframework.security.core.userdetails.PasswordEncodedUser;
import org.springframework.security.oauth2.client.authentication.OAuth2LoginAuthenticationToken;
import org.springframework.security.oauth2.client.registration.InMemoryReactiveClientRegistrationRepository;
import org.springframework.security.oauth2.client.registration.TestClientRegistrations;
@@ -52,10 +51,8 @@ import org.springframework.security.web.server.authentication.InvalidateLeastUse
import org.springframework.security.web.server.authentication.PreventLoginServerMaximumSessionsExceededHandler;
import org.springframework.security.web.server.authentication.RedirectServerAuthenticationSuccessHandler;
import org.springframework.security.web.server.authentication.ServerAuthenticationConverter;
import org.springframework.security.web.server.authentication.ServerAuthenticationSuccessHandler;
import org.springframework.security.web.server.authentication.SessionLimit;
import org.springframework.security.web.server.context.WebSessionServerSecurityContextRepository;
import org.springframework.security.web.session.WebSessionStoreReactiveSessionRegistry;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import org.springframework.test.web.reactive.server.WebTestClient;
import org.springframework.util.LinkedMultiValueMap;
@@ -322,45 +319,6 @@ public class SessionManagementSpecTests {
// @formatter:on
}
@Test
void loginWhenUnlimitedSessionsButSessionsInvalidatedManuallyThenInvalidates() {
ConcurrentSessionsMaxSessionPreventsLoginFalseConfig.sessionLimit = SessionLimit.UNLIMITED;
this.spring.register(ConcurrentSessionsMaxSessionPreventsLoginFalseConfig.class).autowire();
MultiValueMap<String, String> data = new LinkedMultiValueMap<>();
data.add("username", "user");
data.add("password", "password");
ResponseCookie firstLogin = loginReturningCookie(data);
ResponseCookie secondLogin = loginReturningCookie(data);
this.client.get().uri("/").cookie(firstLogin.getName(), firstLogin.getValue()).exchange().expectStatus().isOk();
this.client.get()
.uri("/")
.cookie(secondLogin.getName(), secondLogin.getValue())
.exchange()
.expectStatus()
.isOk();
ReactiveSessionRegistry sessionRegistry = this.spring.getContext().getBean(ReactiveSessionRegistry.class);
sessionRegistry.getAllSessions(PasswordEncodedUser.user())
.flatMap(ReactiveSessionInformation::invalidate)
.blockLast();
this.client.get()
.uri("/")
.cookie(firstLogin.getName(), firstLogin.getValue())
.exchange()
.expectStatus()
.isFound()
.expectHeader()
.location("/login");
this.client.get()
.uri("/")
.cookie(secondLogin.getName(), secondLogin.getValue())
.exchange()
.expectStatus()
.isFound()
.expectHeader()
.location("/login");
}
@Test
void oauth2LoginWhenMaxSessionDoesNotPreventLoginThenSecondLoginSucceedsAndFirstSessionIsInvalidated() {
OAuth2LoginConcurrentSessionsConfig.maxSessions = 1;
@@ -490,10 +448,9 @@ public class SessionManagementSpecTests {
ServerOAuth2AuthorizationRequestResolver resolver = mock(ServerOAuth2AuthorizationRequestResolver.class);
ServerAuthenticationSuccessHandler successHandler = mock(ServerAuthenticationSuccessHandler.class);
@Bean
SecurityWebFilterChain springSecurityFilter(ServerHttpSecurity http) {
SecurityWebFilterChain springSecurityFilter(ServerHttpSecurity http,
DefaultWebSessionManager webSessionManager) {
// @formatter:off
http
.authorizeExchange((exchanges) -> exchanges
@@ -509,7 +466,7 @@ public class SessionManagementSpecTests {
.maximumSessions(SessionLimit.of(maxSessions))
.maximumSessionsExceededHandler(preventLogin
? new PreventLoginServerMaximumSessionsExceededHandler()
: new InvalidateLeastUsedServerMaximumSessionsExceededHandler())
: new InvalidateLeastUsedServerMaximumSessionsExceededHandler(webSessionManager.getSessionStore()))
)
);
// @formatter:on
@@ -611,8 +568,8 @@ public class SessionManagementSpecTests {
}
@Bean
ReactiveSessionRegistry reactiveSessionRegistry(DefaultWebSessionManager webSessionManager) {
return new WebSessionStoreReactiveSessionRegistry(webSessionManager.getSessionStore());
ReactiveSessionRegistry reactiveSessionRegistry() {
return new InMemoryReactiveSessionRegistry();
}
}