Skip to content

Commit ff52e05

Browse files
committed
Favor PathPatternRequestMatcher in XML Configuration
Update BeanDefinitionParsers to use PathPatternRequestMatcher conditionally on the presence of a PathPatternRequestMatcher.Builder bean Closes gh-16828
1 parent de07b11 commit ff52e05

File tree

8 files changed

+89
-18
lines changed

8 files changed

+89
-18
lines changed

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2018 the original author or authors.
2+
* Copyright 2002-2025 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -178,7 +178,7 @@ private RootBeanDefinition createFilterBean(String loginUrl, String defaultTarge
178178
}
179179
this.loginProcessingUrl = loginUrl;
180180
BeanDefinitionBuilder matcherBuilder = BeanDefinitionBuilder
181-
.rootBeanDefinition("org.springframework.security.web.util.matcher.AntPathRequestMatcher");
181+
.rootBeanDefinition(RequestMatcherFactoryBean.class);
182182
matcherBuilder.addConstructorArgValue(loginUrl);
183183
if (this.loginMethod != null) {
184184
matcherBuilder.addConstructorArgValue("POST");

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

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,6 @@
8383
import org.springframework.security.web.session.SimpleRedirectInvalidSessionStrategy;
8484
import org.springframework.security.web.session.SimpleRedirectSessionInformationExpiredStrategy;
8585
import org.springframework.security.web.transport.HttpsRedirectFilter;
86-
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
8786
import org.springframework.util.Assert;
8887
import org.springframework.util.ClassUtils;
8988
import org.springframework.util.StringUtils;
@@ -751,7 +750,7 @@ private void createRequestCacheFilter() {
751750
requestCacheBldr.addPropertyValue("portResolver", this.portResolver);
752751
if (this.csrfFilter != null) {
753752
BeanDefinitionBuilder requestCacheMatcherBldr = BeanDefinitionBuilder
754-
.rootBeanDefinition(AntPathRequestMatcher.class);
753+
.rootBeanDefinition(RequestMatcherFactoryBean.class);
755754
requestCacheMatcherBldr.addConstructorArgValue("/**");
756755
requestCacheMatcherBldr.addConstructorArgValue("GET");
757756
requestCacheBldr.addPropertyValue("requestMatcher", requestCacheMatcherBldr.getBeanDefinition());

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2022 the original author or authors.
2+
* Copyright 2002-2025 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -134,7 +134,7 @@ public BeanDefinition parse(Element element, ParserContext pc) {
134134

135135
private BeanDefinition getLogoutRequestMatcher(String logoutUrl) {
136136
BeanDefinitionBuilder matcherBuilder = BeanDefinitionBuilder
137-
.rootBeanDefinition("org.springframework.security.web.util.matcher.AntPathRequestMatcher");
137+
.rootBeanDefinition(RequestMatcherFactoryBean.class);
138138
matcherBuilder.addConstructorArgValue(logoutUrl);
139139
if (this.csrfEnabled) {
140140
matcherBuilder.addConstructorArgValue("POST");
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
/*
2+
* Copyright 2002-2025 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.springframework.security.config.http;
18+
19+
import org.springframework.beans.BeansException;
20+
import org.springframework.beans.factory.FactoryBean;
21+
import org.springframework.context.ApplicationContext;
22+
import org.springframework.context.ApplicationContextAware;
23+
import org.springframework.http.HttpMethod;
24+
import org.springframework.security.web.servlet.util.matcher.PathPatternRequestMatcher;
25+
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
26+
import org.springframework.security.web.util.matcher.RequestMatcher;
27+
28+
@Deprecated
29+
public final class RequestMatcherFactoryBean implements FactoryBean<RequestMatcher>, ApplicationContextAware {
30+
31+
private PathPatternRequestMatcher.Builder builder;
32+
33+
private final HttpMethod method;
34+
35+
private final String path;
36+
37+
public RequestMatcherFactoryBean(String path) {
38+
this(path, null);
39+
}
40+
41+
public RequestMatcherFactoryBean(String path, HttpMethod method) {
42+
this.method = method;
43+
this.path = path;
44+
}
45+
46+
@Override
47+
public RequestMatcher getObject() throws Exception {
48+
if (this.builder != null) {
49+
return this.builder.matcher(this.method, this.path);
50+
}
51+
return new AntPathRequestMatcher(this.path, (this.method != null) ? this.method.name() : null);
52+
}
53+
54+
@Override
55+
public Class<?> getObjectType() {
56+
return null;
57+
}
58+
59+
@Override
60+
public void setApplicationContext(ApplicationContext context) throws BeansException {
61+
this.builder = context.getBeanProvider(PathPatternRequestMatcher.Builder.class).getIfUnique();
62+
}
63+
64+
}

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

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2022 the original author or authors.
2+
* Copyright 2002-2025 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -43,7 +43,6 @@
4343
import org.springframework.security.saml2.provider.service.web.authentication.Saml2WebSsoAuthenticationFilter;
4444
import org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint;
4545
import org.springframework.security.web.authentication.ui.DefaultLoginPageGeneratingFilter;
46-
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
4746
import org.springframework.util.StringUtils;
4847
import org.springframework.util.xml.DomUtils;
4948

@@ -216,7 +215,7 @@ private void resolveLoginPage(Element element, ParserContext parserContext) {
216215
}
217216
if (saml2LoginAuthenticationEntryPoint != null) {
218217
BeanDefinitionBuilder requestMatcherBuilder = BeanDefinitionBuilder
219-
.rootBeanDefinition(AntPathRequestMatcher.class);
218+
.rootBeanDefinition(RequestMatcherFactoryBean.class);
220219
requestMatcherBuilder.addConstructorArgValue(this.loginProcessingUrl);
221220
BeanDefinition requestMatcher = requestMatcherBuilder.getBeanDefinition();
222221
this.entryPoints.put(requestMatcher, saml2LoginAuthenticationEntryPoint);
@@ -260,7 +259,7 @@ private void resolveAuthenticationSuccessHandler(Element element,
260259

261260
private void registerDefaultCsrfOverride() {
262261
BeanDefinitionBuilder requestMatcherBuilder = BeanDefinitionBuilder
263-
.rootBeanDefinition(AntPathRequestMatcher.class);
262+
.rootBeanDefinition(RequestMatcherFactoryBean.class);
264263
requestMatcherBuilder.addConstructorArgValue(this.loginProcessingUrl);
265264
BeanDefinition requestMatcher = requestMatcherBuilder.getBeanDefinition();
266265
this.csrfIgnoreRequestMatchers.add(requestMatcher);

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

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2024 the original author or authors.
2+
* Copyright 2002-2025 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -41,7 +41,6 @@
4141
import org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler;
4242
import org.springframework.security.web.authentication.logout.SimpleUrlLogoutSuccessHandler;
4343
import org.springframework.security.web.util.matcher.AndRequestMatcher;
44-
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
4544
import org.springframework.security.web.util.matcher.ParameterRequestMatcher;
4645
import org.springframework.security.web.util.matcher.RequestMatcher;
4746
import org.springframework.util.CollectionUtils;
@@ -171,7 +170,7 @@ private static BeanMetadataElement createDefaultLogoutSuccessHandler() {
171170
}
172171

173172
private BeanMetadataElement createLogoutRequestMatcher() {
174-
BeanMetadataElement logoutMatcher = BeanDefinitionBuilder.rootBeanDefinition(AntPathRequestMatcher.class)
173+
BeanMetadataElement logoutMatcher = BeanDefinitionBuilder.rootBeanDefinition(RequestMatcherFactoryBean.class)
175174
.addConstructorArgValue(this.logoutUrl)
176175
.addConstructorArgValue("POST")
177176
.getBeanDefinition();
@@ -184,7 +183,8 @@ private BeanMetadataElement createLogoutRequestMatcher() {
184183
}
185184

186185
private BeanMetadataElement createSaml2LogoutRequestMatcher() {
187-
BeanMetadataElement logoutRequestMatcher = BeanDefinitionBuilder.rootBeanDefinition(AntPathRequestMatcher.class)
186+
BeanMetadataElement logoutRequestMatcher = BeanDefinitionBuilder
187+
.rootBeanDefinition(RequestMatcherFactoryBean.class)
188188
.addConstructorArgValue(this.logoutRequestUrl)
189189
.getBeanDefinition();
190190
BeanMetadataElement saml2RequestMatcher = BeanDefinitionBuilder
@@ -198,7 +198,7 @@ private BeanMetadataElement createSaml2LogoutRequestMatcher() {
198198

199199
private BeanMetadataElement createSaml2LogoutResponseMatcher() {
200200
BeanMetadataElement logoutResponseMatcher = BeanDefinitionBuilder
201-
.rootBeanDefinition(AntPathRequestMatcher.class)
201+
.rootBeanDefinition(RequestMatcherFactoryBean.class)
202202
.addConstructorArgValue(this.logoutResponseUrl)
203203
.getBeanDefinition();
204204
BeanMetadataElement saml2ResponseMatcher = BeanDefinitionBuilder

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

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2021 the original author or authors.
2+
* Copyright 2002-2025 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -23,7 +23,6 @@
2323
import org.springframework.beans.factory.xml.BeanDefinitionParser;
2424
import org.springframework.beans.factory.xml.ParserContext;
2525
import org.springframework.security.web.RequestMatcherRedirectFilter;
26-
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
2726
import org.springframework.util.StringUtils;
2827

2928
/**
@@ -45,9 +44,12 @@ public final class WellKnownChangePasswordBeanDefinitionParser implements BeanDe
4544
*/
4645
@Override
4746
public BeanDefinition parse(Element element, ParserContext parserContext) {
47+
BeanDefinition requestMatcher = BeanDefinitionBuilder.rootBeanDefinition(RequestMatcherFactoryBean.class)
48+
.addConstructorArgValue(WELL_KNOWN_CHANGE_PASSWORD_PATTERN)
49+
.getBeanDefinition();
4850
BeanDefinition changePasswordFilter = BeanDefinitionBuilder
4951
.rootBeanDefinition(RequestMatcherRedirectFilter.class)
50-
.addConstructorArgValue(new AntPathRequestMatcher(WELL_KNOWN_CHANGE_PASSWORD_PATTERN))
52+
.addConstructorArgValue(requestMatcher)
5153
.addConstructorArgValue(getChangePasswordPage(element))
5254
.getBeanDefinition();
5355
parserContext.getReaderContext().registerWithGeneratedName(changePasswordFilter);

docs/modules/ROOT/pages/migration/web.adoc

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,13 @@ fun requestMatcherBuilder(): PathPatternRequestMatcherBuilderFactoryBean {
2929
return PathPatternRequestMatcherBuilderFactoryBean()
3030
}
3131
----
32+
33+
Xml::
34+
+
35+
[source,xml,role="secondary"]
36+
----
37+
<b:bean class="org.springframework.security.config.web.PathPatternRequestMatcherBuilderFactoryBean"/>
38+
----
3239
======
3340

3441
This will tell the Spring Security DSL to use `PathPatternRequestMatcher` for all request matchers that it constructs.

0 commit comments

Comments
 (0)