2
0
Эх сурвалжийг харах

Document Defer load CsrfToken

Closes gh-12105
Rob Winch 2 жил өмнө
parent
commit
d860775b45

+ 0 - 5
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();

+ 1 - 6
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">
 		<intercept-url  pattern="/**" access="permitAll"/>
-		<csrf request-handler-ref="requestHandler"
-			token-repository-ref="csrfRepository"/>
+		<csrf request-handler-ref="requestHandler"/>
 		<request-cache ref="requestCache"/>
 		<session-management authentication-strategy-explicit-invocation="true"/>
 	</http>
 
 	<b:bean id="requestCache" class="org.springframework.security.web.savedrequest.HttpSessionRequestCache"
 		p:matchingRequestParameterName="continue"/>
-	<b:bean id="httpSessionCsrfRepository" class="org.springframework.security.web.csrf.HttpSessionCsrfTokenRepository"/>
-	<b:bean id="csrfRepository" class="org.springframework.security.web.csrf.LazyCsrfTokenRepository"
-		c:delegate-ref="httpSessionCsrfRepository"
-	 	p:deferLoadToken="true"/>
 	<b:bean id="requestHandler" class="org.springframework.security.web.csrf.CsrfTokenRequestAttributeHandler"
 		p:csrfRequestAttributeName="_csrf"/>
 	<b:import resource="CsrfConfigTests-shared-userservice.xml"/>

+ 71 - 13
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"]
+----
+<http>
+	<!-- ... -->
+	<csrf request-handler-ref="requestHandler"/>
+</http>
+<b:bean id="requestHandler"
+	class="org.springframework.security.web.csrf.CsrfTokenRequestAttributeHandler"
+	p:csrfRequestAttributeName="_csrf"/>
+----
+====
+
 === 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
+	}
 }
 ----
 ====