1
0
mirror of synced 2026-08-07 10:47:49 +00:00

Use SessionAuthenticationStrategy for Remember-Me authentication

Closes gh-2253
This commit is contained in:
xhaggi
2024-09-06 08:30:45 +02:00
committed by Josh Cummings
parent d37d41c130
commit 7f537241e7
4 changed files with 96 additions and 0 deletions
@@ -37,6 +37,8 @@ import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.context.SecurityContextHolderStrategy;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.security.web.authentication.RememberMeServices;
import org.springframework.security.web.authentication.session.NullAuthenticatedSessionStrategy;
import org.springframework.security.web.authentication.session.SessionAuthenticationStrategy;
import org.springframework.security.web.context.HttpSessionSecurityContextRepository;
import org.springframework.security.web.context.SecurityContextRepository;
import org.springframework.util.Assert;
@@ -81,6 +83,8 @@ public class RememberMeAuthenticationFilter extends GenericFilterBean implements
private SecurityContextRepository securityContextRepository = new HttpSessionSecurityContextRepository();
private SessionAuthenticationStrategy sessionStrategy = new NullAuthenticatedSessionStrategy();
public RememberMeAuthenticationFilter(AuthenticationManager authenticationManager,
RememberMeServices rememberMeServices) {
Assert.notNull(authenticationManager, "authenticationManager cannot be null");
@@ -115,6 +119,7 @@ public class RememberMeAuthenticationFilter extends GenericFilterBean implements
// Attempt authentication via AuthenticationManager
try {
rememberMeAuth = this.authenticationManager.authenticate(rememberMeAuth);
this.sessionStrategy.onAuthentication(rememberMeAuth, request, response);
// Store to SecurityContextHolder
SecurityContext context = this.securityContextHolderStrategy.createEmptyContext();
context.setAuthentication(rememberMeAuth);
@@ -211,4 +216,17 @@ public class RememberMeAuthenticationFilter extends GenericFilterBean implements
this.securityContextHolderStrategy = securityContextHolderStrategy;
}
/**
* The session handling strategy which will be invoked immediately after an
* authentication request is successfully processed by the
* <tt>AuthenticationManager</tt>. Used, for example, to handle changing of the
* session identifier to prevent session fixation attacks.
* @param sessionStrategy the implementation to use. If not set a null implementation
* is used.
*/
public void setSessionAuthenticationStrategy(SessionAuthenticationStrategy sessionStrategy) {
Assert.notNull(sessionStrategy, "sessionStrategy cannot be null");
this.sessionStrategy = sessionStrategy;
}
}
@@ -35,6 +35,7 @@ import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.authentication.NullRememberMeServices;
import org.springframework.security.web.authentication.RememberMeServices;
import org.springframework.security.web.authentication.SimpleUrlAuthenticationSuccessHandler;
import org.springframework.security.web.authentication.session.SessionAuthenticationStrategy;
import org.springframework.security.web.context.SecurityContextRepository;
import static org.assertj.core.api.Assertions.assertThat;
@@ -170,6 +171,23 @@ public class RememberMeAuthenticationFilterTests {
verify(securityContextRepository).saveContext(any(), eq(request), eq(response));
}
@Test
public void sessionAuthenticationStrategyInvokedIfSet() throws Exception {
SessionAuthenticationStrategy sessionAuthenticationStrategy = mock(SessionAuthenticationStrategy.class);
AuthenticationManager am = mock(AuthenticationManager.class);
given(am.authenticate(this.remembered)).willReturn(this.remembered);
RememberMeAuthenticationFilter filter = new RememberMeAuthenticationFilter(am,
new MockRememberMeServices(this.remembered));
filter.setAuthenticationSuccessHandler(new SimpleUrlAuthenticationSuccessHandler("/target"));
filter.setSessionAuthenticationStrategy(sessionAuthenticationStrategy);
MockHttpServletRequest request = new MockHttpServletRequest();
MockHttpServletResponse response = new MockHttpServletResponse();
FilterChain fc = mock(FilterChain.class);
request.setRequestURI("x");
filter.doFilter(request, response, fc);
verify(sessionAuthenticationStrategy).onAuthentication(any(), eq(request), eq(response));
}
private class MockRememberMeServices implements RememberMeServices {
private Authentication authToReturn;