I'm facing some problems with concurrent session management, in particular when multiple concurrent requests are performed. Using this configuration:
http
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.IF_REQUIRED)
.maximumSessions(1)
.sessionRegistry(sessionRegistry)
.maxSessionsPreventsLogin(true)
a given user can create only one session at a time. It works, but when I try to login multiple times with many threads, the checks performed by ConcurrentSessionControlAuthenticationStrategy are bypassed. Looking at the implementation it seems that this class is not designed with thread-safety in mind:
final List<SessionInformation> sessions = sessionRegistry.getAllSessions(
authentication.getPrincipal(), false);
int sessionCount = sessions.size();
int allowedSessions = getMaximumSessionsForThisUser(authentication);
if (sessionCount < allowedSessions) {
// They haven't got too many login sessions running at present
return;
}
if (allowedSessions == -1) {
// We permit unlimited logins
return;
}
Using an aspect to wrap the session authentication strategy inside a synchronized block fixes the problem, but I wonder if there is a better approach (or some configuration I've missed).
I've created a Spring Boot sample application reproducing the bug, hosted in this GitHub repository. The main class is PeakTest along with force-sync property (please note that due to the non-deterministic nature of the test, results change between runs).
Thanks
I'm facing some problems with concurrent session management, in particular when multiple concurrent requests are performed. Using this configuration:
a given user can create only one session at a time. It works, but when I try to login multiple times with many threads, the checks performed by
ConcurrentSessionControlAuthenticationStrategyare bypassed. Looking at the implementation it seems that this class is not designed with thread-safety in mind:Using an aspect to wrap the session authentication strategy inside a synchronized block fixes the problem, but I wonder if there is a better approach (or some configuration I've missed).
I've created a Spring Boot sample application reproducing the bug, hosted in this GitHub repository. The main class is
PeakTestalong withforce-syncproperty (please note that due to the non-deterministic nature of the test, results change between runs).Thanks