@@ -787,48 +787,10 @@ public class SecurityConfig {
787787 public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
788788 http
789789 // ...
790- .csrf((csrf) -> csrf
791- .csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse()) // <1>
792- .csrfTokenRequestHandler(new SpaCsrfTokenRequestHandler()) // <2>
793- );
790+ .csrf((csrf) -> csrf.spa());
794791 return http.build();
795792 }
796793}
797-
798- final class SpaCsrfTokenRequestHandler implements CsrfTokenRequestHandler {
799- private final CsrfTokenRequestHandler plain = new CsrfTokenRequestAttributeHandler();
800- private final CsrfTokenRequestHandler xor = new XorCsrfTokenRequestAttributeHandler();
801-
802- @Override
803- public void handle(HttpServletRequest request, HttpServletResponse response, Supplier<CsrfToken> csrfToken) {
804- /*
805- * Always use XorCsrfTokenRequestAttributeHandler to provide BREACH protection of
806- * the CsrfToken when it is rendered in the response body.
807- */
808- this.xor.handle(request, response, csrfToken);
809- /*
810- * Render the token value to a cookie by causing the deferred token to be loaded.
811- */
812- csrfToken.get();
813- }
814-
815- @Override
816- public String resolveCsrfTokenValue(HttpServletRequest request, CsrfToken csrfToken) {
817- String headerValue = request.getHeader(csrfToken.getHeaderName());
818- /*
819- * If the request contains a request header, use CsrfTokenRequestAttributeHandler
820- * to resolve the CsrfToken. This applies when a single-page application includes
821- * the header value automatically, which was obtained via a cookie containing the
822- * raw CsrfToken.
823- *
824- * In all other cases (e.g. if the request contains a request parameter), use
825- * XorCsrfTokenRequestAttributeHandler to resolve the CsrfToken. This applies
826- * when a server-side rendered form includes the _csrf request parameter as a
827- * hidden input.
828- */
829- return (StringUtils.hasText(headerValue) ? this.plain : this.xor).resolveCsrfTokenValue(request, csrfToken);
830- }
831- }
832794----
833795
834796Kotlin::
@@ -846,51 +808,12 @@ class SecurityConfig {
846808 http {
847809 // ...
848810 csrf {
849- csrfTokenRepository = CookieCsrfTokenRepository.withHttpOnlyFalse() // <1>
850- csrfTokenRequestHandler = SpaCsrfTokenRequestHandler() // <2>
811+ spa()
851812 }
852813 }
853814 return http.build()
854815 }
855816}
856-
857- class SpaCsrfTokenRequestHandler : CsrfTokenRequestHandler {
858- private val plain: CsrfTokenRequestHandler = CsrfTokenRequestAttributeHandler()
859- private val xor: CsrfTokenRequestHandler = XorCsrfTokenRequestAttributeHandler()
860-
861- override fun handle(request: HttpServletRequest, response: HttpServletResponse, csrfToken: Supplier<CsrfToken>) {
862- /*
863- * Always use XorCsrfTokenRequestAttributeHandler to provide BREACH protection of
864- * the CsrfToken when it is rendered in the response body.
865- */
866- xor.handle(request, response, csrfToken)
867- /*
868- * Render the token value to a cookie by causing the deferred token to be loaded.
869- */
870- csrfToken.get()
871- }
872-
873- override fun resolveCsrfTokenValue(request: HttpServletRequest, csrfToken: CsrfToken): String? {
874- val headerValue = request.getHeader(csrfToken.headerName)
875- /*
876- * If the request contains a request header, use CsrfTokenRequestAttributeHandler
877- * to resolve the CsrfToken. This applies when a single-page application includes
878- * the header value automatically, which was obtained via a cookie containing the
879- * raw CsrfToken.
880- */
881- return if (StringUtils.hasText(headerValue)) {
882- plain
883- } else {
884- /*
885- * In all other cases (e.g. if the request contains a request parameter), use
886- * XorCsrfTokenRequestAttributeHandler to resolve the CsrfToken. This applies
887- * when a server-side rendered form includes the _csrf request parameter as a
888- * hidden input.
889- */
890- xor
891- }.resolveCsrfTokenValue(request, csrfToken)
892- }
893- }
894817----
895818
896819XML::
@@ -899,22 +822,13 @@ XML::
899822----
900823<http>
901824 <!-- ... -->
902- <csrf
903- token-repository-ref="tokenRepository" <1 >
904- request-handler-ref="requestHandler"/> <2 >
825+ <csrf>
826+ <spa / >
827+ </csrf >
905828</http>
906- <b:bean id="tokenRepository"
907- class="org.springframework.security.web.csrf.CookieCsrfTokenRepository"
908- p:cookieHttpOnly="false"/>
909- <b:bean id="requestHandler"
910- class="example.SpaCsrfTokenRequestHandler"/>
911829----
912830======
913831
914- <1> Configure `CookieCsrfTokenRepository` with `HttpOnly` set to `false` so the cookie can be read by the JavaScript application.
915- <2> Configure a custom `CsrfTokenRequestHandler` that resolves the CSRF token based on whether it is an HTTP request header (`X-XSRF-TOKEN`) or request parameter (`_csrf`).
916- This implementation also causes the deferred `CsrfToken` to be loaded on every request, which will return a new cookie if needed.
917-
918832[[csrf-integration-javascript-mpa]]
919833==== Multi-Page Applications
920834
0 commit comments