diff --git a/config/src/test/java/org/springframework/security/config/annotation/web/configuration/DeferHttpSessionJavaConfigTests.java b/config/src/test/java/org/springframework/security/config/annotation/web/configuration/DeferHttpSessionJavaConfigTests.java
index fe5cca2527..28b2adaf9a 100644
--- a/config/src/test/java/org/springframework/security/config/annotation/web/configuration/DeferHttpSessionJavaConfigTests.java
+++ b/config/src/test/java/org/springframework/security/config/annotation/web/configuration/DeferHttpSessionJavaConfigTests.java
@@ -34,8 +34,6 @@ import org.springframework.security.config.test.SpringTestContextExtension;
import org.springframework.security.web.DefaultSecurityFilterChain;
import org.springframework.security.web.FilterChainProxy;
import org.springframework.security.web.csrf.CsrfTokenRequestAttributeHandler;
-import org.springframework.security.web.csrf.HttpSessionCsrfTokenRepository;
-import org.springframework.security.web.csrf.LazyCsrfTokenRepository;
import org.springframework.security.web.savedrequest.HttpSessionRequestCache;
import static org.mockito.ArgumentMatchers.anyBoolean;
@@ -81,8 +79,6 @@ public class DeferHttpSessionJavaConfigTests {
@Bean
DefaultSecurityFilterChain springSecurity(HttpSecurity http) throws Exception {
- LazyCsrfTokenRepository csrfRepository = new LazyCsrfTokenRepository(new HttpSessionCsrfTokenRepository());
- csrfRepository.setDeferLoadToken(true);
HttpSessionRequestCache requestCache = new HttpSessionRequestCache();
requestCache.setMatchingRequestParameterName("continue");
CsrfTokenRequestAttributeHandler requestHandler = new CsrfTokenRequestAttributeHandler();
@@ -103,7 +99,6 @@ public class DeferHttpSessionJavaConfigTests {
)
.csrf((csrf) -> csrf
.csrfTokenRequestHandler(requestHandler)
- .csrfTokenRepository(csrfRepository)
);
// @formatter:on
return http.build();
diff --git a/config/src/test/resources/org/springframework/security/config/http/DeferHttpSessionTests-Explicit.xml b/config/src/test/resources/org/springframework/security/config/http/DeferHttpSessionTests-Explicit.xml
index cbfdfa90a3..27af272bcf 100644
--- a/config/src/test/resources/org/springframework/security/config/http/DeferHttpSessionTests-Explicit.xml
+++ b/config/src/test/resources/org/springframework/security/config/http/DeferHttpSessionTests-Explicit.xml
@@ -30,18 +30,13 @@
security-context-explicit-save="true"
use-authorization-manager="true">
-
+
-
-
diff --git a/docs/modules/ROOT/pages/migration.adoc b/docs/modules/ROOT/pages/migration.adoc
index 0dbb919b11..8c81515009 100644
--- a/docs/modules/ROOT/pages/migration.adoc
+++ b/docs/modules/ROOT/pages/migration.adoc
@@ -13,6 +13,64 @@ endif::[]
== Servlet
+=== Defer Loading CsrfToken
+
+In Spring Security 5, the default behavior is that the `CsrfToken` will be loaded on every request.
+This means that in a typical setup, the `HttpSession` must be read for every request even if it is unnecessary.
+
+In Spring Security 6, the default is that the lookup of the `CsrfToken` will be deferred until it is needed.
+
+To opt into the new Spring Security 6 default, the following configuration can be used.
+
+.Defer Loading `CsrfToken`
+====
+.Java
+[source,java,role="primary"]
+----
+@Bean
+DefaultSecurityFilterChain springSecurity(HttpSecurity http) throws Exception {
+ CsrfTokenRequestAttributeHandler requestHandler = new CsrfTokenRequestAttributeHandler();
+ // set the name of the attribute the CsrfToken will be populated on
+ requestHandler.setCsrfRequestAttributeName("_csrf");
+ http
+ // ...
+ .csrf((csrf) -> csrf
+ .csrfTokenRequestHandler(requestHandler)
+ );
+ return http.build();
+}
+----
+
+.Kotlin
+[source,kotlin,role="secondary"]
+----
+@Bean
+open fun springSecurity(http: HttpSecurity): SecurityFilterChain {
+ val requestHandler = CsrfTokenRequestAttributeHandler()
+ // set the name of the attribute the CsrfToken will be populated on
+ requestHandler.setCsrfRequestAttributeName("_csrf")
+ http {
+ csrf {
+ csrfTokenRequestHandler = requestHandler
+ }
+ }
+ return http.build()
+}
+----
+
+.XML
+[source,xml,role="secondary"]
+----
+
+
+
+
+
+----
+====
+
=== Explicit Save SecurityContextRepository
In Spring Security 5, the default behavior is for the xref:servlet/authentication/architecture.adoc#servlet-authentication-securitycontext[`SecurityContext`] to automatically be saved to the xref:servlet/authentication/persistence.adoc#securitycontextrepository[`SecurityContextRepository`] using the xref:servlet/authentication/persistence.adoc#securitycontextpersistencefilter[`SecurityContextPersistenceFilter`].
@@ -170,10 +228,10 @@ static PermissionEvaluator permissionEvaluator() {
[source,kotlin,role="secondary"]
----
companion object {
- @Bean
- fun permissionEvaluator(): PermissionEvaluator {
- // ... your evaluator
- }
+ @Bean
+ fun permissionEvaluator(): PermissionEvaluator {
+ // ... your evaluator
+ }
}
----
====
@@ -186,9 +244,9 @@ to:
----
@Bean
static MethodSecurityExpressionHandler expressionHandler() {
- var expressionHandler = new DefaultMethodSecurityExpressionHandler();
- expressionHandler.setPermissionEvaluator(myPermissionEvaluator);
- return expressionHandler;
+ var expressionHandler = new DefaultMethodSecurityExpressionHandler();
+ expressionHandler.setPermissionEvaluator(myPermissionEvaluator);
+ return expressionHandler;
}
----
@@ -196,12 +254,12 @@ static MethodSecurityExpressionHandler expressionHandler() {
[source,kotlin,role="secondary"]
----
companion object {
- @Bean
- fun expressionHandler(): MethodSecurityExpressionHandler {
- val expressionHandler = DefaultMethodSecurityExpressionHandler
- expressionHandler.setPermissionEvaluator(myPermissionEvaluator)
- return expressionHandler
- }
+ @Bean
+ fun expressionHandler(): MethodSecurityExpressionHandler {
+ val expressionHandler = DefaultMethodSecurityExpressionHandler
+ expressionHandler.setPermissionEvaluator(myPermissionEvaluator)
+ return expressionHandler
+ }
}
----
====