Document Defer load CsrfToken

Closes gh-12105
This commit is contained in:
Rob Winch 2022-10-28 15:41:25 -05:00
parent 4938c394e4
commit d860775b45
3 changed files with 72 additions and 24 deletions

View File

@ -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();

View File

@ -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"/>

View File

@ -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
}
}
----
====