From 7c3c8bbdcb2c9558974d5957dd7780d330faa511 Mon Sep 17 00:00:00 2001 From: Tran Ngoc Nhan Date: Wed, 4 Feb 2026 20:15:06 +0700 Subject: [PATCH] Update Remember-Me example Closes gh-18639 Signed-off-by: Tran Ngoc Nhan --- .../servlet/authentication/rememberme.adoc | 99 +------------------ ...orithmRememberMeServicesConfiguration.java | 65 ++++++++++++ ...orithmRememberMeServicesConfiguration.java | 58 +++++++++++ ...lgorithmRememberMeServicesConfiguration.kt | 61 ++++++++++++ ...lgorithmRememberMeServicesConfiguration.kt | 57 +++++++++++ ...gorithmRememberMeServicesConfiguration.xml | 46 +++++++++ ...gorithmRememberMeServicesConfiguration.xml | 53 ++++++++++ 7 files changed, 343 insertions(+), 96 deletions(-) create mode 100644 docs/src/test/java/org/springframework/security/docs/servlet/authentication/tokenbasedremembermeservices/CustomAlgorithmRememberMeServicesConfiguration.java create mode 100644 docs/src/test/java/org/springframework/security/docs/servlet/authentication/tokenbasedremembermeservices/DefaultAlgorithmRememberMeServicesConfiguration.java create mode 100644 docs/src/test/kotlin/org/springframework/security/kt/docs/servlet/authentication/tokenbasedremembermeservices/CustomAlgorithmRememberMeServicesConfiguration.kt create mode 100644 docs/src/test/kotlin/org/springframework/security/kt/docs/servlet/authentication/tokenbasedremembermeservices/DefaultAlgorithmRememberMeServicesConfiguration.kt create mode 100644 docs/src/test/resources/org/springframework/security/docs/servlet/authentication/tokenbasedremembermeservices/CustomAlgorithmRememberMeServicesConfiguration.xml create mode 100644 docs/src/test/resources/org/springframework/security/docs/servlet/authentication/tokenbasedremembermeservices/DefaultAlgorithmRememberMeServicesConfiguration.xml diff --git a/docs/modules/ROOT/pages/servlet/authentication/rememberme.adoc b/docs/modules/ROOT/pages/servlet/authentication/rememberme.adoc index c0c5143f02..84482a3e59 100644 --- a/docs/modules/ROOT/pages/servlet/authentication/rememberme.adoc +++ b/docs/modules/ROOT/pages/servlet/authentication/rememberme.adoc @@ -97,6 +97,7 @@ This design allows any number of remember-me implementation strategies. We have seen earlier that Spring Security provides two implementations. We look at each of these in turn. +[[token-based-remember-me-services]] === TokenBasedRememberMeServices This implementation supports the simpler approach described in <>. `TokenBasedRememberMeServices` generates a `RememberMeAuthenticationToken`, which is processed by `RememberMeAuthenticationProvider`. @@ -110,105 +111,11 @@ If no `algorithmName` is present, the default matching algorithm will be used, w You can specify different algorithms for signature encoding and for signature matching, this allows users to safely upgrade to a different encoding algorithm while still able to verify old ones if there is no `algorithmName` present. To do that you can specify your customized `TokenBasedRememberMeServices` as a Bean and use it in the configuration. -[tabs] -====== -Java:: -+ -[source,java,role="primary"] ----- -@Bean -SecurityFilterChain securityFilterChain(HttpSecurity http, RememberMeServices rememberMeServices) throws Exception { - http - .authorizeHttpRequests((authorize) -> authorize - .anyRequest().authenticated() - ) - .rememberMe((remember) -> remember - .rememberMeServices(rememberMeServices) - ); - return http.build(); -} - -@Bean -RememberMeServices rememberMeServices(UserDetailsService userDetailsService) { - RememberMeTokenAlgorithm encodingAlgorithm = RememberMeTokenAlgorithm.SHA256; - TokenBasedRememberMeServices rememberMe = new TokenBasedRememberMeServices(myKey, userDetailsService, encodingAlgorithm); - rememberMe.setMatchingAlgorithm(RememberMeTokenAlgorithm.MD5); - return rememberMe; -} ----- - -XML:: -+ -[source,xml,role="secondary"] ----- - - - - - - - - - - ----- -====== +include-code::./CustomAlgorithmRememberMeServicesConfiguration[tag=snippet,indent=0] The following beans are required in an application context to enable remember-me services: -[tabs] -====== -Java:: -+ -[source,java,role="primary"] ----- -@Bean -RememberMeAuthenticationFilter rememberMeFilter() { - RememberMeAuthenticationFilter rememberMeFilter = new RememberMeAuthenticationFilter(); - rememberMeFilter.setRememberMeServices(rememberMeServices()); - rememberMeFilter.setAuthenticationManager(theAuthenticationManager); - return rememberMeFilter; -} - -@Bean -TokenBasedRememberMeServices rememberMeServices() { - TokenBasedRememberMeServices rememberMeServices = new TokenBasedRememberMeServices(); - rememberMeServices.setUserDetailsService(myUserDetailsService); - rememberMeServices.setKey("springRocks"); - return rememberMeServices; -} - -@Bean -RememberMeAuthenticationProvider rememberMeAuthenticationProvider() { - RememberMeAuthenticationProvider rememberMeAuthenticationProvider = new RememberMeAuthenticationProvider(); - rememberMeAuthenticationProvider.setKey("springRocks"); - return rememberMeAuthenticationProvider; -} ----- - -XML:: -+ -[source,xml,role="secondary"] ----- - - - - - - - - - - - - - ----- -====== +include-code::./DefaultAlgorithmRememberMeServicesConfiguration[tag=snippet,indent=0] Remember to add your `RememberMeServices` implementation to your `UsernamePasswordAuthenticationFilter.setRememberMeServices()` property, include the `RememberMeAuthenticationProvider` in your `AuthenticationManager.setProviders()` list, and add `RememberMeAuthenticationFilter` into your `FilterChainProxy` (typically immediately after your `UsernamePasswordAuthenticationFilter`). diff --git a/docs/src/test/java/org/springframework/security/docs/servlet/authentication/tokenbasedremembermeservices/CustomAlgorithmRememberMeServicesConfiguration.java b/docs/src/test/java/org/springframework/security/docs/servlet/authentication/tokenbasedremembermeservices/CustomAlgorithmRememberMeServicesConfiguration.java new file mode 100644 index 0000000000..085ac95bcb --- /dev/null +++ b/docs/src/test/java/org/springframework/security/docs/servlet/authentication/tokenbasedremembermeservices/CustomAlgorithmRememberMeServicesConfiguration.java @@ -0,0 +1,65 @@ +/* + * Copyright 2026-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.security.docs.servlet.authentication.tokenbasedremembermeservices; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; +import org.springframework.security.core.userdetails.UserDetailsService; +import org.springframework.security.web.SecurityFilterChain; +import org.springframework.security.web.authentication.RememberMeServices; +import org.springframework.security.web.authentication.rememberme.TokenBasedRememberMeServices; +import org.springframework.security.web.authentication.rememberme.TokenBasedRememberMeServices.RememberMeTokenAlgorithm; +import org.springframework.web.servlet.config.annotation.EnableWebMvc; + +/** + * Demonstrates custom algorithm for remember me configuration. + * + * @author Ngoc Nhan + */ +@EnableWebMvc +@EnableWebSecurity +@Configuration(proxyBeanMethods = false) +public class CustomAlgorithmRememberMeServicesConfiguration { + + // tag::snippet[] + @Bean + SecurityFilterChain securityFilterChain(HttpSecurity http, RememberMeServices rememberMeServices) throws Exception { + // @formatter:off + http + .authorizeHttpRequests((authorize) -> authorize + .anyRequest().authenticated() + ) + .rememberMe((remember) -> remember + .rememberMeServices(rememberMeServices) + ); + // @formatter:on + return http.build(); + } + + @Bean + RememberMeServices rememberMeServices(UserDetailsService userDetailsService) { + RememberMeTokenAlgorithm encodingAlgorithm = RememberMeTokenAlgorithm.SHA256; + TokenBasedRememberMeServices rememberMe = new TokenBasedRememberMeServices("myKey", userDetailsService, + encodingAlgorithm); + rememberMe.setMatchingAlgorithm(RememberMeTokenAlgorithm.MD5); + return rememberMe; + } + // end::snippet[] + +} diff --git a/docs/src/test/java/org/springframework/security/docs/servlet/authentication/tokenbasedremembermeservices/DefaultAlgorithmRememberMeServicesConfiguration.java b/docs/src/test/java/org/springframework/security/docs/servlet/authentication/tokenbasedremembermeservices/DefaultAlgorithmRememberMeServicesConfiguration.java new file mode 100644 index 0000000000..bc3d2c84f4 --- /dev/null +++ b/docs/src/test/java/org/springframework/security/docs/servlet/authentication/tokenbasedremembermeservices/DefaultAlgorithmRememberMeServicesConfiguration.java @@ -0,0 +1,58 @@ +/* + * Copyright 2026-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.security.docs.servlet.authentication.tokenbasedremembermeservices; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.security.authentication.AuthenticationManager; +import org.springframework.security.authentication.RememberMeAuthenticationProvider; +import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; +import org.springframework.security.core.userdetails.UserDetailsService; +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.web.servlet.config.annotation.EnableWebMvc; + +/** + * Demonstrates default algorithm for remember me configuration. + * + * @author Ngoc Nhan + */ +@EnableWebMvc +@EnableWebSecurity +@Configuration(proxyBeanMethods = false) +public class DefaultAlgorithmRememberMeServicesConfiguration { + + // tag::snippet[] + @Bean + RememberMeServices rememberMeServices(UserDetailsService userDetailsService) { + return new TokenBasedRememberMeServices("myKey", userDetailsService); + } + + @Bean + RememberMeAuthenticationFilter rememberMeFilter(AuthenticationManager authenticationManager, + TokenBasedRememberMeServices rememberMeServices) { + return new RememberMeAuthenticationFilter(authenticationManager, rememberMeServices); + } + + @Bean + RememberMeAuthenticationProvider rememberMeAuthenticationProvider() { + return new RememberMeAuthenticationProvider("myKey"); + } + // end::snippet[] + +} diff --git a/docs/src/test/kotlin/org/springframework/security/kt/docs/servlet/authentication/tokenbasedremembermeservices/CustomAlgorithmRememberMeServicesConfiguration.kt b/docs/src/test/kotlin/org/springframework/security/kt/docs/servlet/authentication/tokenbasedremembermeservices/CustomAlgorithmRememberMeServicesConfiguration.kt new file mode 100644 index 0000000000..47309fcf52 --- /dev/null +++ b/docs/src/test/kotlin/org/springframework/security/kt/docs/servlet/authentication/tokenbasedremembermeservices/CustomAlgorithmRememberMeServicesConfiguration.kt @@ -0,0 +1,61 @@ +/* + * Copyright 2026-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.security.kt.docs.servlet.authentication.tokenbasedremembermeservices + +import org.springframework.context.annotation.Bean +import org.springframework.context.annotation.Configuration +import org.springframework.security.config.annotation.web.builders.HttpSecurity +import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity +import org.springframework.security.core.userdetails.UserDetailsService +import org.springframework.security.web.SecurityFilterChain +import org.springframework.security.web.authentication.RememberMeServices +import org.springframework.security.web.authentication.rememberme.TokenBasedRememberMeServices +import org.springframework.security.web.authentication.rememberme.TokenBasedRememberMeServices.RememberMeTokenAlgorithm +import org.springframework.web.servlet.config.annotation.EnableWebMvc + +/** + * Demonstrates custom algorithm for remember me configuration. + * + * @author Ngoc Nhan + */ +@EnableWebMvc +@EnableWebSecurity +@Configuration(proxyBeanMethods = false) +class CustomAlgorithmRememberMeServicesConfiguration { + + // tag::snippet[] + @Bean + @Throws(Exception::class) + fun securityFilterChain(http: HttpSecurity, rememberMeServices: RememberMeServices): SecurityFilterChain { + // @formatter:off + http + .authorizeHttpRequests{ it.anyRequest().authenticated() } + .rememberMe { it.rememberMeServices(rememberMeServices) } + // @formatter:on + return http.build() + } + + @Bean + fun rememberMeServices(userDetailsService: UserDetailsService): RememberMeServices { + val encodingAlgorithm = RememberMeTokenAlgorithm.SHA256 + val rememberMe = TokenBasedRememberMeServices("myKey", userDetailsService, encodingAlgorithm) + rememberMe.setMatchingAlgorithm(RememberMeTokenAlgorithm.MD5) + return rememberMe + } + // end::snippet[] + +} diff --git a/docs/src/test/kotlin/org/springframework/security/kt/docs/servlet/authentication/tokenbasedremembermeservices/DefaultAlgorithmRememberMeServicesConfiguration.kt b/docs/src/test/kotlin/org/springframework/security/kt/docs/servlet/authentication/tokenbasedremembermeservices/DefaultAlgorithmRememberMeServicesConfiguration.kt new file mode 100644 index 0000000000..2f22ec3f17 --- /dev/null +++ b/docs/src/test/kotlin/org/springframework/security/kt/docs/servlet/authentication/tokenbasedremembermeservices/DefaultAlgorithmRememberMeServicesConfiguration.kt @@ -0,0 +1,57 @@ +/* + * Copyright 2026-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.security.kt.docs.servlet.authentication.tokenbasedremembermeservices + +import org.springframework.context.annotation.Bean +import org.springframework.context.annotation.Configuration +import org.springframework.security.authentication.AuthenticationManager +import org.springframework.security.authentication.RememberMeAuthenticationProvider +import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity +import org.springframework.security.core.userdetails.UserDetailsService +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.web.servlet.config.annotation.EnableWebMvc + +/** + * Demonstrates default algorithm for remember me configuration. + * + * @author Ngoc Nhan + */ +@EnableWebMvc +@EnableWebSecurity +@Configuration(proxyBeanMethods = false) +class DefaultAlgorithmRememberMeServicesConfiguration { + + // tag::snippet[] + @Bean + fun rememberMeServices(userDetailsService: UserDetailsService): RememberMeServices { + return TokenBasedRememberMeServices("myKey", userDetailsService) + } + + @Bean + fun rememberMeFilter(authenticationManager: AuthenticationManager, rememberMeServices: TokenBasedRememberMeServices): RememberMeAuthenticationFilter { + return RememberMeAuthenticationFilter(authenticationManager, rememberMeServices) + } + + @Bean + fun rememberMeAuthenticationProvider(): RememberMeAuthenticationProvider { + return RememberMeAuthenticationProvider("myKey") + } + // end::snippet[] + +} \ No newline at end of file diff --git a/docs/src/test/resources/org/springframework/security/docs/servlet/authentication/tokenbasedremembermeservices/CustomAlgorithmRememberMeServicesConfiguration.xml b/docs/src/test/resources/org/springframework/security/docs/servlet/authentication/tokenbasedremembermeservices/CustomAlgorithmRememberMeServicesConfiguration.xml new file mode 100644 index 0000000000..16bce70e41 --- /dev/null +++ b/docs/src/test/resources/org/springframework/security/docs/servlet/authentication/tokenbasedremembermeservices/CustomAlgorithmRememberMeServicesConfiguration.xml @@ -0,0 +1,46 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/src/test/resources/org/springframework/security/docs/servlet/authentication/tokenbasedremembermeservices/DefaultAlgorithmRememberMeServicesConfiguration.xml b/docs/src/test/resources/org/springframework/security/docs/servlet/authentication/tokenbasedremembermeservices/DefaultAlgorithmRememberMeServicesConfiguration.xml new file mode 100644 index 0000000000..66fc28a7f5 --- /dev/null +++ b/docs/src/test/resources/org/springframework/security/docs/servlet/authentication/tokenbasedremembermeservices/DefaultAlgorithmRememberMeServicesConfiguration.xml @@ -0,0 +1,53 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + +