Skip to content

Commit 46696a9

Browse files
author
Steve Riesenberg
committed
CsrfTokenRequestHandler extends CsrfTokenRequestResolver
Closes gh-11896
1 parent d140d95 commit 46696a9

File tree

18 files changed

+155
-188
lines changed

18 files changed

+155
-188
lines changed

config/src/main/java/org/springframework/security/config/annotation/web/configurers/CsrfConfigurer.java

Lines changed: 9 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,8 @@
3636
import org.springframework.security.web.csrf.CsrfFilter;
3737
import org.springframework.security.web.csrf.CsrfLogoutHandler;
3838
import org.springframework.security.web.csrf.CsrfTokenRepository;
39+
import org.springframework.security.web.csrf.CsrfTokenRepositoryRequestHandler;
3940
import org.springframework.security.web.csrf.CsrfTokenRequestHandler;
40-
import org.springframework.security.web.csrf.CsrfTokenRequestResolver;
4141
import org.springframework.security.web.csrf.HttpSessionCsrfTokenRepository;
4242
import org.springframework.security.web.csrf.LazyCsrfTokenRepository;
4343
import org.springframework.security.web.csrf.MissingCsrfTokenException;
@@ -93,8 +93,6 @@ public final class CsrfConfigurer<H extends HttpSecurityBuilder<H>>
9393

9494
private CsrfTokenRequestHandler requestHandler;
9595

96-
private CsrfTokenRequestResolver requestResolver;
97-
9896
private final ApplicationContext context;
9997

10098
/**
@@ -135,23 +133,13 @@ public CsrfConfigurer<H> requireCsrfProtectionMatcher(RequestMatcher requireCsrf
135133
* available as a request attribute.
136134
* @param requestHandler the {@link CsrfTokenRequestHandler} to use
137135
* @return the {@link CsrfConfigurer} for further customizations
136+
* @since 5.8
138137
*/
139138
public CsrfConfigurer<H> csrfTokenRequestHandler(CsrfTokenRequestHandler requestHandler) {
140139
this.requestHandler = requestHandler;
141140
return this;
142141
}
143142

144-
/**
145-
* Specify a {@link CsrfTokenRequestResolver} to use for resolving the token value
146-
* from the request.
147-
* @param requestResolver the {@link CsrfTokenRequestResolver} to use
148-
* @return the {@link CsrfConfigurer} for further customizations
149-
*/
150-
public CsrfConfigurer<H> csrfTokenRequestResolver(CsrfTokenRequestResolver requestResolver) {
151-
this.requestResolver = requestResolver;
152-
return this;
153-
}
154-
155143
/**
156144
* <p>
157145
* Allows specifying {@link HttpServletRequest} that should not use CSRF Protection
@@ -229,7 +217,13 @@ public CsrfConfigurer<H> sessionAuthenticationStrategy(
229217
@SuppressWarnings("unchecked")
230218
@Override
231219
public void configure(H http) {
232-
CsrfFilter filter = new CsrfFilter(this.csrfTokenRepository);
220+
CsrfFilter filter;
221+
if (this.requestHandler != null) {
222+
filter = new CsrfFilter(this.requestHandler);
223+
}
224+
else {
225+
filter = new CsrfFilter(new CsrfTokenRepositoryRequestHandler(this.csrfTokenRepository));
226+
}
233227
RequestMatcher requireCsrfProtectionMatcher = getRequireCsrfProtectionMatcher();
234228
if (requireCsrfProtectionMatcher != null) {
235229
filter.setRequireCsrfProtectionMatcher(requireCsrfProtectionMatcher);
@@ -246,12 +240,6 @@ public void configure(H http) {
246240
if (sessionConfigurer != null) {
247241
sessionConfigurer.addSessionAuthenticationStrategy(getSessionAuthenticationStrategy());
248242
}
249-
if (this.requestHandler != null) {
250-
filter.setRequestHandler(this.requestHandler);
251-
}
252-
if (this.requestResolver != null) {
253-
filter.setRequestResolver(this.requestResolver);
254-
}
255243
filter = postProcess(filter);
256244
http.addFilter(filter);
257245
}

config/src/main/java/org/springframework/security/config/http/CsrfBeanDefinitionParser.java

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
import org.springframework.security.web.csrf.CsrfAuthenticationStrategy;
4242
import org.springframework.security.web.csrf.CsrfFilter;
4343
import org.springframework.security.web.csrf.CsrfLogoutHandler;
44+
import org.springframework.security.web.csrf.CsrfTokenRepositoryRequestHandler;
4445
import org.springframework.security.web.csrf.HttpSessionCsrfTokenRepository;
4546
import org.springframework.security.web.csrf.LazyCsrfTokenRepository;
4647
import org.springframework.security.web.csrf.MissingCsrfTokenException;
@@ -73,8 +74,6 @@ public class CsrfBeanDefinitionParser implements BeanDefinitionParser {
7374

7475
private static final String ATT_REQUEST_HANDLER = "request-handler-ref";
7576

76-
private static final String ATT_REQUEST_RESOLVER = "request-resolver-ref";
77-
7877
private String csrfRepositoryRef;
7978

8079
private BeanDefinition csrfFilter;
@@ -83,8 +82,6 @@ public class CsrfBeanDefinitionParser implements BeanDefinitionParser {
8382

8483
private String requestHandlerRef;
8584

86-
private String requestResolverRef;
87-
8885
@Override
8986
public BeanDefinition parse(Element element, ParserContext pc) {
9087
boolean disabled = element != null && "true".equals(element.getAttribute("disabled"));
@@ -104,7 +101,6 @@ public BeanDefinition parse(Element element, ParserContext pc) {
104101
this.csrfRepositoryRef = element.getAttribute(ATT_REPOSITORY);
105102
this.requestMatcherRef = element.getAttribute(ATT_MATCHER);
106103
this.requestHandlerRef = element.getAttribute(ATT_REQUEST_HANDLER);
107-
this.requestResolverRef = element.getAttribute(ATT_REQUEST_RESOLVER);
108104
}
109105
if (!StringUtils.hasText(this.csrfRepositoryRef)) {
110106
RootBeanDefinition csrfTokenRepository = new RootBeanDefinition(HttpSessionCsrfTokenRepository.class);
@@ -116,15 +112,17 @@ public BeanDefinition parse(Element element, ParserContext pc) {
116112
new BeanComponentDefinition(lazyTokenRepository.getBeanDefinition(), this.csrfRepositoryRef));
117113
}
118114
BeanDefinitionBuilder builder = BeanDefinitionBuilder.rootBeanDefinition(CsrfFilter.class);
119-
builder.addConstructorArgReference(this.csrfRepositoryRef);
120-
if (StringUtils.hasText(this.requestMatcherRef)) {
121-
builder.addPropertyReference("requireCsrfProtectionMatcher", this.requestMatcherRef);
115+
if (!StringUtils.hasText(this.requestHandlerRef)) {
116+
BeanDefinition csrfTokenRequestHandler = BeanDefinitionBuilder
117+
.rootBeanDefinition(CsrfTokenRepositoryRequestHandler.class)
118+
.addConstructorArgReference(this.csrfRepositoryRef).getBeanDefinition();
119+
builder.addConstructorArgValue(csrfTokenRequestHandler);
122120
}
123-
if (StringUtils.hasText(this.requestHandlerRef)) {
124-
builder.addPropertyReference("requestHandler", this.requestHandlerRef);
121+
else {
122+
builder.addConstructorArgReference(this.requestHandlerRef);
125123
}
126-
if (StringUtils.hasText(this.requestResolverRef)) {
127-
builder.addPropertyReference("requestResolver", this.requestResolverRef);
124+
if (StringUtils.hasText(this.requestMatcherRef)) {
125+
builder.addPropertyReference("requireCsrfProtectionMatcher", this.requestMatcherRef);
128126
}
129127
this.csrfFilter = builder.getBeanDefinition();
130128
return this.csrfFilter;

config/src/main/resources/org/springframework/security/config/spring-security-5.8.rnc

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1154,9 +1154,6 @@ csrf-options.attlist &=
11541154
csrf-options.attlist &=
11551155
## The CsrfTokenRequestHandler to use. The default is CsrfTokenRequestProcessor.
11561156
attribute request-handler-ref { xsd:token }?
1157-
csrf-options.attlist &=
1158-
## The CsrfTokenRequestResolver to use. The default is CsrfTokenRequestProcessor.
1159-
attribute request-resolver-ref { xsd:token }?
11601157

11611158
headers =
11621159
## Element for configuration of the HeaderWritersFilter. Enables easy setting for the X-Frame-Options, X-XSS-Protection and X-Content-Type-Options headers.

config/src/main/resources/org/springframework/security/config/spring-security-5.8.xsd

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3258,13 +3258,7 @@
32583258
</xs:attribute>
32593259
<xs:attribute name="request-handler-ref" type="xs:token">
32603260
<xs:annotation>
3261-
<xs:documentation>The CsrfTokenRequestHandler to use. The default is CsrfTokenRequestProcessor.
3262-
</xs:documentation>
3263-
</xs:annotation>
3264-
</xs:attribute>
3265-
<xs:attribute name="request-resolver-ref" type="xs:token">
3266-
<xs:annotation>
3267-
<xs:documentation>The CsrfTokenRequestResolver to use. The default is CsrfTokenRequestProcessor.
3261+
<xs:documentation>The CsrfTokenRequestHandler to use. The default is CsrfTokenRepositoryRequestHandler.
32683262
</xs:documentation>
32693263
</xs:annotation>
32703264
</xs:attribute>

config/src/test/java/org/springframework/security/config/annotation/web/configuration/DeferHttpSessionJavaConfigTests.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@
3333
import org.springframework.security.config.test.SpringTestContextExtension;
3434
import org.springframework.security.web.DefaultSecurityFilterChain;
3535
import org.springframework.security.web.FilterChainProxy;
36-
import org.springframework.security.web.csrf.CsrfTokenRequestProcessor;
36+
import org.springframework.security.web.csrf.CsrfTokenRepositoryRequestHandler;
3737
import org.springframework.security.web.csrf.HttpSessionCsrfTokenRepository;
3838
import org.springframework.security.web.csrf.LazyCsrfTokenRepository;
3939
import org.springframework.security.web.savedrequest.HttpSessionRequestCache;
@@ -85,7 +85,7 @@ DefaultSecurityFilterChain springSecurity(HttpSecurity http) throws Exception {
8585
csrfRepository.setDeferLoadToken(true);
8686
HttpSessionRequestCache requestCache = new HttpSessionRequestCache();
8787
requestCache.setMatchingRequestParameterName("continue");
88-
CsrfTokenRequestProcessor requestHandler = new CsrfTokenRequestProcessor();
88+
CsrfTokenRepositoryRequestHandler requestHandler = new CsrfTokenRepositoryRequestHandler();
8989
requestHandler.setCsrfRequestAttributeName("_csrf");
9090
// @formatter:off
9191
http

config/src/test/java/org/springframework/security/config/annotation/web/configurers/CsrfConfigurerTests.java

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@
4444
import org.springframework.security.web.authentication.session.SessionAuthenticationStrategy;
4545
import org.springframework.security.web.csrf.CsrfToken;
4646
import org.springframework.security.web.csrf.CsrfTokenRepository;
47-
import org.springframework.security.web.csrf.CsrfTokenRequestProcessor;
47+
import org.springframework.security.web.csrf.CsrfTokenRepositoryRequestHandler;
4848
import org.springframework.security.web.csrf.DefaultCsrfToken;
4949
import org.springframework.security.web.firewall.StrictHttpFirewall;
5050
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
@@ -422,8 +422,7 @@ public void getLoginWhenCsrfTokenRequestProcessorSetThenRespondsWithNormalCsrfTo
422422
CsrfTokenRepository csrfTokenRepository = mock(CsrfTokenRepository.class);
423423
CsrfToken csrfToken = new DefaultCsrfToken("X-CSRF-TOKEN", "_csrf", "token");
424424
given(csrfTokenRepository.generateToken(any(HttpServletRequest.class))).willReturn(csrfToken);
425-
CsrfTokenRequestProcessorConfig.PROCESSOR = new CsrfTokenRequestProcessor();
426-
CsrfTokenRequestProcessorConfig.PROCESSOR.setTokenRepository(csrfTokenRepository);
425+
CsrfTokenRequestProcessorConfig.HANDLER = new CsrfTokenRepositoryRequestHandler(csrfTokenRepository);
427426
this.spring.register(CsrfTokenRequestProcessorConfig.class, BasicController.class).autowire();
428427
this.mvc.perform(get("/login")).andExpect(status().isOk())
429428
.andExpect(content().string(containsString(csrfToken.getToken())));
@@ -440,8 +439,7 @@ public void loginWhenCsrfTokenRequestProcessorSetAndNormalCsrfTokenThenSuccess()
440439
CsrfTokenRepository csrfTokenRepository = mock(CsrfTokenRepository.class);
441440
given(csrfTokenRepository.loadToken(any(HttpServletRequest.class))).willReturn(null, csrfToken);
442441
given(csrfTokenRepository.generateToken(any(HttpServletRequest.class))).willReturn(csrfToken);
443-
CsrfTokenRequestProcessorConfig.PROCESSOR = new CsrfTokenRequestProcessor();
444-
CsrfTokenRequestProcessorConfig.PROCESSOR.setTokenRepository(csrfTokenRepository);
442+
CsrfTokenRequestProcessorConfig.HANDLER = new CsrfTokenRepositoryRequestHandler(csrfTokenRepository);
445443

446444
this.spring.register(CsrfTokenRequestProcessorConfig.class, BasicController.class).autowire();
447445
// @formatter:off
@@ -803,7 +801,7 @@ protected void configure(AuthenticationManagerBuilder auth) throws Exception {
803801
@EnableWebSecurity
804802
static class CsrfTokenRequestProcessorConfig {
805803

806-
static CsrfTokenRequestProcessor PROCESSOR;
804+
static CsrfTokenRepositoryRequestHandler HANDLER;
807805

808806
@Bean
809807
SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
@@ -813,10 +811,7 @@ SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
813811
.anyRequest().authenticated()
814812
)
815813
.formLogin(Customizer.withDefaults())
816-
.csrf((csrf) -> csrf
817-
.csrfTokenRequestHandler(PROCESSOR)
818-
.csrfTokenRequestResolver(PROCESSOR)
819-
);
814+
.csrf((csrf) -> csrf.csrfTokenRequestHandler(HANDLER));
820815
// @formatter:on
821816

822817
return http.build();

config/src/test/resources/org/springframework/security/config/http/CsrfConfigTests-WithRequestAttrName.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
<csrf request-handler-ref="requestHandler"/>
2727
</http>
2828

29-
<b:bean id="requestHandler" class="org.springframework.security.web.csrf.CsrfTokenRequestProcessor"
29+
<b:bean id="requestHandler" class="org.springframework.security.web.csrf.CsrfTokenRepositoryRequestHandler"
3030
p:csrfRequestAttributeName="csrf-attribute-name"/>
3131
<b:import resource="CsrfConfigTests-shared-userservice.xml"/>
3232
</b:beans>

config/src/test/resources/org/springframework/security/config/http/DeferHttpSessionTests-Explicit.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@
4242
<b:bean id="csrfRepository" class="org.springframework.security.web.csrf.LazyCsrfTokenRepository"
4343
c:delegate-ref="httpSessionCsrfRepository"
4444
p:deferLoadToken="true"/>
45-
<b:bean id="requestHandler" class="org.springframework.security.web.csrf.CsrfTokenRequestProcessor"
45+
<b:bean id="requestHandler" class="org.springframework.security.web.csrf.CsrfTokenRepositoryRequestHandler"
4646
p:csrfRequestAttributeName="_csrf"/>
4747
<b:import resource="CsrfConfigTests-shared-userservice.xml"/>
4848
</b:beans>

docs/modules/ROOT/pages/servlet/appendix/namespace/http.adoc

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -777,11 +777,7 @@ The default is `HttpSessionCsrfTokenRepository`.
777777

778778
[[nsa-csrf-request-handler-ref]]
779779
* **request-handler-ref**
780-
The optional `CsrfTokenRequestHandler` to use. The default is `CsrfTokenRequestProcessor`.
781-
782-
[[nsa-csrf-request-resolver-ref]]
783-
* **request-resolver-ref**
784-
The optional `CsrfTokenRequestResolver` to use. The default is `CsrfTokenRequestProcessor`.
780+
The optional `CsrfTokenRequestHandler` to use. The default is `CsrfTokenRepositoryRequestHandler`.
785781

786782
[[nsa-csrf-request-matcher-ref]]
787783
* **request-matcher-ref**

test/src/main/java/org/springframework/security/test/web/support/WebTestUtils.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,8 @@
3131
import org.springframework.security.web.context.SecurityContextRepository;
3232
import org.springframework.security.web.csrf.CsrfFilter;
3333
import org.springframework.security.web.csrf.CsrfTokenRepository;
34+
import org.springframework.security.web.csrf.CsrfTokenRepositoryRequestHandler;
3435
import org.springframework.security.web.csrf.CsrfTokenRequestHandler;
35-
import org.springframework.security.web.csrf.CsrfTokenRequestProcessor;
3636
import org.springframework.security.web.csrf.HttpSessionCsrfTokenRepository;
3737
import org.springframework.test.util.ReflectionTestUtils;
3838
import org.springframework.web.context.WebApplicationContext;
@@ -48,7 +48,7 @@ public abstract class WebTestUtils {
4848

4949
private static final SecurityContextRepository DEFAULT_CONTEXT_REPO = new HttpSessionSecurityContextRepository();
5050

51-
private static final CsrfTokenRequestProcessor DEFAULT_CSRF_PROCESSOR = new CsrfTokenRequestProcessor();
51+
private static final CsrfTokenRepositoryRequestHandler DEFAULT_CSRF_HANDLER = new CsrfTokenRepositoryRequestHandler();
5252

5353
private WebTestUtils() {
5454
}
@@ -104,7 +104,7 @@ public static void setSecurityContextRepository(HttpServletRequest request,
104104
public static CsrfTokenRequestHandler getCsrfTokenRequestHandler(HttpServletRequest request) {
105105
CsrfFilter filter = findFilter(request, CsrfFilter.class);
106106
if (filter == null) {
107-
return DEFAULT_CSRF_PROCESSOR;
107+
return DEFAULT_CSRF_HANDLER;
108108
}
109109
return (CsrfTokenRequestHandler) ReflectionTestUtils.getField(filter, "requestHandler");
110110
}

0 commit comments

Comments
 (0)