Open
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());
}
}