Skip to content

SessionManagementFilter thread safety #5775

@daniloarcidiacono

Description

@daniloarcidiacono

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

Metadata

Metadata

Assignees

No one assigned

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions