SessionRegistryImpl can be used to track sessions. We can register new sessions with it. When the session expires it'll be automatically removed, because it implements ApplicationListener.

However, as of Servlet spec 3.1 it is possible to change the id of the current session without invalidating it by calling Session.changeSessionId(). But, SessionRegistryImpl will not be aware of the change and continues to have the older session id. The older session id will never be removed.

Comment From: eleftherias

@aj-jaswanth Please see my comments on the PR gh-5439.

Comment From: eleftherias

Use Case

Summary

When using the changeSessionId session fixation protection strategy (which is also the default) and setting the maximumSessions to 1, the expired session information is not removed from SessionRegistryImpl.

To reproduce this, while running in debug, log in using one tab and then log in with the same user in a different tab. Check the sessionIds list in SessionRegistryImpl.

Actual Behavior

Both the current session ID and the previously expired session ID are in the sessionIds list.

Expected Behavior

Only the current session ID should be in the sessionIds list.

Configuration

protected void configure(HttpSecurity http) throws Exception {
    http
        .authorizeRequests(authorize -> authorize
            .anyRequest().authenticated()
        )
        .sessionManagement(management -> management
            .sessionConcurrency(concurrency -> concurrency
                .maximumSessions(1)
            )
            .sessionFixation(fixation -> fixation
                .changeSessionId()
            )
        )
        .formLogin(withDefaults());
}
@Bean
public HttpSessionEventPublisher httpSessionEventPublisher() {
    return new HttpSessionEventPublisher();
}