|
@@ -60,6 +60,7 @@ import org.springframework.test.web.servlet.request.MockHttpServletRequestBuilde
|
|
|
|
|
|
import static org.assertj.core.api.Assertions.assertThat;
|
|
|
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
|
|
|
+import static org.hamcrest.Matchers.startsWith;
|
|
|
import static org.mockito.ArgumentMatchers.any;
|
|
|
import static org.mockito.ArgumentMatchers.anyString;
|
|
|
import static org.mockito.BDDMockito.given;
|
|
@@ -74,6 +75,7 @@ import static org.springframework.security.test.web.servlet.request.SecurityMock
|
|
|
import static org.springframework.security.test.web.servlet.response.SecurityMockMvcResultMatchers.authenticated;
|
|
|
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
|
|
|
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
|
|
|
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
|
|
|
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.cookie;
|
|
|
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.redirectedUrl;
|
|
|
|
|
@@ -334,6 +336,27 @@ public class RememberMeConfigurerTests {
|
|
|
verify(repository).saveContext(any(), any(), any());
|
|
|
}
|
|
|
|
|
|
+ @Test
|
|
|
+ public void rememberMeExpiresSessionWhenSessionManagementMaximumSessionsExceeds() throws Exception {
|
|
|
+ this.spring.register(RememberMeMaximumSessionsConfig.class).autowire();
|
|
|
+
|
|
|
+ MockHttpServletRequestBuilder loginRequest = post("/login").with(csrf())
|
|
|
+ .param("username", "user")
|
|
|
+ .param("password", "password")
|
|
|
+ .param("remember-me", "true");
|
|
|
+ MvcResult mvcResult = this.mvc.perform(loginRequest).andReturn();
|
|
|
+ Cookie rememberMeCookie = mvcResult.getResponse().getCookie("remember-me");
|
|
|
+ HttpSession session = mvcResult.getRequest().getSession();
|
|
|
+
|
|
|
+ MockHttpServletRequestBuilder exceedsMaximumSessionsRequest = get("/abc").cookie(rememberMeCookie);
|
|
|
+ this.mvc.perform(exceedsMaximumSessionsRequest);
|
|
|
+
|
|
|
+ MockHttpServletRequestBuilder sessionExpiredRequest = get("/abc").cookie(rememberMeCookie)
|
|
|
+ .session((MockHttpSession) session);
|
|
|
+ this.mvc.perform(sessionExpiredRequest)
|
|
|
+ .andExpect(content().string(startsWith("This session has been expired")));
|
|
|
+ }
|
|
|
+
|
|
|
@Configuration
|
|
|
@EnableWebSecurity
|
|
|
static class NullUserDetailsConfig {
|
|
@@ -617,6 +640,35 @@ public class RememberMeConfigurerTests {
|
|
|
|
|
|
}
|
|
|
|
|
|
+ @Configuration
|
|
|
+ @EnableWebSecurity
|
|
|
+ static class RememberMeMaximumSessionsConfig {
|
|
|
+
|
|
|
+ @Bean
|
|
|
+ SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
|
|
|
+ // @formatter:off
|
|
|
+ http
|
|
|
+ .authorizeRequests((authorizeRequests) ->
|
|
|
+ authorizeRequests
|
|
|
+ .anyRequest().hasRole("USER")
|
|
|
+ )
|
|
|
+ .sessionManagement((sessionManagement) ->
|
|
|
+ sessionManagement
|
|
|
+ .maximumSessions(1)
|
|
|
+ )
|
|
|
+ .formLogin(withDefaults())
|
|
|
+ .rememberMe(withDefaults());
|
|
|
+ return http.build();
|
|
|
+ // @formatter:on
|
|
|
+ }
|
|
|
+
|
|
|
+ @Bean
|
|
|
+ UserDetailsService userDetailsService() {
|
|
|
+ return new InMemoryUserDetailsManager(PasswordEncodedUser.user());
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
@Configuration
|
|
|
@EnableWebSecurity
|
|
|
static class SecurityContextRepositoryConfig {
|