Merge branch '7.0.x'

This commit is contained in:
Josh Cummings 2026-02-26 15:57:27 -07:00
commit 50caf0cb28
No known key found for this signature in database
GPG Key ID: 869B37A20E876129
7 changed files with 343 additions and 96 deletions

View File

@ -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 <<remember-me-hash-token>>.
`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"]
----
<http>
<remember-me services-ref="rememberMeServices"/>
</http>
<bean id="rememberMeServices" class=
"org.springframework.security.web.authentication.rememberme.TokenBasedRememberMeServices">
<property name="userDetailsService" ref="myUserDetailsService"/>
<property name="key" value="springRocks"/>
<property name="matchingAlgorithm" value="MD5"/>
<property name="encodingAlgorithm" value="SHA256"/>
</bean>
----
======
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"]
----
<bean id="rememberMeFilter" class=
"org.springframework.security.web.authentication.rememberme.RememberMeAuthenticationFilter">
<property name="rememberMeServices" ref="rememberMeServices"/>
<property name="authenticationManager" ref="theAuthenticationManager" />
</bean>
<bean id="rememberMeServices" class=
"org.springframework.security.web.authentication.rememberme.TokenBasedRememberMeServices">
<property name="userDetailsService" ref="myUserDetailsService"/>
<property name="key" value="springRocks"/>
</bean>
<bean id="rememberMeAuthenticationProvider" class=
"org.springframework.security.authentication.RememberMeAuthenticationProvider">
<property name="key" value="springRocks"/>
</bean>
----
======
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`).

View File

@ -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[]
}

View File

@ -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[]
}

View File

@ -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[]
}

View File

@ -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[]
}

View File

@ -0,0 +1,46 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ 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.
-->
<b:beans xmlns:b="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.springframework.org/schema/security"
xsi:schemaLocation="
http://www.springframework.org/schema/security
https://www.springframework.org/schema/security/spring-security.xsd
http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd">
<b:bean id="userDetailsService"
class="org.springframework.security.core.userdetails.jdbc.JdbcDaoImpl"/>
<!-- tag::snippet[] -->
<http>
<intercept-url pattern="/**" access="authenticated"/>
<remember-me services-ref="rememberMeServices"/>
</http>
<b:bean id="rememberMeServices"
class="org.springframework.security.web.authentication.rememberme.TokenBasedRememberMeServices">
<b:constructor-arg value="myKey"/>
<b:constructor-arg ref="userDetailsService"/>
<b:constructor-arg value="SHA256"
type="org.springframework.security.web.authentication.rememberme.TokenBasedRememberMeServices$RememberMeTokenAlgorithm"/>
<b:property name="matchingAlgorithm" value="MD5"/>
</b:bean>
<!-- end::snippet[] -->
</b:beans>

View File

@ -0,0 +1,53 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ 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.
-->
<b:beans xmlns:b="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.springframework.org/schema/security"
xsi:schemaLocation="
http://www.springframework.org/schema/security
https://www.springframework.org/schema/security/spring-security.xsd
http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd">
<b:bean id="userDetailsService"
class="org.springframework.security.core.userdetails.jdbc.JdbcDaoImpl"/>
<!-- tag::snippet[] -->
<b:bean id="rememberMeServices"
class="org.springframework.security.web.authentication.rememberme.TokenBasedRememberMeServices">
<b:constructor-arg value="myKey"/>
<b:constructor-arg ref="userDetailsService"/>
</b:bean>
<b:bean id="rememberMeFilter"
class="org.springframework.security.web.authentication.rememberme.RememberMeAuthenticationFilter">
<b:constructor-arg ref="authenticationManager"/>
<b:constructor-arg ref="rememberMeServices"/>
</b:bean>
<b:bean id="rememberMeAuthenticationProvider"
class="org.springframework.security.authentication.RememberMeAuthenticationProvider">
<b:constructor-arg value="myKey"/>
</b:bean>
<!-- end::snippet[] -->
<authentication-manager alias="authenticationManager">
<authentication-provider ref="rememberMeAuthenticationProvider"/>
</authentication-manager>
</b:beans>