spring-projects / spring-projects/spring-security

Authenticating using same session does not clean up SessionRegistry

Open
#3,704 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

in: web type: bug
Dominant language
Java
Stars
9.6k
Forks
6.3k
Avg merge
2d 11h
Merged PRs (30d)
52

Description

Using the following configuration:

http
    .sessionManagement()
         .sessionFixation().changeSessionId()
         .maximumSessions(1)
         .maxSessionsPreventsLogin(true)

A user performs the following steps:

  • Open three tabs to a log in page
  • Authenticate in the first tab
  • Authenticate in the second tab
  • Authenticate in the third tab

The user is not allowed to authenticate. This happens for two reasons:

  • The second authentication is allowed only because we check to see if the current session is the same as one of the existing sessions in ConcurrentSessionControlAuthenticationStrategy this is why the error doesn't happen till the third authentication attempt
  • Currently authenticated users are not removed from the SessionRegistry

Users can work around this using the following:

http
    .sessionManagement()
         .withObjectPostProcessor(new AdditionalStrategyPostProcessor(new CleanRegistry(sessionRegistry)))
         .sessionFixation().changeSessionId()
         .maximumSessions(1)
         .maxSessionsPreventsLogin(true)
public class AdditionalStrategyPostProcessor 
       implements ObjectPostProcessor<CompositeSessionAuthenticationStrategy> {
    private final SessionAuthenticationStrategy delegate;

    public AdditionalStrategyPostProcessor(SessionAuthenticationStrategy delegate) {
        super();
        this.delegate = delegate;
    }
    public <O extends CompositeSessionAuthenticationStrategy> O postProcess(O object) {
        return (O) new CompositeSessionAuthenticationStrategy(Arrays.asList(delegate, object));
    }
}

public class CleanRegistry implements SessionAuthenticationStrategy {
    private SessionRegistry sessionRegistry;
    public CleanRegistry(SessionRegistry sessionRegistry) {
        super();
        this.sessionRegistry = sessionRegistry;
    }
    @Override
    public void onAuthentication(Authentication authentication, HttpServletRequest request,
            HttpServletResponse response) throws SessionAuthenticationException {
        HttpSession session = request.getSession(false);
        if(session == null) {
            return;
        }
        sessionRegistry.removeSessionInformation(session.getId());
    }
}

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by reading ConcurrentSessionControlAuthenticationStrategy and the SessionRegistry usage in Spring Security's session-management authentication flow. Reproduce the three-tab login sequence with the stated configuration, then verify that the registry no longer retains the session after re-authentication and that the third login is handled correctly.

Written by the indexing model from the issue text.

Assessment

Tech stack
java, spring
Domain
authentication, security
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Stale
Clarity
Clearly specified
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.