diff --git a/config/src/test/java/org/springframework/security/config/annotation/web/configurers/ott/OneTimeTokenLoginConfigurerTests.java b/config/src/test/java/org/springframework/security/config/annotation/web/configurers/ott/OneTimeTokenLoginConfigurerTests.java index b3c97b9201..2d3441e674 100644 --- a/config/src/test/java/org/springframework/security/config/annotation/web/configurers/ott/OneTimeTokenLoginConfigurerTests.java +++ b/config/src/test/java/org/springframework/security/config/annotation/web/configurers/ott/OneTimeTokenLoginConfigurerTests.java @@ -78,7 +78,7 @@ public class OneTimeTokenLoginConfigurerTests { this.mvc.perform(post("/ott/generate").param("username", "user").with(csrf())) .andExpectAll(status().isFound(), redirectedUrl("/login/ott")); - String token = TestOneTimeTokenGenerationSuccessHandler.lastToken.getTokenValue(); + String token = getLastToken().getTokenValue(); this.mvc.perform(post("/login/ott").param("token", token).with(csrf())) .andExpectAll(status().isFound(), redirectedUrl("/"), authenticated()); @@ -90,7 +90,7 @@ public class OneTimeTokenLoginConfigurerTests { this.mvc.perform(post("/generateurl").param("username", "user").with(csrf())) .andExpectAll(status().isFound(), redirectedUrl("/redirected")); - String token = TestOneTimeTokenGenerationSuccessHandler.lastToken.getTokenValue(); + String token = getLastToken().getTokenValue(); this.mvc.perform(post("/loginprocessingurl").param("token", token).with(csrf())) .andExpectAll(status().isFound(), redirectedUrl("/authenticated"), authenticated()); @@ -102,7 +102,7 @@ public class OneTimeTokenLoginConfigurerTests { this.mvc.perform(post("/ott/generate").param("username", "user").with(csrf())) .andExpectAll(status().isFound(), redirectedUrl("/login/ott")); - String token = TestOneTimeTokenGenerationSuccessHandler.lastToken.getTokenValue(); + String token = getLastToken().getTokenValue(); this.mvc.perform(post("/login/ott").param("token", token).with(csrf())) .andExpectAll(status().isFound(), redirectedUrl("/"), authenticated()); @@ -206,7 +206,7 @@ public class OneTimeTokenLoginConfigurerTests { this.mvc.perform(post("/ott/generate").param("username", "user").with(csrf())) .andExpectAll(status().isFound(), redirectedUrl("/login/ott")); - OneTimeToken token = TestOneTimeTokenGenerationSuccessHandler.lastToken; + OneTimeToken token = getLastToken(); this.mvc.perform(post("/login/ott").param("token", token.getTokenValue()).with(csrf())) .andExpectAll(status().isFound(), redirectedUrl("/"), authenticated()); @@ -219,25 +219,37 @@ public class OneTimeTokenLoginConfigurerTests { return expiresMinutes - currentMinutes; } + private OneTimeToken getLastToken() { + OneTimeToken lastToken = this.spring.getContext() + .getBean(TestOneTimeTokenGenerationSuccessHandler.class).lastToken; + return lastToken; + } + @Configuration(proxyBeanMethods = false) @EnableWebSecurity @Import(UserDetailsServiceConfig.class) static class OneTimeTokenConfigWithCustomTokenExpirationTime { @Bean - SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { + SecurityFilterChain securityFilterChain(HttpSecurity http, + OneTimeTokenGenerationSuccessHandler ottSuccessHandler) throws Exception { // @formatter:off http .authorizeHttpRequests((authz) -> authz .anyRequest().authenticated() ) .oneTimeTokenLogin((ott) -> ott - .tokenGenerationSuccessHandler(new TestOneTimeTokenGenerationSuccessHandler()) + .tokenGenerationSuccessHandler(ottSuccessHandler) ); // @formatter:on return http.build(); } + @Bean + TestOneTimeTokenGenerationSuccessHandler ottSuccessHandler() { + return new TestOneTimeTokenGenerationSuccessHandler(); + } + @Bean GenerateOneTimeTokenRequestResolver generateOneTimeTokenRequestResolver() { DefaultGenerateOneTimeTokenRequestResolver delegate = new DefaultGenerateOneTimeTokenRequestResolver(); @@ -255,19 +267,25 @@ public class OneTimeTokenLoginConfigurerTests { static class OneTimeTokenDefaultConfig { @Bean - SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { + SecurityFilterChain securityFilterChain(HttpSecurity http, + OneTimeTokenGenerationSuccessHandler ottSuccessHandler) throws Exception { // @formatter:off http .authorizeHttpRequests((authz) -> authz .anyRequest().authenticated() ) .oneTimeTokenLogin((ott) -> ott - .tokenGenerationSuccessHandler(new TestOneTimeTokenGenerationSuccessHandler()) + .tokenGenerationSuccessHandler(ottSuccessHandler) ); // @formatter:on return http.build(); } + @Bean + TestOneTimeTokenGenerationSuccessHandler ottSuccessHandler() { + return new TestOneTimeTokenGenerationSuccessHandler(); + } + } @Configuration(proxyBeanMethods = false) @@ -276,7 +294,8 @@ public class OneTimeTokenLoginConfigurerTests { static class OneTimeTokenDifferentUrlsConfig { @Bean - SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { + SecurityFilterChain securityFilterChain(HttpSecurity http, + OneTimeTokenGenerationSuccessHandler ottSuccessHandler) throws Exception { // @formatter:off http .authorizeHttpRequests((authz) -> authz @@ -284,7 +303,7 @@ public class OneTimeTokenLoginConfigurerTests { ) .oneTimeTokenLogin((ott) -> ott .tokenGeneratingUrl("/generateurl") - .tokenGenerationSuccessHandler(new TestOneTimeTokenGenerationSuccessHandler("/redirected")) + .tokenGenerationSuccessHandler(ottSuccessHandler) .loginProcessingUrl("/loginprocessingurl") .authenticationSuccessHandler(new SimpleUrlAuthenticationSuccessHandler("/authenticated")) ); @@ -292,6 +311,11 @@ public class OneTimeTokenLoginConfigurerTests { return http.build(); } + @Bean + TestOneTimeTokenGenerationSuccessHandler ottSuccessHandler() { + return new TestOneTimeTokenGenerationSuccessHandler("/redirected"); + } + } @Configuration(proxyBeanMethods = false) @@ -300,7 +324,8 @@ public class OneTimeTokenLoginConfigurerTests { static class OneTimeTokenFormLoginConfig { @Bean - SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { + SecurityFilterChain securityFilterChain(HttpSecurity http, + OneTimeTokenGenerationSuccessHandler ottSuccessHandler) throws Exception { // @formatter:off http .authorizeHttpRequests((authz) -> authz @@ -308,12 +333,17 @@ public class OneTimeTokenLoginConfigurerTests { ) .formLogin(Customizer.withDefaults()) .oneTimeTokenLogin((ott) -> ott - .tokenGenerationSuccessHandler(new TestOneTimeTokenGenerationSuccessHandler()) + .tokenGenerationSuccessHandler(ottSuccessHandler) ); // @formatter:on return http.build(); } + @Bean + TestOneTimeTokenGenerationSuccessHandler ottSuccessHandler() { + return new TestOneTimeTokenGenerationSuccessHandler(); + } + } @Configuration(proxyBeanMethods = false) @@ -337,7 +367,7 @@ public class OneTimeTokenLoginConfigurerTests { static class TestOneTimeTokenGenerationSuccessHandler implements OneTimeTokenGenerationSuccessHandler { - private static OneTimeToken lastToken; + private OneTimeToken lastToken; private final OneTimeTokenGenerationSuccessHandler delegate; @@ -352,7 +382,7 @@ public class OneTimeTokenLoginConfigurerTests { @Override public void handle(HttpServletRequest request, HttpServletResponse response, OneTimeToken oneTimeToken) throws IOException, ServletException { - lastToken = oneTimeToken; + this.lastToken = oneTimeToken; this.delegate.handle(request, response, oneTimeToken); } diff --git a/config/src/test/kotlin/org/springframework/security/config/annotation/web/OneTimeTokenLoginDslTests.kt b/config/src/test/kotlin/org/springframework/security/config/annotation/web/OneTimeTokenLoginDslTests.kt index a8b52c5137..12bacc47e2 100644 --- a/config/src/test/kotlin/org/springframework/security/config/annotation/web/OneTimeTokenLoginDslTests.kt +++ b/config/src/test/kotlin/org/springframework/security/config/annotation/web/OneTimeTokenLoginDslTests.kt @@ -74,7 +74,7 @@ class OneTimeTokenLoginDslTests { .redirectedUrl("/login/ott") ) - val token = TestOneTimeTokenGenerationSuccessHandler.lastToken?.tokenValue + val token = getLastToken().tokenValue this.mockMvc.perform( MockMvcRequestBuilders.post("/login/ott").param("token", token) @@ -96,7 +96,7 @@ class OneTimeTokenLoginDslTests { ) .andExpectAll(MockMvcResultMatchers.status().isFound(), MockMvcResultMatchers.redirectedUrl("/redirected")) - val token = TestOneTimeTokenGenerationSuccessHandler.lastToken?.tokenValue + val token = getLastToken().tokenValue this.mockMvc.perform( MockMvcRequestBuilders.post("/loginprocessingurl").param("token", token) @@ -124,7 +124,7 @@ class OneTimeTokenLoginDslTests { .redirectedUrl("/login/ott") ) - val token = TestOneTimeTokenGenerationSuccessHandler.lastToken + val token = getLastToken() assertThat(getCurrentMinutes(token!!.expiresAt)).isEqualTo(10) } @@ -135,25 +135,36 @@ class OneTimeTokenLoginDslTests { return expiresMinutes - currentMinutes } + private fun getLastToken(): OneTimeToken { + val lastToken = spring.context + .getBean(TestOneTimeTokenGenerationSuccessHandler::class.java).lastToken + return lastToken!! + } + @Configuration @EnableWebSecurity @Import(UserDetailsServiceConfig::class) open class OneTimeTokenConfig { @Bean - open fun securityFilterChain(http: HttpSecurity): SecurityFilterChain { + open fun securityFilterChain(http: HttpSecurity, ottSuccessHandler: OneTimeTokenGenerationSuccessHandler): SecurityFilterChain { // @formatter:off http { authorizeHttpRequests { authorize(anyRequest, authenticated) } oneTimeTokenLogin { - oneTimeTokenGenerationSuccessHandler = TestOneTimeTokenGenerationSuccessHandler() + oneTimeTokenGenerationSuccessHandler = ottSuccessHandler } } // @formatter:on return http.build() } + + @Bean + open fun ottSuccessHandler(): TestOneTimeTokenGenerationSuccessHandler { + return TestOneTimeTokenGenerationSuccessHandler() + } } @Configuration @@ -162,14 +173,14 @@ class OneTimeTokenLoginDslTests { open class OneTimeTokenConfigWithCustomTokenResolver { @Bean - open fun securityFilterChain(http: HttpSecurity): SecurityFilterChain { + open fun securityFilterChain(http: HttpSecurity, ottSuccessHandler: OneTimeTokenGenerationSuccessHandler): SecurityFilterChain { // @formatter:off http { authorizeHttpRequests { authorize(anyRequest, authenticated) } oneTimeTokenLogin { - oneTimeTokenGenerationSuccessHandler = TestOneTimeTokenGenerationSuccessHandler() + oneTimeTokenGenerationSuccessHandler = ottSuccessHandler generateRequestResolver = DefaultGenerateOneTimeTokenRequestResolver().apply { this.setExpiresIn(Duration.ofMinutes(10)) } @@ -179,6 +190,10 @@ class OneTimeTokenLoginDslTests { return http.build() } + @Bean + open fun ottSuccessHandler(): TestOneTimeTokenGenerationSuccessHandler { + return TestOneTimeTokenGenerationSuccessHandler() + } } @@ -187,7 +202,7 @@ class OneTimeTokenLoginDslTests { @Import(UserDetailsServiceConfig::class) open class OneTimeTokenDifferentUrlsConfig { @Bean - open fun securityFilterChain(http: HttpSecurity): SecurityFilterChain { + open fun securityFilterChain(http: HttpSecurity, ottSuccessHandler: OneTimeTokenGenerationSuccessHandler): SecurityFilterChain { // @formatter:off http { authorizeHttpRequests { @@ -195,7 +210,7 @@ class OneTimeTokenLoginDslTests { } oneTimeTokenLogin { tokenGeneratingUrl = "/generateurl" - oneTimeTokenGenerationSuccessHandler = TestOneTimeTokenGenerationSuccessHandler("/redirected") + oneTimeTokenGenerationSuccessHandler = ottSuccessHandler loginProcessingUrl = "/loginprocessingurl" authenticationSuccessHandler = SimpleUrlAuthenticationSuccessHandler("/authenticated") } @@ -203,6 +218,11 @@ class OneTimeTokenLoginDslTests { // @formatter:on return http.build() } + + @Bean + open fun ottSuccessHandler(): TestOneTimeTokenGenerationSuccessHandler { + return TestOneTimeTokenGenerationSuccessHandler("/redirected") + } } @Configuration(proxyBeanMethods = false) @@ -213,9 +233,10 @@ class OneTimeTokenLoginDslTests { InMemoryUserDetailsManager(PasswordEncodedUser.user(), PasswordEncodedUser.admin()) } - private class TestOneTimeTokenGenerationSuccessHandler : + class TestOneTimeTokenGenerationSuccessHandler : OneTimeTokenGenerationSuccessHandler { private val delegate: OneTimeTokenGenerationSuccessHandler + var lastToken: OneTimeToken? = null constructor() { this.delegate = @@ -232,12 +253,9 @@ class OneTimeTokenLoginDslTests { } override fun handle(request: HttpServletRequest, response: HttpServletResponse, oneTimeToken: OneTimeToken) { - lastToken = oneTimeToken + this.lastToken = oneTimeToken delegate.handle(request, response, oneTimeToken) } - companion object { - var lastToken: OneTimeToken? = null - } } }