From 753bb5725f50025c993ce77cfdfad3c93910412c Mon Sep 17 00:00:00 2001 From: XieEDeHeiShou <2325690622@qq.com> Date: Fri, 13 Jul 2018 23:36:20 +0800 Subject: [PATCH 01/12] Override the key to avoid CookieTheftException People may confused why those `token.keyhash()` not equals, for they forget to config the key twice. So, override the key for them, make it more convenient to custom RememberMeServices. --- .../web/configurers/RememberMeConfigurer.java | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/config/src/main/java/org/springframework/security/config/annotation/web/configurers/RememberMeConfigurer.java b/config/src/main/java/org/springframework/security/config/annotation/web/configurers/RememberMeConfigurer.java index b6fe07a8889..e84ed74b7fe 100644 --- a/config/src/main/java/org/springframework/security/config/annotation/web/configurers/RememberMeConfigurer.java +++ b/config/src/main/java/org/springframework/security/config/annotation/web/configurers/RememberMeConfigurer.java @@ -267,6 +267,19 @@ public void init(H http) throws Exception { validateInput(); String key = getKey(); RememberMeServices rememberMeServices = getRememberMeServices(http, key); + if (rememberMeServices instanceof AbstractRememberMeServices) { + /* + * To avoid CookieTheftException in PersistentTokenBasedRememberMeServices.processAutoLoginCookie(...), + * override the key or config it twice like below: + * + * + * http.rememberMe() + * .key(key) + * .rememberMeServices(new PersistentTokenBasedRememberMeServices(key, userDetailsService, tokenRepository)); + * + */ + key = rememberMeServices.getKey(); + } http.setSharedObject(RememberMeServices.class, rememberMeServices); LogoutConfigurer logoutConfigurer = http.getConfigurer(LogoutConfigurer.class); if (logoutConfigurer != null && this.logoutHandler != null) { @@ -441,4 +454,4 @@ private String getKey() { } return this.key; } -} \ No newline at end of file +} From f699901b6ae87e6cc50c3b9a3c170d4d09cb6a63 Mon Sep 17 00:00:00 2001 From: XieEDeHeiShou <2325690622@qq.com> Date: Fri, 13 Jul 2018 23:57:39 +0800 Subject: [PATCH 02/12] Fix cast exception --- .../config/annotation/web/configurers/RememberMeConfigurer.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/src/main/java/org/springframework/security/config/annotation/web/configurers/RememberMeConfigurer.java b/config/src/main/java/org/springframework/security/config/annotation/web/configurers/RememberMeConfigurer.java index e84ed74b7fe..a0059d7b240 100644 --- a/config/src/main/java/org/springframework/security/config/annotation/web/configurers/RememberMeConfigurer.java +++ b/config/src/main/java/org/springframework/security/config/annotation/web/configurers/RememberMeConfigurer.java @@ -278,7 +278,7 @@ public void init(H http) throws Exception { * .rememberMeServices(new PersistentTokenBasedRememberMeServices(key, userDetailsService, tokenRepository)); * */ - key = rememberMeServices.getKey(); + key = ((AbstractRememberMeServices) rememberMeServices).getKey(); } http.setSharedObject(RememberMeServices.class, rememberMeServices); LogoutConfigurer logoutConfigurer = http.getConfigurer(LogoutConfigurer.class); From 5dd4546c2aad4dca0ed52b5b7a9d2917a9f5fc72 Mon Sep 17 00:00:00 2001 From: XieEDeHeiShou <2325690622@qq.com> Date: Sat, 14 Jul 2018 22:35:36 +0800 Subject: [PATCH 03/12] Remove trailing whitespace Remove trailing whitespace to avoid travis CI failure. --- .../annotation/web/configurers/RememberMeConfigurer.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/config/src/main/java/org/springframework/security/config/annotation/web/configurers/RememberMeConfigurer.java b/config/src/main/java/org/springframework/security/config/annotation/web/configurers/RememberMeConfigurer.java index a0059d7b240..df7f8dd37bc 100644 --- a/config/src/main/java/org/springframework/security/config/annotation/web/configurers/RememberMeConfigurer.java +++ b/config/src/main/java/org/springframework/security/config/annotation/web/configurers/RememberMeConfigurer.java @@ -269,12 +269,12 @@ public void init(H http) throws Exception { RememberMeServices rememberMeServices = getRememberMeServices(http, key); if (rememberMeServices instanceof AbstractRememberMeServices) { /* - * To avoid CookieTheftException in PersistentTokenBasedRememberMeServices.processAutoLoginCookie(...), + * To avoid CookieTheftException in PersistentTokenBasedRememberMeServices.processAutoLoginCookie(...), * override the key or config it twice like below: - * + * * * http.rememberMe() - * .key(key) + * .key(key) * .rememberMeServices(new PersistentTokenBasedRememberMeServices(key, userDetailsService, tokenRepository)); * */ From 634fdd2a5e7d51292385862e208b415b80060266 Mon Sep 17 00:00:00 2001 From: XieEDeHeiShou <2325690622@qq.com> Date: Mon, 8 Oct 2018 21:33:15 +0800 Subject: [PATCH 04/12] Update README.adoc nothing else, just try trigger the CI. From 88e90f68d523bef505b9a5c850c02ecb124f7b58 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=82=93=E8=B6=85?= <2325690622@qq.com> Date: Tue, 29 Oct 2019 21:55:49 +0800 Subject: [PATCH 05/12] Fix condition when override the key --- .../web/configurers/RememberMeConfigurer.java | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) diff --git a/config/src/main/java/org/springframework/security/config/annotation/web/configurers/RememberMeConfigurer.java b/config/src/main/java/org/springframework/security/config/annotation/web/configurers/RememberMeConfigurer.java index df7f8dd37bc..2166a4ce439 100644 --- a/config/src/main/java/org/springframework/security/config/annotation/web/configurers/RememberMeConfigurer.java +++ b/config/src/main/java/org/springframework/security/config/annotation/web/configurers/RememberMeConfigurer.java @@ -267,18 +267,10 @@ public void init(H http) throws Exception { validateInput(); String key = getKey(); RememberMeServices rememberMeServices = getRememberMeServices(http, key); - if (rememberMeServices instanceof AbstractRememberMeServices) { - /* - * To avoid CookieTheftException in PersistentTokenBasedRememberMeServices.processAutoLoginCookie(...), - * override the key or config it twice like below: - * - * - * http.rememberMe() - * .key(key) - * .rememberMeServices(new PersistentTokenBasedRememberMeServices(key, userDetailsService, tokenRepository)); - * - */ - key = ((AbstractRememberMeServices) rememberMeServices).getKey(); + if (key == null) { + if (rememberMeServices instanceof AbstractRememberMeServices) { + key = ((AbstractRememberMeServices) rememberMeServices).getKey(); + } } http.setSharedObject(RememberMeServices.class, rememberMeServices); LogoutConfigurer logoutConfigurer = http.getConfigurer(LogoutConfigurer.class); From cbea2e1d668847da4dc074dfa3441852a3131462 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=82=93=E8=B6=85?= <2325690622@qq.com> Date: Mon, 4 Nov 2019 20:36:22 +0800 Subject: [PATCH 06/12] Replace spaces with tab --- .../config/annotation/web/configurers/RememberMeConfigurer.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/src/main/java/org/springframework/security/config/annotation/web/configurers/RememberMeConfigurer.java b/config/src/main/java/org/springframework/security/config/annotation/web/configurers/RememberMeConfigurer.java index 2166a4ce439..4fd7189d6a3 100644 --- a/config/src/main/java/org/springframework/security/config/annotation/web/configurers/RememberMeConfigurer.java +++ b/config/src/main/java/org/springframework/security/config/annotation/web/configurers/RememberMeConfigurer.java @@ -269,7 +269,7 @@ public void init(H http) throws Exception { RememberMeServices rememberMeServices = getRememberMeServices(http, key); if (key == null) { if (rememberMeServices instanceof AbstractRememberMeServices) { - key = ((AbstractRememberMeServices) rememberMeServices).getKey(); + key = ((AbstractRememberMeServices) rememberMeServices).getKey(); } } http.setSharedObject(RememberMeServices.class, rememberMeServices); From ff64c221e3a53af887edc0a3246c13e357f09e77 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=82=93=E8=B6=85=40xgtl?= <2325690622@qq.com> Date: Wed, 6 Nov 2019 10:49:31 +0800 Subject: [PATCH 07/12] Move logic into getKey() --- .../annotation/web/configurers/RememberMeConfigurer.java | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/config/src/main/java/org/springframework/security/config/annotation/web/configurers/RememberMeConfigurer.java b/config/src/main/java/org/springframework/security/config/annotation/web/configurers/RememberMeConfigurer.java index 4fd7189d6a3..9561a6a99b5 100644 --- a/config/src/main/java/org/springframework/security/config/annotation/web/configurers/RememberMeConfigurer.java +++ b/config/src/main/java/org/springframework/security/config/annotation/web/configurers/RememberMeConfigurer.java @@ -267,11 +267,6 @@ public void init(H http) throws Exception { validateInput(); String key = getKey(); RememberMeServices rememberMeServices = getRememberMeServices(http, key); - if (key == null) { - if (rememberMeServices instanceof AbstractRememberMeServices) { - key = ((AbstractRememberMeServices) rememberMeServices).getKey(); - } - } http.setSharedObject(RememberMeServices.class, rememberMeServices); LogoutConfigurer logoutConfigurer = http.getConfigurer(LogoutConfigurer.class); if (logoutConfigurer != null && this.logoutHandler != null) { @@ -441,6 +436,9 @@ private UserDetailsService getUserDetailsService(H http) { * @return the remember me key to use */ private String getKey() { + if (this.key == null && this.rememberMeServices instanceof AbstractRememberMeServices) { + this.key = ((AbstractRememberMeServices) rememberMeServices).getKey(); + } if (this.key == null) { this.key = UUID.randomUUID().toString(); } From 4fa65cada146079b9cad09c78c56d1c47fb6e1e9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=82=93=E8=B6=85=40xgtl?= <2325690622@qq.com> Date: Wed, 6 Nov 2019 13:46:26 +0800 Subject: [PATCH 08/12] Append test case for fallback key configuration --- .../RememberMeConfigurerTests.java | 32 +++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/config/src/test/java/org/springframework/security/config/annotation/web/configurers/RememberMeConfigurerTests.java b/config/src/test/java/org/springframework/security/config/annotation/web/configurers/RememberMeConfigurerTests.java index 1323ce442d7..d40c9cab798 100644 --- a/config/src/test/java/org/springframework/security/config/annotation/web/configurers/RememberMeConfigurerTests.java +++ b/config/src/test/java/org/springframework/security/config/annotation/web/configurers/RememberMeConfigurerTests.java @@ -36,6 +36,7 @@ import org.springframework.security.provisioning.InMemoryUserDetailsManager; import org.springframework.security.web.authentication.RememberMeServices; import org.springframework.security.web.authentication.rememberme.RememberMeAuthenticationFilter; +import org.springframework.security.web.authentication.rememberme.TokenBasedRememberMeServices; import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.MvcResult; @@ -453,4 +454,35 @@ public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception // @formatter:on } } + + @Test + public void getWhenRememberMeCookieThenAuthenticationIsRememberMeAuthenticationTokenWithFallbackKeyConfiguration() + throws Exception { + this.spring.register(FallbackRememberMeKeyConfig.class).autowire(); + + MvcResult mvcResult = this.mvc.perform(post("/login") + .with(csrf()) + .param("username", "user") + .param("password", "password") + .param("remember-me", "true")) + .andReturn(); + Cookie rememberMeCookie = mvcResult.getResponse().getCookie("remember-me"); + + this.mvc.perform(get("/abc") + .cookie(rememberMeCookie)) + .andExpect(authenticated().withAuthentication(auth -> + assertThat(auth).isInstanceOf(RememberMeAuthenticationToken.class))); + } + + @EnableWebSecurity + static class FallbackRememberMeKeyConfig extends RememberMeConfig { + + @Override + protected void configure(HttpSecurity http) throws Exception { + // @formatter:off + http.rememberMe() + .rememberMeServices(new TokenBasedRememberMeServices("key", userDetailsService())); + // @formatter:on + } + } } From 2f529e7c1a4b964cfc7b642e13974e3c877a87dc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=82=93=E8=B6=85=40xgtl?= <2325690622@qq.com> Date: Wed, 6 Nov 2019 13:48:48 +0800 Subject: [PATCH 09/12] Fix warning --- .../annotation/web/configurers/RememberMeConfigurerTests.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/config/src/test/java/org/springframework/security/config/annotation/web/configurers/RememberMeConfigurerTests.java b/config/src/test/java/org/springframework/security/config/annotation/web/configurers/RememberMeConfigurerTests.java index d40c9cab798..45617e2143e 100644 --- a/config/src/test/java/org/springframework/security/config/annotation/web/configurers/RememberMeConfigurerTests.java +++ b/config/src/test/java/org/springframework/security/config/annotation/web/configurers/RememberMeConfigurerTests.java @@ -33,6 +33,7 @@ import org.springframework.security.core.userdetails.PasswordEncodedUser; import org.springframework.security.core.userdetails.User; import org.springframework.security.core.userdetails.UserDetailsService; +import org.springframework.security.crypto.factory.PasswordEncoderFactories; import org.springframework.security.provisioning.InMemoryUserDetailsManager; import org.springframework.security.web.authentication.RememberMeServices; import org.springframework.security.web.authentication.rememberme.RememberMeAuthenticationFilter; @@ -190,7 +191,8 @@ protected void configure(HttpSecurity http) throws Exception { @Bean public UserDetailsService userDetailsService() { return new InMemoryUserDetailsManager( - User.withDefaultPasswordEncoder() + User.builder() + .passwordEncoder(it-> PasswordEncoderFactories.createDelegatingPasswordEncoder().encode(it)) .username("user") .password("password") .roles("USER") From fb23b5a39f83f1f4c1316adb63037461fc8ef7c4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=82=93=E8=B6=85=40xgtl?= <2325690622@qq.com> Date: Wed, 6 Nov 2019 17:54:57 +0800 Subject: [PATCH 10/12] Optimize key initialization --- .../annotation/web/configurers/RememberMeConfigurer.java | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/config/src/main/java/org/springframework/security/config/annotation/web/configurers/RememberMeConfigurer.java b/config/src/main/java/org/springframework/security/config/annotation/web/configurers/RememberMeConfigurer.java index 930f1636ba4..1cc57a0b981 100644 --- a/config/src/main/java/org/springframework/security/config/annotation/web/configurers/RememberMeConfigurer.java +++ b/config/src/main/java/org/springframework/security/config/annotation/web/configurers/RememberMeConfigurer.java @@ -434,11 +434,12 @@ private UserDetailsService getUserDetailsService(H http) { * @return the remember me key to use */ private String getKey() { - if (this.key == null && this.rememberMeServices instanceof AbstractRememberMeServices) { - this.key = ((AbstractRememberMeServices) rememberMeServices).getKey(); - } if (this.key == null) { - this.key = UUID.randomUUID().toString(); + if (this.rememberMeServices instanceof AbstractRememberMeServices) { + this.key = ((AbstractRememberMeServices) rememberMeServices).getKey(); + } else { + this.key = UUID.randomUUID().toString(); + } } return this.key; } From fc5c9dfa338a2a199b0c2cea7bd083c7ff8b45e1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=82=93=E8=B6=85=40xgtl?= <2325690622@qq.com> Date: Wed, 6 Nov 2019 17:55:41 +0800 Subject: [PATCH 11/12] Fix test case by invoke super.configure() --- .../annotation/web/configurers/RememberMeConfigurerTests.java | 1 + 1 file changed, 1 insertion(+) diff --git a/config/src/test/java/org/springframework/security/config/annotation/web/configurers/RememberMeConfigurerTests.java b/config/src/test/java/org/springframework/security/config/annotation/web/configurers/RememberMeConfigurerTests.java index 45617e2143e..1ce31829c48 100644 --- a/config/src/test/java/org/springframework/security/config/annotation/web/configurers/RememberMeConfigurerTests.java +++ b/config/src/test/java/org/springframework/security/config/annotation/web/configurers/RememberMeConfigurerTests.java @@ -481,6 +481,7 @@ static class FallbackRememberMeKeyConfig extends RememberMeConfig { @Override protected void configure(HttpSecurity http) throws Exception { + super.configure(http); // @formatter:off http.rememberMe() .rememberMeServices(new TokenBasedRememberMeServices("key", userDetailsService())); From 9b1ad4eda177e56493252038f7363d0f2a321360 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=82=93=E8=B6=85=40xgtl?= <2325690622@qq.com> Date: Thu, 7 Nov 2019 17:35:16 +0800 Subject: [PATCH 12/12] Revert "Fix warning" This reverts commit 2f529e7c --- .../annotation/web/configurers/RememberMeConfigurerTests.java | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/config/src/test/java/org/springframework/security/config/annotation/web/configurers/RememberMeConfigurerTests.java b/config/src/test/java/org/springframework/security/config/annotation/web/configurers/RememberMeConfigurerTests.java index 1ce31829c48..5d3e4032e94 100644 --- a/config/src/test/java/org/springframework/security/config/annotation/web/configurers/RememberMeConfigurerTests.java +++ b/config/src/test/java/org/springframework/security/config/annotation/web/configurers/RememberMeConfigurerTests.java @@ -33,7 +33,6 @@ import org.springframework.security.core.userdetails.PasswordEncodedUser; import org.springframework.security.core.userdetails.User; import org.springframework.security.core.userdetails.UserDetailsService; -import org.springframework.security.crypto.factory.PasswordEncoderFactories; import org.springframework.security.provisioning.InMemoryUserDetailsManager; import org.springframework.security.web.authentication.RememberMeServices; import org.springframework.security.web.authentication.rememberme.RememberMeAuthenticationFilter; @@ -191,8 +190,7 @@ protected void configure(HttpSecurity http) throws Exception { @Bean public UserDetailsService userDetailsService() { return new InMemoryUserDetailsManager( - User.builder() - .passwordEncoder(it-> PasswordEncoderFactories.createDelegatingPasswordEncoder().encode(it)) + User.withDefaultPasswordEncoder() .username("user") .password("password") .roles("USER")