Josh Cummings 2 hónapja
szülő
commit
ef50ff29ad
100 módosított fájl, 562 hozzáadás és 1409 törlés
  1. 1 2
      cas/src/main/java/org/springframework/security/cas/web/CasAuthenticationFilter.java
  2. 14 329
      config/src/main/java/org/springframework/security/config/annotation/web/AbstractRequestMatcherRegistry.java
  3. 3 10
      config/src/main/java/org/springframework/security/config/annotation/web/RequestMatcherFactory.java
  4. 10 52
      config/src/main/java/org/springframework/security/config/annotation/web/builders/HttpSecurity.java
  5. 2 1
      config/src/main/java/org/springframework/security/config/annotation/web/builders/WebSecurity.java
  6. 0 95
      config/src/main/java/org/springframework/security/config/annotation/web/configuration/WebMvcSecurityConfiguration.java
  7. 3 5
      config/src/main/java/org/springframework/security/config/annotation/web/configuration/WebSecurityConfiguration.java
  8. 1 16
      config/src/main/java/org/springframework/security/config/annotation/web/configurers/CorsConfigurer.java
  9. 1 7
      config/src/main/java/org/springframework/security/config/annotation/web/configurers/RequestCacheConfigurer.java
  10. 0 4
      config/src/main/java/org/springframework/security/config/aot/hint/WebMvcSecurityConfigurationRuntimeHints.java
  11. 1 1
      config/src/main/java/org/springframework/security/config/http/AuthorizationFilterParser.java
  12. 1 14
      config/src/main/java/org/springframework/security/config/http/CorsBeanDefinitionParser.java
  13. 8 9
      config/src/main/java/org/springframework/security/config/http/CorsConfigurationSourceFactoryBean.java
  14. 10 5
      config/src/main/java/org/springframework/security/config/http/DefaultFilterChainValidator.java
  15. 1 1
      config/src/main/java/org/springframework/security/config/http/FilterInvocationSecurityMetadataSourceParser.java
  16. 4 16
      config/src/main/java/org/springframework/security/config/http/HttpConfigurationBuilder.java
  17. 11 28
      config/src/main/java/org/springframework/security/config/http/MatcherType.java
  18. 77 0
      config/src/main/java/org/springframework/security/config/http/PathPatternRequestMatcherFactoryBean.java
  19. 3 6
      config/src/main/java/org/springframework/security/config/http/RequestMatcherFactoryBean.java
  20. 1 1
      config/src/main/kotlin/org/springframework/security/config/annotation/web/AbstractRequestMatcherDsl.kt
  21. 8 19
      config/src/main/kotlin/org/springframework/security/config/annotation/web/AuthorizeHttpRequestsDsl.kt
  22. 8 20
      config/src/main/kotlin/org/springframework/security/config/annotation/web/AuthorizeRequestsDsl.kt
  23. 0 1
      config/src/main/kotlin/org/springframework/security/config/annotation/web/HttpSecurityDsl.kt
  24. 8 19
      config/src/main/kotlin/org/springframework/security/config/annotation/web/RequiresChannelDsl.kt
  25. 1 1
      config/src/main/resources/org/springframework/security/config/spring-security-7.0.rnc
  26. 1 2
      config/src/main/resources/org/springframework/security/config/spring-security-7.0.xsd
  27. 2 1
      config/src/test/java/org/springframework/security/config/FilterChainProxyConfigTests.java
  28. 2 2
      config/src/test/java/org/springframework/security/config/annotation/issue50/SecurityConfig.java
  29. 11 7
      config/src/test/java/org/springframework/security/config/annotation/web/AbstractRequestMatcherRegistryAnyMatcherTests.java
  30. 10 6
      config/src/test/java/org/springframework/security/config/annotation/web/AbstractRequestMatcherRegistryNoMvcTests.java
  31. 24 252
      config/src/test/java/org/springframework/security/config/annotation/web/AbstractRequestMatcherRegistryTests.java
  32. 3 3
      config/src/test/java/org/springframework/security/config/annotation/web/builders/HttpConfigurationTests.java
  33. 13 12
      config/src/test/java/org/springframework/security/config/annotation/web/builders/NamespaceHttpTests.java
  34. 13 9
      config/src/test/java/org/springframework/security/config/annotation/web/builders/WebSecurityFilterChainValidatorTests.java
  35. 18 7
      config/src/test/java/org/springframework/security/config/annotation/web/builders/WebSecurityTests.java
  36. 6 26
      config/src/test/java/org/springframework/security/config/annotation/web/configuration/AuthorizationManagerWebInvocationPrivilegeEvaluatorConfigTests.java
  37. 0 127
      config/src/test/java/org/springframework/security/config/annotation/web/configuration/HandlerMappingIntrospectorCacheFilterConfigTests.java
  38. 26 32
      config/src/test/java/org/springframework/security/config/annotation/web/configuration/WebSecurityConfigurationTests.java
  39. 8 7
      config/src/test/java/org/springframework/security/config/annotation/web/configurers/AbstractConfigAttributeRequestMatcherRegistryTests.java
  40. 10 9
      config/src/test/java/org/springframework/security/config/annotation/web/configurers/AuthorizeHttpRequestsConfigurerTests.java
  41. 35 15
      config/src/test/java/org/springframework/security/config/annotation/web/configurers/AuthorizeRequestsTests.java
  42. 5 5
      config/src/test/java/org/springframework/security/config/annotation/web/configurers/CsrfConfigurerIgnoringRequestMatchersTests.java
  43. 2 2
      config/src/test/java/org/springframework/security/config/annotation/web/configurers/CsrfConfigurerTests.java
  44. 1 2
      config/src/test/java/org/springframework/security/config/annotation/web/configurers/DefaultFiltersTests.java
  45. 4 4
      config/src/test/java/org/springframework/security/config/annotation/web/configurers/ExceptionHandlingConfigurerAccessDeniedHandlerTests.java
  46. 59 32
      config/src/test/java/org/springframework/security/config/annotation/web/configurers/HttpSecurityRequestMatchersTests.java
  47. 2 2
      config/src/test/java/org/springframework/security/config/annotation/web/configurers/HttpSecuritySecurityMatchersNoMvcTests.java
  48. 20 12
      config/src/test/java/org/springframework/security/config/annotation/web/configurers/HttpSecuritySecurityMatchersTests.java
  49. 1 2
      config/src/test/java/org/springframework/security/config/annotation/web/configurers/NamespaceRememberMeTests.java
  50. 5 5
      config/src/test/java/org/springframework/security/config/annotation/web/configurers/RequestMatcherConfigurerTests.java
  51. 1 1
      config/src/test/java/org/springframework/security/config/annotation/web/configurers/SessionManagementConfigurerServlet31Tests.java
  52. 17 8
      config/src/test/java/org/springframework/security/config/annotation/web/configurers/UrlAuthorizationConfigurerTests.java
  53. 1 1
      config/src/test/java/org/springframework/security/config/annotation/web/configurers/oauth2/client/OAuth2LoginConfigurerTests.java
  54. 3 2
      config/src/test/java/org/springframework/security/config/annotation/web/configurers/saml2/Saml2LogoutConfigurerTests.java
  55. 0 8
      config/src/test/java/org/springframework/security/config/aot/hint/WebMvcSecurityConfigurationRuntimeHintsTests.java
  56. 6 5
      config/src/test/java/org/springframework/security/config/http/DefaultFilterChainValidatorTests.java
  57. 5 8
      config/src/test/java/org/springframework/security/config/http/FilterSecurityMetadataSourceBeanDefinitionParserTests.java
  58. 1 1
      config/src/test/java/org/springframework/security/config/http/FormLoginConfigTests.java
  59. 0 65
      config/src/test/java/org/springframework/security/config/http/InterceptUrlConfigTests.java
  60. 2 2
      config/src/test/java/org/springframework/security/config/http/customconfigurer/CustomConfigurer.java
  61. 5 5
      config/src/test/kotlin/org/springframework/security/config/annotation/web/CsrfDslTests.kt
  62. 7 5
      config/src/test/kotlin/org/springframework/security/config/annotation/web/ExceptionHandlingDslTests.kt
  63. 4 4
      config/src/test/kotlin/org/springframework/security/config/annotation/web/LogoutDslTests.kt
  64. 1 2
      config/src/test/kotlin/org/springframework/security/config/annotation/web/RememberMeDslTests.kt
  65. 2 2
      config/src/test/kotlin/org/springframework/security/config/annotation/web/headers/HttpStrictTransportSecurityDslTests.kt
  66. 2 2
      config/src/test/resources/org/springframework/security/config/http/CsrfBeanDefinitionParserTests-RegisterDataValueProcessorOnyIfNotRegistered.xml
  67. 1 1
      config/src/test/resources/org/springframework/security/config/http/CsrfConfigTests-CsrfEnabled.xml
  68. 1 1
      config/src/test/resources/org/springframework/security/config/http/FormLoginConfigTests-WithRequestMatcher.xml
  69. 1 1
      config/src/test/resources/org/springframework/security/config/http/FormLoginConfigTests-WithSuccessAndFailureHandlers.xml
  70. 8 4
      config/src/test/resources/org/springframework/security/config/http/HttpInterceptUrlTests-interceptUrlWhenRequestMatcherRefThenWorks.xml
  71. 4 4
      config/src/test/resources/org/springframework/security/config/http/InterceptUrlConfigTests-AuthorizationManagerFilterAllDispatcherTypes.xml
  72. 1 1
      config/src/test/resources/org/springframework/security/config/http/InterceptUrlConfigTests-CamelCasePathVariables.xml
  73. 1 1
      config/src/test/resources/org/springframework/security/config/http/InterceptUrlConfigTests-CamelCasePathVariablesAuthorizationManager.xml
  74. 1 1
      config/src/test/resources/org/springframework/security/config/http/InterceptUrlConfigTests-DefaultMatcherServletPath.xml
  75. 1 1
      config/src/test/resources/org/springframework/security/config/http/InterceptUrlConfigTests-DefaultMatcherServletPathAuthorizationManager.xml
  76. 4 4
      config/src/test/resources/org/springframework/security/config/http/InterceptUrlConfigTests-FilterAllDispatcherTypesFalse.xml
  77. 1 1
      config/src/test/resources/org/springframework/security/config/http/InterceptUrlConfigTests-PatchMethod.xml
  78. 1 1
      config/src/test/resources/org/springframework/security/config/http/InterceptUrlConfigTests-PatchMethodAuthorizationManager.xml
  79. 1 1
      config/src/test/resources/org/springframework/security/config/http/InterceptUrlConfigTests-PathVariables.xml
  80. 1 1
      config/src/test/resources/org/springframework/security/config/http/InterceptUrlConfigTests-PathVariablesAuthorizationManager.xml
  81. 1 1
      config/src/test/resources/org/springframework/security/config/http/InterceptUrlConfigTests-Sec2256.xml
  82. 1 1
      config/src/test/resources/org/springframework/security/config/http/InterceptUrlConfigTests-Sec2256AuthorizationManager.xml
  83. 1 1
      config/src/test/resources/org/springframework/security/config/http/InterceptUrlConfigTests-TypeConversionPathVariables.xml
  84. 1 1
      config/src/test/resources/org/springframework/security/config/http/InterceptUrlConfigTests-TypeConversionPathVariablesAuthorizationManager.xml
  85. 1 1
      config/src/test/resources/org/springframework/security/config/http/MiscHttpConfigTests-AnonymousDisabled.xml
  86. 1 1
      config/src/test/resources/org/springframework/security/config/http/MiscHttpConfigTests-AnonymousEndpoints.xml
  87. 1 1
      config/src/test/resources/org/springframework/security/config/http/MiscHttpConfigTests-CustomHttpBasicEntryPointRef.xml
  88. 1 1
      config/src/test/resources/org/springframework/security/config/http/MiscHttpConfigTests-CustomRequestMatcher.xml
  89. 1 1
      config/src/test/resources/org/springframework/security/config/http/MiscHttpConfigTests-NoSecurityForPattern.xml
  90. 1 1
      config/src/test/resources/org/springframework/security/config/http/MiscHttpConfigTests-OncePerRequest.xml
  91. 1 1
      config/src/test/resources/org/springframework/security/config/http/MiscHttpConfigTests-OncePerRequestTrue.xml
  92. 1 1
      config/src/test/resources/org/springframework/security/config/http/MiscHttpConfigTests-ProtectedLoginPage.xml
  93. 1 1
      config/src/test/resources/org/springframework/security/config/http/MiscHttpConfigTests-ProtectedLoginPageAuthorizationManager.xml
  94. 1 1
      config/src/test/resources/org/springframework/security/config/http/MultiHttpBlockConfigTests-DistinctHttpElements.xml
  95. 1 1
      config/src/test/resources/org/springframework/security/config/http/MultiHttpBlockConfigTests-IdenticallyPatternedHttpElements.xml
  96. 1 1
      config/src/test/resources/org/springframework/security/config/http/MultiHttpBlockConfigTests-Sec1937.xml
  97. 1 1
      config/src/test/resources/org/springframework/security/config/http/OAuth2ResourceServerBeanDefinitionParserTests-AuthenticationManagerResolver.xml
  98. 1 1
      config/src/test/resources/org/springframework/security/config/http/OAuth2ResourceServerBeanDefinitionParserTests-BasicAndResourceServer.xml
  99. 1 1
      config/src/test/resources/org/springframework/security/config/http/OAuth2ResourceServerBeanDefinitionParserTests-FormAndResourceServer.xml
  100. 1 1
      config/src/test/resources/org/springframework/security/config/http/OAuth2ResourceServerBeanDefinitionParserTests-JwkSetUri.xml

+ 1 - 2
cas/src/main/java/org/springframework/security/cas/web/CasAuthenticationFilter.java

@@ -52,7 +52,6 @@ import org.springframework.security.web.savedrequest.HttpSessionRequestCache;
 import org.springframework.security.web.savedrequest.RequestCache;
 import org.springframework.security.web.savedrequest.SavedRequest;
 import org.springframework.security.web.servlet.util.matcher.PathPatternRequestMatcher;
-import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
 import org.springframework.security.web.util.matcher.RequestMatcher;
 import org.springframework.util.Assert;
 import org.springframework.util.StringUtils;
@@ -335,7 +334,7 @@ public class CasAuthenticationFilter extends AbstractAuthenticationProcessingFil
 	}
 
 	public final void setProxyReceptorUrl(final String proxyReceptorUrl) {
-		this.proxyReceptorMatcher = new AntPathRequestMatcher("/**" + proxyReceptorUrl);
+		this.proxyReceptorMatcher = PathPatternRequestMatcher.withDefaults().matcher(proxyReceptorUrl);
 	}
 
 	public final void setProxyGrantingTicketStorage(final ProxyGrantingTicketStorage proxyGrantingTicketStorage) {

+ 14 - 329
config/src/main/java/org/springframework/security/config/annotation/web/AbstractRequestMatcherRegistry.java

@@ -18,41 +18,20 @@ package org.springframework.security.config.annotation.web;
 
 import java.util.ArrayList;
 import java.util.Arrays;
-import java.util.Collection;
-import java.util.LinkedHashMap;
 import java.util.List;
-import java.util.Map;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.atomic.AtomicReference;
-import java.util.function.Function;
 
 import jakarta.servlet.DispatcherType;
-import jakarta.servlet.ServletContext;
-import jakarta.servlet.ServletRegistration;
-import jakarta.servlet.http.HttpServletRequest;
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 
-import org.springframework.beans.factory.NoSuchBeanDefinitionException;
-import org.springframework.beans.factory.ObjectProvider;
 import org.springframework.context.ApplicationContext;
-import org.springframework.core.ResolvableType;
 import org.springframework.http.HttpMethod;
 import org.springframework.lang.Nullable;
-import org.springframework.security.config.ObjectPostProcessor;
-import org.springframework.security.config.annotation.web.ServletRegistrationsSupport.RegistrationMapping;
-import org.springframework.security.web.servlet.util.matcher.MvcRequestMatcher;
-import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
+import org.springframework.security.web.servlet.util.matcher.PathPatternRequestMatcher;
 import org.springframework.security.web.util.matcher.AnyRequestMatcher;
 import org.springframework.security.web.util.matcher.DispatcherTypeRequestMatcher;
-import org.springframework.security.web.util.matcher.OrRequestMatcher;
-import org.springframework.security.web.util.matcher.RegexRequestMatcher;
 import org.springframework.security.web.util.matcher.RequestMatcher;
 import org.springframework.util.Assert;
-import org.springframework.util.ClassUtils;
-import org.springframework.web.context.WebApplicationContext;
-import org.springframework.web.servlet.DispatcherServlet;
-import org.springframework.web.servlet.handler.HandlerMappingIntrospector;
 
 /**
  * A base class for registering {@link RequestMatcher}'s. For example, it might allow for
@@ -65,23 +44,12 @@ import org.springframework.web.servlet.handler.HandlerMappingIntrospector;
  */
 public abstract class AbstractRequestMatcherRegistry<C> {
 
-	private static final String HANDLER_MAPPING_INTROSPECTOR_BEAN_NAME = "mvcHandlerMappingIntrospector";
-
-	private static final String HANDLER_MAPPING_INTROSPECTOR = "org.springframework.web.servlet.handler.HandlerMappingIntrospector";
-
-	private static final boolean mvcPresent;
-
 	private static final RequestMatcher ANY_REQUEST = AnyRequestMatcher.INSTANCE;
 
 	private ApplicationContext context;
 
 	private boolean anyRequestConfigured = false;
 
-	static {
-		mvcPresent = ClassUtils.isPresent(HANDLER_MAPPING_INTROSPECTOR,
-				AbstractRequestMatcherRegistry.class.getClassLoader());
-	}
-
 	private final Log logger = LogFactory.getLog(getClass());
 
 	protected final void setApplicationContext(ApplicationContext context) {
@@ -107,40 +75,6 @@ public abstract class AbstractRequestMatcherRegistry<C> {
 		return configurer;
 	}
 
-	/**
-	 * Creates {@link MvcRequestMatcher} instances for the method and patterns passed in
-	 * @param method the HTTP method to use or null if any should be used
-	 * @param mvcPatterns the Spring MVC patterns to match on
-	 * @return a List of {@link MvcRequestMatcher} instances
-	 * @deprecated Please use
-	 * {@link org.springframework.security.web.servlet.util.matcher.PathPatternRequestMatcher.Builder}
-	 * instead
-	 */
-	@Deprecated
-	protected final List<MvcRequestMatcher> createMvcMatchers(HttpMethod method, String... mvcPatterns) {
-		Assert.state(!this.anyRequestConfigured, "Can't configure mvcMatchers after anyRequest");
-		ResolvableType type = ResolvableType.forClassWithGenerics(ObjectPostProcessor.class, Object.class);
-		ObjectProvider<ObjectPostProcessor<Object>> postProcessors = this.context.getBeanProvider(type);
-		ObjectPostProcessor<Object> opp = postProcessors.getObject();
-		if (!this.context.containsBean(HANDLER_MAPPING_INTROSPECTOR_BEAN_NAME)) {
-			throw new NoSuchBeanDefinitionException("A Bean named " + HANDLER_MAPPING_INTROSPECTOR_BEAN_NAME
-					+ " of type " + HandlerMappingIntrospector.class.getName()
-					+ " is required to use MvcRequestMatcher. Please ensure Spring Security & Spring MVC are configured in a shared ApplicationContext.");
-		}
-		HandlerMappingIntrospector introspector = this.context.getBean(HANDLER_MAPPING_INTROSPECTOR_BEAN_NAME,
-				HandlerMappingIntrospector.class);
-		List<MvcRequestMatcher> matchers = new ArrayList<>(mvcPatterns.length);
-		for (String mvcPattern : mvcPatterns) {
-			MvcRequestMatcher matcher = new MvcRequestMatcher(introspector, mvcPattern);
-			opp.postProcess(matcher);
-			if (method != null) {
-				matcher.setMethod(method);
-			}
-			matchers.add(matcher);
-		}
-		return matchers;
-	}
-
 	/**
 	 * Maps a {@link List} of
 	 * {@link org.springframework.security.web.util.matcher.DispatcherTypeRequestMatcher}
@@ -184,12 +118,9 @@ public abstract class AbstractRequestMatcherRegistry<C> {
 
 	/**
 	 * <p>
-	 * If the {@link HandlerMappingIntrospector} is available in the classpath, maps to an
-	 * {@link MvcRequestMatcher} that also specifies a specific {@link HttpMethod} to
-	 * match on. This matcher will use the same rules that Spring MVC uses for matching.
-	 * For example, often times a mapping of the path "/path" will match on "/path",
-	 * "/path/", "/path.html", etc. If the {@link HandlerMappingIntrospector} is not
-	 * available, maps to an {@link AntPathRequestMatcher}.
+	 * Match when the {@link HttpMethod} is {@code method} and when the request URI
+	 * matches one of {@code patterns}. See
+	 * {@link org.springframework.web.util.pattern.PathPattern} for matching rules.
 	 * </p>
 	 * <p>
 	 * If a specific {@link RequestMatcher} must be specified, use
@@ -197,8 +128,7 @@ public abstract class AbstractRequestMatcherRegistry<C> {
 	 * </p>
 	 * @param method the {@link HttpMethod} to use or {@code null} for any
 	 * {@link HttpMethod}.
-	 * @param patterns the patterns to match on. The rules for matching are defined by
-	 * Spring MVC if {@link MvcRequestMatcher} is used
+	 * @param patterns the patterns to match on
 	 * @return the object that is chained after creating the {@link RequestMatcher}.
 	 * @since 5.8
 	 */
@@ -209,27 +139,13 @@ public abstract class AbstractRequestMatcherRegistry<C> {
 					+ "leading slash in all your request matcher patterns. In future versions of "
 					+ "Spring Security, leaving out the leading slash will result in an exception.");
 		}
-		if (!mvcPresent) {
-			return requestMatchers(RequestMatchers.antMatchersAsArray(method, patterns));
-		}
-		if (!(this.context instanceof WebApplicationContext)) {
-			return requestMatchers(RequestMatchers.antMatchersAsArray(method, patterns));
-		}
-		WebApplicationContext context = (WebApplicationContext) this.context;
-		ServletContext servletContext = context.getServletContext();
-		if (servletContext == null) {
-			return requestMatchers(RequestMatchers.antMatchersAsArray(method, patterns));
-		}
+		Assert.state(!this.anyRequestConfigured, "Can't configure requestMatchers after anyRequest");
+		PathPatternRequestMatcher.Builder builder = this.context
+			.getBeanProvider(PathPatternRequestMatcher.Builder.class)
+			.getIfUnique(PathPatternRequestMatcher::withDefaults);
 		List<RequestMatcher> matchers = new ArrayList<>();
 		for (String pattern : patterns) {
-			if (RequestMatcherFactory.usesPathPatterns()) {
-				matchers.add(RequestMatcherFactory.matcher(method, pattern));
-			}
-			else {
-				AntPathRequestMatcher ant = new AntPathRequestMatcher(pattern, (method != null) ? method.name() : null);
-				MvcRequestMatcher mvc = createMvcMatchers(method, pattern).get(0);
-				matchers.add(new DeferredRequestMatcher((c) -> resolve(ant, mvc, c), mvc, ant));
-			}
+			matchers.add(builder.matcher(method, pattern));
 		}
 		return requestMatchers(matchers.toArray(new RequestMatcher[0]));
 	}
@@ -243,64 +159,16 @@ public abstract class AbstractRequestMatcherRegistry<C> {
 		return false;
 	}
 
-	private RequestMatcher resolve(AntPathRequestMatcher ant, MvcRequestMatcher mvc, ServletContext servletContext) {
-		ServletRegistrationsSupport registrations = new ServletRegistrationsSupport(servletContext);
-		Collection<RegistrationMapping> mappings = registrations.mappings();
-		if (mappings.isEmpty()) {
-			return new DispatcherServletDelegatingRequestMatcher(ant, mvc, new MockMvcRequestMatcher());
-		}
-		Collection<RegistrationMapping> dispatcherServletMappings = registrations.dispatcherServletMappings();
-		if (dispatcherServletMappings.isEmpty()) {
-			return new DispatcherServletDelegatingRequestMatcher(ant, mvc, new MockMvcRequestMatcher());
-		}
-		if (dispatcherServletMappings.size() > 1) {
-			String errorMessage = computeErrorMessage(servletContext.getServletRegistrations().values());
-			throw new IllegalArgumentException(errorMessage);
-		}
-		RegistrationMapping dispatcherServlet = dispatcherServletMappings.iterator().next();
-		if (mappings.size() > 1 && !dispatcherServlet.isDefault()) {
-			String errorMessage = computeErrorMessage(servletContext.getServletRegistrations().values());
-			throw new IllegalArgumentException(errorMessage);
-		}
-		if (dispatcherServlet.isDefault()) {
-			if (mappings.size() == 1) {
-				return mvc;
-			}
-			return new DispatcherServletDelegatingRequestMatcher(ant, mvc);
-		}
-		return mvc;
-	}
-
-	private static String computeErrorMessage(Collection<? extends ServletRegistration> registrations) {
-		String template = """
-				This method cannot decide whether these patterns are Spring MVC patterns or not. \
-				This is because there is more than one mappable servlet in your servlet context: %s.
-
-				To address this, please create one PathPatternRequestMatcher.Builder#servletPath for each servlet that has \
-				authorized endpoints and use them to construct request matchers manually.
-				""";
-		Map<String, Collection<String>> mappings = new LinkedHashMap<>();
-		for (ServletRegistration registration : registrations) {
-			mappings.put(registration.getClassName(), registration.getMappings());
-		}
-		return String.format(template, mappings);
-	}
-
 	/**
 	 * <p>
-	 * If the {@link HandlerMappingIntrospector} is available in the classpath, maps to an
-	 * {@link MvcRequestMatcher} that does not care which {@link HttpMethod} is used. This
-	 * matcher will use the same rules that Spring MVC uses for matching. For example,
-	 * often times a mapping of the path "/path" will match on "/path", "/path/",
-	 * "/path.html", etc. If the {@link HandlerMappingIntrospector} is not available, maps
-	 * to an {@link AntPathRequestMatcher}.
+	 * Match when the request URI matches one of {@code patterns}. See
+	 * {@link org.springframework.web.util.pattern.PathPattern} for matching rules.
 	 * </p>
 	 * <p>
 	 * If a specific {@link RequestMatcher} must be specified, use
 	 * {@link #requestMatchers(RequestMatcher...)} instead
 	 * </p>
-	 * @param patterns the patterns to match on. The rules for matching are defined by
-	 * Spring MVC if {@link MvcRequestMatcher} is used
+	 * @param patterns the patterns to match on
 	 * @return the object that is chained after creating the {@link RequestMatcher}.
 	 * @since 5.8
 	 */
@@ -310,12 +178,7 @@ public abstract class AbstractRequestMatcherRegistry<C> {
 
 	/**
 	 * <p>
-	 * If the {@link HandlerMappingIntrospector} is available in the classpath, maps to an
-	 * {@link MvcRequestMatcher} that matches on a specific {@link HttpMethod}. This
-	 * matcher will use the same rules that Spring MVC uses for matching. For example,
-	 * often times a mapping of the path "/path" will match on "/path", "/path/",
-	 * "/path.html", etc. If the {@link HandlerMappingIntrospector} is not available, maps
-	 * to an {@link AntPathRequestMatcher}.
+	 * Match when the {@link HttpMethod} is {@code method}
 	 * </p>
 	 * <p>
 	 * If a specific {@link RequestMatcher} must be specified, use
@@ -339,182 +202,4 @@ public abstract class AbstractRequestMatcherRegistry<C> {
 	 */
 	protected abstract C chainRequestMatchers(List<RequestMatcher> requestMatchers);
 
-	/**
-	 * Utilities for creating {@link RequestMatcher} instances.
-	 *
-	 * @author Rob Winch
-	 * @since 3.2
-	 */
-	private static final class RequestMatchers {
-
-		private RequestMatchers() {
-		}
-
-		/**
-		 * Create a {@link List} of {@link AntPathRequestMatcher} instances.
-		 * @param httpMethod the {@link HttpMethod} to use or {@code null} for any
-		 * {@link HttpMethod}.
-		 * @param antPatterns the ant patterns to create {@link AntPathRequestMatcher}
-		 * from
-		 * @return a {@link List} of {@link AntPathRequestMatcher} instances
-		 */
-		static List<RequestMatcher> antMatchers(HttpMethod httpMethod, String... antPatterns) {
-			return Arrays.asList(antMatchersAsArray(httpMethod, antPatterns));
-		}
-
-		/**
-		 * Create a {@link List} of {@link AntPathRequestMatcher} instances that do not
-		 * specify an {@link HttpMethod}.
-		 * @param antPatterns the ant patterns to create {@link AntPathRequestMatcher}
-		 * from
-		 * @return a {@link List} of {@link AntPathRequestMatcher} instances
-		 */
-		static List<RequestMatcher> antMatchers(String... antPatterns) {
-			return antMatchers(null, antPatterns);
-		}
-
-		static RequestMatcher[] antMatchersAsArray(HttpMethod httpMethod, String... antPatterns) {
-			String method = (httpMethod != null) ? httpMethod.toString() : null;
-			RequestMatcher[] matchers = new RequestMatcher[antPatterns.length];
-			for (int index = 0; index < antPatterns.length; index++) {
-				matchers[index] = new AntPathRequestMatcher(antPatterns[index], method);
-			}
-			return matchers;
-		}
-
-		/**
-		 * Create a {@link List} of {@link RegexRequestMatcher} instances.
-		 * @param httpMethod the {@link HttpMethod} to use or {@code null} for any
-		 * {@link HttpMethod}.
-		 * @param regexPatterns the regular expressions to create
-		 * {@link RegexRequestMatcher} from
-		 * @return a {@link List} of {@link RegexRequestMatcher} instances
-		 */
-		static List<RequestMatcher> regexMatchers(HttpMethod httpMethod, String... regexPatterns) {
-			String method = (httpMethod != null) ? httpMethod.toString() : null;
-			List<RequestMatcher> matchers = new ArrayList<>();
-			for (String pattern : regexPatterns) {
-				matchers.add(new RegexRequestMatcher(pattern, method));
-			}
-			return matchers;
-		}
-
-		/**
-		 * Create a {@link List} of {@link RegexRequestMatcher} instances that do not
-		 * specify an {@link HttpMethod}.
-		 * @param regexPatterns the regular expressions to create
-		 * {@link RegexRequestMatcher} from
-		 * @return a {@link List} of {@link RegexRequestMatcher} instances
-		 */
-		static List<RequestMatcher> regexMatchers(String... regexPatterns) {
-			return regexMatchers(null, regexPatterns);
-		}
-
-	}
-
-	static class DeferredRequestMatcher implements RequestMatcher {
-
-		final Function<ServletContext, RequestMatcher> requestMatcherFactory;
-
-		final AtomicReference<String> description = new AtomicReference<>();
-
-		final Map<ServletContext, RequestMatcher> requestMatchers = new ConcurrentHashMap<>();
-
-		DeferredRequestMatcher(Function<ServletContext, RequestMatcher> resolver, RequestMatcher... candidates) {
-			this.requestMatcherFactory = (sc) -> this.requestMatchers.computeIfAbsent(sc, resolver);
-			this.description.set("Deferred " + Arrays.toString(candidates));
-		}
-
-		RequestMatcher requestMatcher(ServletContext servletContext) {
-			return this.requestMatcherFactory.apply(servletContext);
-		}
-
-		@Override
-		public boolean matches(HttpServletRequest request) {
-			return this.requestMatcherFactory.apply(request.getServletContext()).matches(request);
-		}
-
-		@Override
-		public MatchResult matcher(HttpServletRequest request) {
-			return this.requestMatcherFactory.apply(request.getServletContext()).matcher(request);
-		}
-
-		@Override
-		public String toString() {
-			return this.description.get();
-		}
-
-	}
-
-	static class MockMvcRequestMatcher implements RequestMatcher {
-
-		@Override
-		public boolean matches(HttpServletRequest request) {
-			return request.getAttribute("org.springframework.test.web.servlet.MockMvc.MVC_RESULT_ATTRIBUTE") != null;
-		}
-
-	}
-
-	static class DispatcherServletRequestMatcher implements RequestMatcher {
-
-		@Override
-		public boolean matches(HttpServletRequest request) {
-			String name = request.getHttpServletMapping().getServletName();
-			ServletRegistration registration = request.getServletContext().getServletRegistration(name);
-			Assert.notNull(registration,
-					() -> computeErrorMessage(request.getServletContext().getServletRegistrations().values()));
-			try {
-				Class<?> clazz = Class.forName(registration.getClassName());
-				return DispatcherServlet.class.isAssignableFrom(clazz);
-			}
-			catch (ClassNotFoundException ex) {
-				return false;
-			}
-		}
-
-	}
-
-	static class DispatcherServletDelegatingRequestMatcher implements RequestMatcher {
-
-		private final AntPathRequestMatcher ant;
-
-		private final MvcRequestMatcher mvc;
-
-		private final RequestMatcher dispatcherServlet;
-
-		DispatcherServletDelegatingRequestMatcher(AntPathRequestMatcher ant, MvcRequestMatcher mvc) {
-			this(ant, mvc, new OrRequestMatcher(new MockMvcRequestMatcher(), new DispatcherServletRequestMatcher()));
-		}
-
-		DispatcherServletDelegatingRequestMatcher(AntPathRequestMatcher ant, MvcRequestMatcher mvc,
-				RequestMatcher dispatcherServlet) {
-			this.ant = ant;
-			this.mvc = mvc;
-			this.dispatcherServlet = dispatcherServlet;
-		}
-
-		RequestMatcher requestMatcher(HttpServletRequest request) {
-			if (this.dispatcherServlet.matches(request)) {
-				return this.mvc;
-			}
-			return this.ant;
-		}
-
-		@Override
-		public boolean matches(HttpServletRequest request) {
-			return requestMatcher(request).matches(request);
-		}
-
-		@Override
-		public MatchResult matcher(HttpServletRequest request) {
-			return requestMatcher(request).matcher(request);
-		}
-
-		@Override
-		public String toString() {
-			return "DispatcherServletDelegating [" + "ant = " + this.ant + ", mvc = " + this.mvc + "]";
-		}
-
-	}
-
 }

+ 3 - 10
config/src/main/java/org/springframework/security/config/annotation/web/RequestMatcherFactory.java

@@ -19,7 +19,6 @@ package org.springframework.security.config.annotation.web;
 import org.springframework.context.ApplicationContext;
 import org.springframework.http.HttpMethod;
 import org.springframework.security.web.servlet.util.matcher.PathPatternRequestMatcher;
-import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
 import org.springframework.security.web.util.matcher.RequestMatcher;
 
 /**
@@ -34,11 +33,8 @@ public final class RequestMatcherFactory {
 	private static PathPatternRequestMatcher.Builder builder;
 
 	public static void setApplicationContext(ApplicationContext context) {
-		builder = context.getBeanProvider(PathPatternRequestMatcher.Builder.class).getIfUnique();
-	}
-
-	public static boolean usesPathPatterns() {
-		return builder != null;
+		builder = context.getBeanProvider(PathPatternRequestMatcher.Builder.class)
+			.getIfUnique(PathPatternRequestMatcher::withDefaults);
 	}
 
 	public static RequestMatcher matcher(String path) {
@@ -46,10 +42,7 @@ public final class RequestMatcherFactory {
 	}
 
 	public static RequestMatcher matcher(HttpMethod method, String path) {
-		if (builder != null) {
-			return builder.matcher(method, path);
-		}
-		return new AntPathRequestMatcher(path, (method != null) ? method.name() : null);
+		return builder.matcher(method, path);
 	}
 
 	private RequestMatcherFactory() {

+ 10 - 52
config/src/main/java/org/springframework/security/config/annotation/web/builders/HttpSecurity.java

@@ -28,7 +28,6 @@ import jakarta.servlet.ServletRequest;
 import jakarta.servlet.ServletResponse;
 import jakarta.servlet.http.HttpServletRequest;
 
-import org.springframework.beans.factory.NoSuchBeanDefinitionException;
 import org.springframework.beans.factory.ObjectProvider;
 import org.springframework.context.ApplicationContext;
 import org.springframework.core.OrderComparator;
@@ -45,7 +44,6 @@ import org.springframework.security.config.annotation.SecurityConfigurerAdapter;
 import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
 import org.springframework.security.config.annotation.web.AbstractRequestMatcherRegistry;
 import org.springframework.security.config.annotation.web.HttpSecurityBuilder;
-import org.springframework.security.config.annotation.web.RequestMatcherFactory;
 import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
 import org.springframework.security.config.annotation.web.configuration.WebSecurityConfiguration;
 import org.springframework.security.config.annotation.web.configurers.AnonymousConfigurer;
@@ -91,17 +89,14 @@ import org.springframework.security.web.PortMapperImpl;
 import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
 import org.springframework.security.web.context.AbstractSecurityWebApplicationInitializer;
 import org.springframework.security.web.context.SecurityContextRepository;
-import org.springframework.security.web.servlet.util.matcher.MvcRequestMatcher;
+import org.springframework.security.web.servlet.util.matcher.PathPatternRequestMatcher;
 import org.springframework.security.web.session.HttpSessionEventPublisher;
-import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
 import org.springframework.security.web.util.matcher.AnyRequestMatcher;
 import org.springframework.security.web.util.matcher.OrRequestMatcher;
 import org.springframework.security.web.util.matcher.RequestMatcher;
 import org.springframework.util.Assert;
-import org.springframework.util.ClassUtils;
 import org.springframework.web.cors.CorsConfiguration;
 import org.springframework.web.filter.CorsFilter;
-import org.springframework.web.servlet.handler.HandlerMappingIntrospector;
 
 /**
  * A {@link HttpSecurity} is similar to Spring Security's XML &lt;http&gt; element in the
@@ -153,12 +148,6 @@ import org.springframework.web.servlet.handler.HandlerMappingIntrospector;
 public final class HttpSecurity extends AbstractConfiguredSecurityBuilder<DefaultSecurityFilterChain, HttpSecurity>
 		implements SecurityBuilder<DefaultSecurityFilterChain>, HttpSecurityBuilder<HttpSecurity> {
 
-	private static final String HANDLER_MAPPING_INTROSPECTOR_BEAN_NAME = "mvcHandlerMappingIntrospector";
-
-	private static final String HANDLER_MAPPING_INTROSPECTOR = "org.springframework.web.servlet.handler.HandlerMappingIntrospector";
-
-	private static final boolean mvcPresent;
-
 	private final RequestMatcherConfigurer requestMatcherConfigurer;
 
 	private List<OrderedFilter> filters = new ArrayList<>();
@@ -169,10 +158,6 @@ public final class HttpSecurity extends AbstractConfiguredSecurityBuilder<Defaul
 
 	private AuthenticationManager authenticationManager;
 
-	static {
-		mvcPresent = ClassUtils.isPresent(HANDLER_MAPPING_INTROSPECTOR, HttpSecurity.class.getClassLoader());
-	}
-
 	/**
 	 * Creates a new instance
 	 * @param objectPostProcessor the {@link ObjectPostProcessor} that should be used
@@ -320,9 +305,7 @@ public final class HttpSecurity extends AbstractConfiguredSecurityBuilder<Defaul
 	/**
 	 * Adds a {@link CorsFilter} to be used. If a bean by the name of corsFilter is
 	 * provided, that {@link CorsFilter} is used. Else if corsConfigurationSource is
-	 * defined, then that {@link CorsConfiguration} is used. Otherwise, if Spring MVC is
-	 * on the classpath a {@link HandlerMappingIntrospector} is used. You can enable CORS
-	 * using:
+	 * defined, then that {@link CorsConfiguration} is used. You can enable CORS using:
 	 *
 	 * <pre>
 	 * &#064;Configuration
@@ -2202,10 +2185,8 @@ public final class HttpSecurity extends AbstractConfiguredSecurityBuilder<Defaul
 
 	/**
 	 * Allows configuring the {@link HttpSecurity} to only be invoked when matching the
-	 * provided pattern. This method creates a {@link MvcRequestMatcher} if Spring MVC is
-	 * in the classpath or creates an {@link AntPathRequestMatcher} if not. If more
-	 * advanced configuration is necessary, consider using
-	 * {@link #securityMatchers(Customizer)} or {@link #securityMatcher(RequestMatcher)}.
+	 * provided set of {@code patterns}. See
+	 * {@link org.springframework.web.util.pattern.PathPattern} for matching rules
 	 *
 	 * <p>
 	 * Invoking {@link #securityMatcher(String...)} will override previous invocations of
@@ -2215,19 +2196,16 @@ public final class HttpSecurity extends AbstractConfiguredSecurityBuilder<Defaul
 	 * </p>
 	 * @param patterns the pattern to match on (i.e. "/admin/**")
 	 * @return the {@link HttpSecurity} for further customizations
-	 * @see AntPathRequestMatcher
-	 * @see MvcRequestMatcher
+	 * @see org.springframework.security.web.servlet.util.matcher.PathPatternRequestMatcher
+	 * @see org.springframework.web.util.pattern.PathPattern
 	 */
 	public HttpSecurity securityMatcher(String... patterns) {
 		List<RequestMatcher> matchers = new ArrayList<>();
+		PathPatternRequestMatcher.Builder builder = getContext()
+			.getBeanProvider(PathPatternRequestMatcher.Builder.class)
+			.getIfUnique(PathPatternRequestMatcher::withDefaults);
 		for (String pattern : patterns) {
-			if (RequestMatcherFactory.usesPathPatterns()) {
-				matchers.add(RequestMatcherFactory.matcher(pattern));
-			}
-			else {
-				RequestMatcher matcher = mvcPresent ? createMvcMatcher(pattern) : createAntMatcher(pattern);
-				matchers.add(matcher);
-			}
+			matchers.add(builder.matcher(pattern));
 		}
 		this.requestMatcher = new OrRequestMatcher(matchers);
 		return this;
@@ -2258,26 +2236,6 @@ public final class HttpSecurity extends AbstractConfiguredSecurityBuilder<Defaul
 		return HttpSecurity.this;
 	}
 
-	private RequestMatcher createAntMatcher(String pattern) {
-		return new AntPathRequestMatcher(pattern);
-	}
-
-	private RequestMatcher createMvcMatcher(String mvcPattern) {
-		ResolvableType type = ResolvableType.forClassWithGenerics(ObjectPostProcessor.class, Object.class);
-		ObjectProvider<ObjectPostProcessor<Object>> postProcessors = getContext().getBeanProvider(type);
-		ObjectPostProcessor<Object> opp = postProcessors.getObject();
-		if (!getContext().containsBean(HANDLER_MAPPING_INTROSPECTOR_BEAN_NAME)) {
-			throw new NoSuchBeanDefinitionException("A Bean named " + HANDLER_MAPPING_INTROSPECTOR_BEAN_NAME
-					+ " of type " + HandlerMappingIntrospector.class.getName()
-					+ " is required to use MvcRequestMatcher. Please ensure Spring Security & Spring MVC are configured in a shared ApplicationContext.");
-		}
-		HandlerMappingIntrospector introspector = getContext().getBean(HANDLER_MAPPING_INTROSPECTOR_BEAN_NAME,
-				HandlerMappingIntrospector.class);
-		MvcRequestMatcher matcher = new MvcRequestMatcher(introspector, mvcPattern);
-		opp.postProcess(matcher);
-		return matcher;
-	}
-
 	/**
 	 * If the {@link SecurityConfigurer} has already been specified get the original,
 	 * otherwise apply the new {@link SecurityConfigurerAdapter}.

+ 2 - 1
config/src/main/java/org/springframework/security/config/annotation/web/builders/WebSecurity.java

@@ -55,6 +55,7 @@ import org.springframework.security.web.SecurityFilterChain;
 import org.springframework.security.web.access.AuthorizationManagerWebInvocationPrivilegeEvaluator;
 import org.springframework.security.web.access.AuthorizationManagerWebInvocationPrivilegeEvaluator.HttpServletRequestTransformer;
 import org.springframework.security.web.access.DefaultWebInvocationPrivilegeEvaluator;
+import org.springframework.security.web.access.PathPatternRequestTransformer;
 import org.springframework.security.web.access.RequestMatcherDelegatingWebInvocationPrivilegeEvaluator;
 import org.springframework.security.web.access.WebInvocationPrivilegeEvaluator;
 import org.springframework.security.web.access.expression.DefaultWebSecurityExpressionHandler;
@@ -430,7 +431,7 @@ public final class WebSecurity extends AbstractConfiguredSecurityBuilder<Filter,
 		this.filterChainDecoratorPostProcessor = postProcessor.getIfUnique(ObjectPostProcessor::identity);
 		Class<HttpServletRequestTransformer> requestTransformerClass = HttpServletRequestTransformer.class;
 		this.privilegeEvaluatorRequestTransformer = applicationContext.getBeanProvider(requestTransformerClass)
-			.getIfUnique();
+			.getIfUnique(PathPatternRequestTransformer::new);
 	}
 
 	@Override

+ 0 - 95
config/src/main/java/org/springframework/security/config/annotation/web/configuration/WebMvcSecurityConfiguration.java

@@ -26,15 +26,7 @@ import jakarta.servlet.ServletRequest;
 import jakarta.servlet.ServletResponse;
 import jakarta.servlet.http.HttpServletRequest;
 
-import org.springframework.beans.BeanMetadataElement;
 import org.springframework.beans.BeansException;
-import org.springframework.beans.factory.FactoryBean;
-import org.springframework.beans.factory.config.BeanDefinition;
-import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
-import org.springframework.beans.factory.support.BeanDefinitionBuilder;
-import org.springframework.beans.factory.support.BeanDefinitionRegistry;
-import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor;
-import org.springframework.beans.factory.support.ManagedList;
 import org.springframework.context.ApplicationContext;
 import org.springframework.context.ApplicationContextAware;
 import org.springframework.context.annotation.Bean;
@@ -45,8 +37,6 @@ import org.springframework.security.core.context.SecurityContextHolder;
 import org.springframework.security.core.context.SecurityContextHolderStrategy;
 import org.springframework.security.web.FilterChainProxy;
 import org.springframework.security.web.SecurityFilterChain;
-import org.springframework.security.web.access.HandlerMappingIntrospectorRequestTransformer;
-import org.springframework.security.web.context.AbstractSecurityWebApplicationInitializer;
 import org.springframework.security.web.debug.DebugFilter;
 import org.springframework.security.web.firewall.HttpFirewall;
 import org.springframework.security.web.firewall.RequestRejectedHandler;
@@ -58,7 +48,6 @@ import org.springframework.web.filter.CompositeFilter;
 import org.springframework.web.method.support.HandlerMethodArgumentResolver;
 import org.springframework.web.servlet.config.annotation.EnableWebMvc;
 import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
-import org.springframework.web.servlet.handler.HandlerMappingIntrospector;
 import org.springframework.web.servlet.support.RequestDataValueProcessor;
 
 /**
@@ -76,10 +65,6 @@ import org.springframework.web.servlet.support.RequestDataValueProcessor;
  */
 class WebMvcSecurityConfiguration implements WebMvcConfigurer, ApplicationContextAware {
 
-	private static final String HANDLER_MAPPING_INTROSPECTOR_BEAN_NAME = "mvcHandlerMappingIntrospector";
-
-	private static final String PATH_PATTERN_REQUEST_TRANSFORMER_BEAN_NAME = "pathPatternRequestTransformer";
-
 	private BeanResolver beanResolver;
 
 	private SecurityContextHolderStrategy securityContextHolderStrategy = SecurityContextHolder
@@ -121,86 +106,6 @@ class WebMvcSecurityConfiguration implements WebMvcConfigurer, ApplicationContex
 		}
 	}
 
-	@Bean
-	static BeanDefinitionRegistryPostProcessor springSecurityHandlerMappingIntrospectorBeanDefinitionRegistryPostProcessor() {
-		return new BeanDefinitionRegistryPostProcessor() {
-			@Override
-			public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
-			}
-
-			@Override
-			public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
-				if (!registry.containsBeanDefinition(HANDLER_MAPPING_INTROSPECTOR_BEAN_NAME)) {
-					return;
-				}
-
-				String hmiRequestTransformerBeanName = HANDLER_MAPPING_INTROSPECTOR_BEAN_NAME + "RequestTransformer";
-				if (!registry.containsBeanDefinition(PATH_PATTERN_REQUEST_TRANSFORMER_BEAN_NAME)
-						&& !registry.containsBeanDefinition(hmiRequestTransformerBeanName)) {
-					if (!registry.containsBeanDefinition(hmiRequestTransformerBeanName)) {
-						BeanDefinition hmiRequestTransformer = BeanDefinitionBuilder
-							.rootBeanDefinition(HandlerMappingIntrospectorRequestTransformer.class)
-							.addConstructorArgReference(HANDLER_MAPPING_INTROSPECTOR_BEAN_NAME)
-							.getBeanDefinition();
-						registry.registerBeanDefinition(hmiRequestTransformerBeanName, hmiRequestTransformer);
-					}
-				}
-
-				BeanDefinition filterChainProxy = registry
-					.getBeanDefinition(AbstractSecurityWebApplicationInitializer.DEFAULT_FILTER_NAME);
-
-				if (!filterChainProxy.getResolvableType().isInstance(CompositeFilterChainProxy.class)) {
-					BeanDefinitionBuilder hmiCacheFilterBldr = BeanDefinitionBuilder
-						.rootBeanDefinition(HandlerMappingIntrospectorCacheFilterFactoryBean.class)
-						.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
-
-					ManagedList<BeanMetadataElement> filters = new ManagedList<>();
-					filters.add(hmiCacheFilterBldr.getBeanDefinition());
-					filters.add(filterChainProxy);
-					BeanDefinitionBuilder compositeSpringSecurityFilterChainBldr = BeanDefinitionBuilder
-						.rootBeanDefinition(CompositeFilterChainProxy.class)
-						.addConstructorArgValue(filters);
-
-					registry.removeBeanDefinition(AbstractSecurityWebApplicationInitializer.DEFAULT_FILTER_NAME);
-					registry.registerBeanDefinition(AbstractSecurityWebApplicationInitializer.DEFAULT_FILTER_NAME,
-							compositeSpringSecurityFilterChainBldr.getBeanDefinition());
-				}
-			}
-		};
-	}
-
-	/**
-	 * {@link FactoryBean} to defer creation of
-	 * {@link HandlerMappingIntrospector#createCacheFilter()}
-	 *
-	 * @deprecated see {@link WebSecurityConfiguration} for
-	 * {@link org.springframework.web.util.pattern.PathPattern} replacement
-	 */
-	@Deprecated
-	static class HandlerMappingIntrospectorCacheFilterFactoryBean
-			implements ApplicationContextAware, FactoryBean<Filter> {
-
-		private ApplicationContext applicationContext;
-
-		@Override
-		public void setApplicationContext(ApplicationContext applicationContext) {
-			this.applicationContext = applicationContext;
-		}
-
-		@Override
-		public Filter getObject() throws Exception {
-			HandlerMappingIntrospector handlerMappingIntrospector = this.applicationContext
-				.getBean(HANDLER_MAPPING_INTROSPECTOR_BEAN_NAME, HandlerMappingIntrospector.class);
-			return handlerMappingIntrospector.createCacheFilter();
-		}
-
-		@Override
-		public Class<?> getObjectType() {
-			return Filter.class;
-		}
-
-	}
-
 	/**
 	 * Extends {@link FilterChainProxy} to provide as much passivity as possible but
 	 * delegates to {@link CompositeFilter} for

+ 3 - 5
config/src/main/java/org/springframework/security/config/annotation/web/configuration/WebSecurityConfiguration.java

@@ -69,7 +69,6 @@ import org.springframework.security.web.firewall.HttpFirewall;
 import org.springframework.security.web.firewall.RequestRejectedHandler;
 import org.springframework.web.filter.CompositeFilter;
 import org.springframework.web.filter.ServletRequestPathFilter;
-import org.springframework.web.servlet.handler.HandlerMappingIntrospector;
 
 /**
  * Uses a {@link WebSecurity} to create the {@link FilterChainProxy} that performs the web
@@ -209,12 +208,11 @@ public class WebSecurityConfiguration implements ImportAware {
 	/**
 	 * Used to ensure Spring MVC request matching is cached.
 	 *
-	 * Creates a {@link BeanDefinitionRegistryPostProcessor} that detects if a bean named
-	 * HANDLER_MAPPING_INTROSPECTOR_BEAN_NAME is defined. If so, it moves the
+	 * Creates a {@link BeanDefinitionRegistryPostProcessor} that moves the
 	 * AbstractSecurityWebApplicationInitializer.DEFAULT_FILTER_NAME to another bean name
 	 * and then adds a {@link CompositeFilter} that contains
-	 * {@link HandlerMappingIntrospector#createCacheFilter()} and the original
-	 * FilterChainProxy under the original Bean name.
+	 * {@link ServletRequestPathFilter} and the original FilterChainProxy under the
+	 * original Bean name.
 	 * @return
 	 */
 	@Bean

+ 1 - 16
config/src/main/java/org/springframework/security/config/annotation/web/configurers/CorsConfigurer.java

@@ -22,18 +22,14 @@ import org.springframework.security.config.Customizer;
 import org.springframework.security.config.annotation.web.HttpSecurityBuilder;
 import org.springframework.security.config.annotation.web.builders.HttpSecurity;
 import org.springframework.util.Assert;
-import org.springframework.util.ClassUtils;
 import org.springframework.web.cors.CorsConfiguration;
 import org.springframework.web.cors.CorsConfigurationSource;
 import org.springframework.web.filter.CorsFilter;
-import org.springframework.web.servlet.handler.HandlerMappingIntrospector;
 
 /**
  * Adds {@link CorsFilter} to the Spring Security filter chain. If a bean by the name of
  * corsFilter is provided, that {@link CorsFilter} is used. Else if
  * corsConfigurationSource is defined, then that {@link CorsConfiguration} is used.
- * Otherwise, if Spring MVC is on the classpath a {@link HandlerMappingIntrospector} is
- * used.
  *
  * @param <H> the builder to return.
  * @author Rob Winch
@@ -45,16 +41,8 @@ public class CorsConfigurer<H extends HttpSecurityBuilder<H>> extends AbstractHt
 
 	private static final String CORS_FILTER_BEAN_NAME = "corsFilter";
 
-	private static final String HANDLER_MAPPING_INTROSPECTOR = "org.springframework.web.servlet.handler.HandlerMappingIntrospector";
-
-	private static final boolean mvcPresent;
-
 	private CorsConfigurationSource configurationSource;
 
-	static {
-		mvcPresent = ClassUtils.isPresent(HANDLER_MAPPING_INTROSPECTOR, CorsConfigurer.class.getClassLoader());
-	}
-
 	/**
 	 * Creates a new instance
 	 *
@@ -91,10 +79,7 @@ public class CorsConfigurer<H extends HttpSecurityBuilder<H>> extends AbstractHt
 					CorsConfigurationSource.class);
 			return new CorsFilter(configurationSource);
 		}
-		if (mvcPresent) {
-			return MvcCorsFilter.getMvcCorsFilter(context);
-		}
-		return null;
+		return MvcCorsFilter.getMvcCorsFilter(context);
 	}
 
 	static class MvcCorsFilter {

+ 1 - 7
config/src/main/java/org/springframework/security/config/annotation/web/configurers/RequestCacheConfigurer.java

@@ -31,7 +31,6 @@ import org.springframework.security.web.savedrequest.NullRequestCache;
 import org.springframework.security.web.savedrequest.RequestCache;
 import org.springframework.security.web.savedrequest.RequestCacheAwareFilter;
 import org.springframework.security.web.util.matcher.AndRequestMatcher;
-import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
 import org.springframework.security.web.util.matcher.MediaTypeRequestMatcher;
 import org.springframework.security.web.util.matcher.NegatedRequestMatcher;
 import org.springframework.security.web.util.matcher.RequestHeaderRequestMatcher;
@@ -174,12 +173,7 @@ public final class RequestCacheConfigurer<H extends HttpSecurityBuilder<H>>
 	}
 
 	private RequestMatcher getFaviconRequestMatcher() {
-		if (RequestMatcherFactory.usesPathPatterns()) {
-			return RequestMatcherFactory.matcher("/favicon.*");
-		}
-		else {
-			return new AntPathRequestMatcher("/**/favicon.*");
-		}
+		return RequestMatcherFactory.matcher("/favicon.*");
 	}
 
 }

+ 0 - 4
config/src/main/java/org/springframework/security/config/aot/hint/WebMvcSecurityConfigurationRuntimeHints.java

@@ -35,10 +35,6 @@ class WebMvcSecurityConfigurationRuntimeHints implements RuntimeHintsRegistrar {
 			.registerType(TypeReference
 				.of("org.springframework.security.config.annotation.web.configuration.WebMvcSecurityConfiguration$CompositeFilterChainProxy"),
 					MemberCategory.INVOKE_DECLARED_CONSTRUCTORS);
-		hints.reflection()
-			.registerType(TypeReference
-				.of("org.springframework.security.config.annotation.web.configuration.WebMvcSecurityConfiguration$HandlerMappingIntrospectorCacheFilterFactoryBean"),
-					MemberCategory.INVOKE_DECLARED_CONSTRUCTORS);
 	}
 
 }

+ 1 - 1
config/src/main/java/org/springframework/security/config/http/AuthorizationFilterParser.java

@@ -153,7 +153,7 @@ class AuthorizationFilterParser implements BeanDefinitionParser {
 		if (!StringUtils.hasText(servletPath)) {
 			servletPath = null;
 		}
-		else if (!MatcherType.mvc.equals(matcherType)) {
+		else if (!MatcherType.path.equals(matcherType)) {
 			parserContext.getReaderContext()
 				.error(ATT_SERVLET_PATH + " is not applicable for request-matcher: '" + matcherType.name() + "'",
 						urlElt);

+ 1 - 14
config/src/main/java/org/springframework/security/config/http/CorsBeanDefinitionParser.java

@@ -24,7 +24,6 @@ import org.springframework.beans.factory.config.RuntimeBeanReference;
 import org.springframework.beans.factory.support.BeanDefinitionBuilder;
 import org.springframework.beans.factory.support.RootBeanDefinition;
 import org.springframework.beans.factory.xml.ParserContext;
-import org.springframework.util.ClassUtils;
 import org.springframework.util.StringUtils;
 import org.springframework.web.filter.CorsFilter;
 
@@ -40,15 +39,6 @@ public class CorsBeanDefinitionParser {
 
 	private static final String ATT_REF = "ref";
 
-	private static final String HANDLER_MAPPING_INTROSPECTOR = "org.springframework.web.servlet.handler.HandlerMappingIntrospector";
-
-	private static final boolean mvcPresent;
-
-	static {
-		mvcPresent = ClassUtils.isPresent(HANDLER_MAPPING_INTROSPECTOR,
-				CorsBeanDefinitionParser.class.getClassLoader());
-	}
-
 	public BeanMetadataElement parse(Element element, ParserContext parserContext) {
 		if (element == null) {
 			return null;
@@ -71,10 +61,7 @@ public class CorsBeanDefinitionParser {
 		if (StringUtils.hasText(configurationSourceRef)) {
 			return new RuntimeBeanReference(configurationSourceRef);
 		}
-		if (!mvcPresent) {
-			return null;
-		}
-		return new RootBeanDefinition(HandlerMappingIntrospectorFactoryBean.class);
+		return new RootBeanDefinition(CorsConfigurationSourceFactoryBean.class);
 	}
 
 }

+ 8 - 9
config/src/main/java/org/springframework/security/config/http/HandlerMappingIntrospectorFactoryBean.java → config/src/main/java/org/springframework/security/config/http/CorsConfigurationSourceFactoryBean.java

@@ -22,38 +22,37 @@ import org.springframework.beans.factory.NoSuchBeanDefinitionException;
 import org.springframework.context.ApplicationContext;
 import org.springframework.context.ApplicationContextAware;
 import org.springframework.lang.Nullable;
-import org.springframework.web.servlet.handler.HandlerMappingIntrospector;
+import org.springframework.web.cors.CorsConfigurationSource;
 
 /**
- * Used for creating an instance of {@link HandlerMappingIntrospector} and autowiring the
+ * Used for creating an instance of {@link CorsConfigurationSource} and autowiring the
  * {@link ApplicationContext}.
  *
  * @author Rob Winch
  * @since 4.1.1
  */
-class HandlerMappingIntrospectorFactoryBean
-		implements FactoryBean<HandlerMappingIntrospector>, ApplicationContextAware {
+class CorsConfigurationSourceFactoryBean implements FactoryBean<CorsConfigurationSource>, ApplicationContextAware {
 
 	private static final String HANDLER_MAPPING_INTROSPECTOR_BEAN_NAME = "mvcHandlerMappingIntrospector";
 
 	private ApplicationContext context;
 
 	@Override
-	public HandlerMappingIntrospector getObject() {
+	public CorsConfigurationSource getObject() {
 		if (!this.context.containsBean(HANDLER_MAPPING_INTROSPECTOR_BEAN_NAME)) {
 			throw new NoSuchBeanDefinitionException(HANDLER_MAPPING_INTROSPECTOR_BEAN_NAME,
 					"A Bean named " + HANDLER_MAPPING_INTROSPECTOR_BEAN_NAME + " of type "
-							+ HandlerMappingIntrospector.class.getName()
-							+ " is required to use MvcRequestMatcher. Please ensure Spring Security & Spring "
+							+ CorsConfigurationSource.class.getName()
+							+ " is required to use <cors>. Please ensure Spring Security & Spring "
 							+ "MVC are configured in a shared ApplicationContext.");
 		}
-		return this.context.getBean(HANDLER_MAPPING_INTROSPECTOR_BEAN_NAME, HandlerMappingIntrospector.class);
+		return this.context.getBean(HANDLER_MAPPING_INTROSPECTOR_BEAN_NAME, CorsConfigurationSource.class);
 	}
 
 	@Nullable
 	@Override
 	public Class<?> getObjectType() {
-		return HandlerMappingIntrospector.class;
+		return CorsConfigurationSource.class;
 	}
 
 	@Override

+ 10 - 5
config/src/main/java/org/springframework/security/config/http/DefaultFilterChainValidator.java

@@ -40,7 +40,9 @@ import org.springframework.security.web.FilterChainProxy;
 import org.springframework.security.web.FilterInvocation;
 import org.springframework.security.web.SecurityFilterChain;
 import org.springframework.security.web.UnreachableFilterChainException;
+import org.springframework.security.web.access.AuthorizationManagerWebInvocationPrivilegeEvaluator;
 import org.springframework.security.web.access.ExceptionTranslationFilter;
+import org.springframework.security.web.access.PathPatternRequestTransformer;
 import org.springframework.security.web.access.intercept.AuthorizationFilter;
 import org.springframework.security.web.access.intercept.FilterInvocationSecurityMetadataSource;
 import org.springframework.security.web.access.intercept.FilterSecurityInterceptor;
@@ -61,6 +63,8 @@ public class DefaultFilterChainValidator implements FilterChainProxy.FilterChain
 
 	private final Log logger = LogFactory.getLog(getClass());
 
+	private final AuthorizationManagerWebInvocationPrivilegeEvaluator.HttpServletRequestTransformer requestTransformer = new PathPatternRequestTransformer();
+
 	@Override
 	public void validate(FilterChainProxy fcp) {
 		for (SecurityFilterChain filterChain : fcp.getFilterChains()) {
@@ -188,7 +192,8 @@ public class DefaultFilterChainValidator implements FilterChainProxy.FilterChain
 		String loginPage = ((LoginUrlAuthenticationEntryPoint) exceptions.getAuthenticationEntryPoint())
 			.getLoginFormUrl();
 		this.logger.info("Checking whether login URL '" + loginPage + "' is accessible with your configuration");
-		FilterInvocation loginRequest = new FilterInvocation(loginPage, "POST");
+		FilterInvocation invocation = new FilterInvocation(loginPage, "POST");
+		HttpServletRequest loginRequest = this.requestTransformer.transform(invocation.getRequest());
 		List<Filter> filters = null;
 		try {
 			filters = fcp.getFilters(loginPage);
@@ -237,7 +242,7 @@ public class DefaultFilterChainValidator implements FilterChainProxy.FilterChain
 		}
 	}
 
-	private boolean checkLoginPageIsPublic(List<Filter> filters, FilterInvocation loginRequest) {
+	private boolean checkLoginPageIsPublic(List<Filter> filters, HttpServletRequest loginRequest) {
 		FilterSecurityInterceptor authorizationInterceptor = getFilter(FilterSecurityInterceptor.class, filters);
 		if (authorizationInterceptor != null) {
 			FilterInvocationSecurityMetadataSource fids = authorizationInterceptor.getSecurityMetadataSource();
@@ -257,7 +262,7 @@ public class DefaultFilterChainValidator implements FilterChainProxy.FilterChain
 			AuthorizationManager<HttpServletRequest> authorizationManager = authorizationFilter
 				.getAuthorizationManager();
 			try {
-				AuthorizationResult result = authorizationManager.authorize(() -> TEST, loginRequest.getHttpRequest());
+				AuthorizationResult result = authorizationManager.authorize(() -> TEST, loginRequest);
 				return result != null && result.isGranted();
 			}
 			catch (Exception ex) {
@@ -267,7 +272,7 @@ public class DefaultFilterChainValidator implements FilterChainProxy.FilterChain
 		return false;
 	}
 
-	private Supplier<Boolean> deriveAnonymousCheck(List<Filter> filters, FilterInvocation loginRequest,
+	private Supplier<Boolean> deriveAnonymousCheck(List<Filter> filters, HttpServletRequest loginRequest,
 			AnonymousAuthenticationToken token) {
 		FilterSecurityInterceptor authorizationInterceptor = getFilter(FilterSecurityInterceptor.class, filters);
 		if (authorizationInterceptor != null) {
@@ -288,7 +293,7 @@ public class DefaultFilterChainValidator implements FilterChainProxy.FilterChain
 			return () -> {
 				AuthorizationManager<HttpServletRequest> authorizationManager = authorizationFilter
 					.getAuthorizationManager();
-				AuthorizationResult result = authorizationManager.authorize(() -> token, loginRequest.getHttpRequest());
+				AuthorizationResult result = authorizationManager.authorize(() -> token, loginRequest);
 				return result != null && result.isGranted();
 			};
 		}

+ 1 - 1
config/src/main/java/org/springframework/security/config/http/FilterInvocationSecurityMetadataSourceParser.java

@@ -159,7 +159,7 @@ public class FilterInvocationSecurityMetadataSourceParser implements BeanDefinit
 			if (!StringUtils.hasText(servletPath)) {
 				servletPath = null;
 			}
-			else if (!MatcherType.mvc.equals(matcherType)) {
+			else if (!MatcherType.path.equals(matcherType)) {
 				parserContext.getReaderContext()
 					.error(ATT_SERVLET_PATH + " is not applicable for request-matcher: '" + matcherType.name() + "'",
 							urlElt);

+ 4 - 16
config/src/main/java/org/springframework/security/config/http/HttpConfigurationBuilder.java

@@ -50,7 +50,6 @@ import org.springframework.security.core.context.SecurityContextHolderStrategy;
 import org.springframework.security.core.session.SessionRegistryImpl;
 import org.springframework.security.web.access.AuthorizationManagerWebInvocationPrivilegeEvaluator;
 import org.springframework.security.web.access.DefaultWebInvocationPrivilegeEvaluator;
-import org.springframework.security.web.access.HandlerMappingIntrospectorRequestTransformer;
 import org.springframework.security.web.access.PathPatternRequestTransformer;
 import org.springframework.security.web.access.channel.ChannelDecisionManagerImpl;
 import org.springframework.security.web.access.channel.ChannelProcessingFilter;
@@ -88,7 +87,6 @@ import org.springframework.util.Assert;
 import org.springframework.util.ClassUtils;
 import org.springframework.util.StringUtils;
 import org.springframework.util.xml.DomUtils;
-import org.springframework.web.servlet.handler.HandlerMappingIntrospector;
 
 /**
  * Stateful class which helps HttpSecurityBDP to create the configuration for the
@@ -100,11 +98,6 @@ import org.springframework.web.servlet.handler.HandlerMappingIntrospector;
  */
 class HttpConfigurationBuilder {
 
-	private static final String HANDLER_MAPPING_INTROSPECTOR = "org.springframework.web.servlet.handler.HandlerMappingIntrospector";
-
-	private static final boolean mvcPresent = ClassUtils.isPresent(HANDLER_MAPPING_INTROSPECTOR,
-			HttpConfigurationBuilder.class.getClassLoader());
-
 	private static final String ATT_CREATE_SESSION = "create-session";
 
 	private static final String ATT_SESSION_FIXATION_PROTECTION = "session-fixation-protection";
@@ -793,10 +786,8 @@ class HttpConfigurationBuilder {
 		BeanDefinitionBuilder wipeBldr = BeanDefinitionBuilder
 			.rootBeanDefinition(AuthorizationManagerWebInvocationPrivilegeEvaluator.class)
 			.addConstructorArgReference(authorizationFilterParser.getAuthorizationManagerRef());
-		if (mvcPresent) {
-			wipeBldr.addPropertyValue("requestTransformer",
-					new RootBeanDefinition(HandlerMappingIntrospectorRequestTransformerFactoryBean.class));
-		}
+		wipeBldr.addPropertyValue("requestTransformer",
+				new RootBeanDefinition(PathPatternRequestTransformerFactoryBean.class));
 		BeanDefinition wipe = wipeBldr.getBeanDefinition();
 		this.pc.registerBeanComponent(
 				new BeanComponentDefinition(wipe, this.pc.getReaderContext().generateBeanName(wipe)));
@@ -966,7 +957,7 @@ class HttpConfigurationBuilder {
 		return BeanDefinitionBuilder.rootBeanDefinition(ObservationRegistryFactory.class).getBeanDefinition();
 	}
 
-	static class HandlerMappingIntrospectorRequestTransformerFactoryBean
+	static class PathPatternRequestTransformerFactoryBean
 			implements FactoryBean<AuthorizationManagerWebInvocationPrivilegeEvaluator.HttpServletRequestTransformer>,
 			ApplicationContextAware {
 
@@ -982,10 +973,7 @@ class HttpConfigurationBuilder {
 			if (requestTransformer != null) {
 				return requestTransformer;
 			}
-			HandlerMappingIntrospector hmi = this.applicationContext.getBeanProvider(HandlerMappingIntrospector.class)
-				.getIfAvailable();
-			return (hmi != null) ? new HandlerMappingIntrospectorRequestTransformer(hmi)
-					: new PathPatternRequestTransformer();
+			return new PathPatternRequestTransformer();
 		}
 
 		@Override

+ 11 - 28
config/src/main/java/org/springframework/security/config/http/MatcherType.java

@@ -22,13 +22,10 @@ import org.springframework.beans.factory.config.BeanDefinition;
 import org.springframework.beans.factory.support.BeanDefinitionBuilder;
 import org.springframework.beans.factory.support.RootBeanDefinition;
 import org.springframework.beans.factory.xml.ParserContext;
-import org.springframework.http.HttpMethod;
-import org.springframework.security.web.servlet.util.matcher.MvcRequestMatcher;
-import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
+import org.springframework.security.web.servlet.util.matcher.PathPatternRequestMatcher;
 import org.springframework.security.web.util.matcher.AnyRequestMatcher;
 import org.springframework.security.web.util.matcher.RegexRequestMatcher;
 import org.springframework.security.web.util.matcher.RequestMatcher;
-import org.springframework.util.ClassUtils;
 import org.springframework.util.StringUtils;
 
 /**
@@ -39,21 +36,12 @@ import org.springframework.util.StringUtils;
  */
 public enum MatcherType {
 
-	ant(AntPathRequestMatcher.class), regex(RegexRequestMatcher.class), ciRegex(RegexRequestMatcher.class),
-	mvc(MvcRequestMatcher.class);
-
-	private static final String HANDLER_MAPPING_INTROSPECTOR = "org.springframework.web.servlet.handler.HandlerMappingIntrospector";
-
-	private static final boolean mvcPresent;
+	path(PathPatternRequestMatcher.class), regex(RegexRequestMatcher.class), ciRegex(RegexRequestMatcher.class);
 
 	private static final String ATT_MATCHER_TYPE = "request-matcher";
 
 	final Class<? extends RequestMatcher> type;
 
-	static {
-		mvcPresent = ClassUtils.isPresent(HANDLER_MAPPING_INTROSPECTOR, MatcherType.class.getClassLoader());
-	}
-
 	MatcherType(Class<? extends RequestMatcher> type) {
 		this.type = type;
 	}
@@ -66,18 +54,17 @@ public enum MatcherType {
 		if (("/**".equals(path) || "**".equals(path)) && method == null) {
 			return new RootBeanDefinition(AnyRequestMatcher.class);
 		}
-		BeanDefinitionBuilder matcherBldr = BeanDefinitionBuilder.rootBeanDefinition(this.type);
-		if (this == mvc) {
-			matcherBldr.addConstructorArgValue(new RootBeanDefinition(HandlerMappingIntrospectorFactoryBean.class));
-		}
-		matcherBldr.addConstructorArgValue(path);
-		if (this == mvc) {
-			matcherBldr.addPropertyValue("method", (StringUtils.hasText(method) ? HttpMethod.valueOf(method) : null));
-			matcherBldr.addPropertyValue("servletPath", servletPath);
+		BeanDefinitionBuilder matcherBldr;
+		if (this == MatcherType.path) {
+			matcherBldr = BeanDefinitionBuilder.rootBeanDefinition(PathPatternRequestMatcherFactoryBean.class);
+			matcherBldr.addConstructorArgValue(path);
+			matcherBldr.addPropertyValue("basePath", servletPath);
 		}
 		else {
-			matcherBldr.addConstructorArgValue(method);
+			matcherBldr = BeanDefinitionBuilder.rootBeanDefinition(this.type);
+			matcherBldr.addConstructorArgValue(path);
 		}
+		matcherBldr.addConstructorArgValue(method);
 		if (this == ciRegex) {
 			matcherBldr.addConstructorArgValue(true);
 		}
@@ -89,14 +76,10 @@ public enum MatcherType {
 			return valueOf(elt.getAttribute(ATT_MATCHER_TYPE));
 		}
 
-		return ant;
+		return path;
 	}
 
 	static MatcherType fromElementOrMvc(Element elt) {
-		String matcherTypeName = elt.getAttribute(ATT_MATCHER_TYPE);
-		if (!StringUtils.hasText(matcherTypeName) && mvcPresent) {
-			return MatcherType.mvc;
-		}
 		return MatcherType.fromElement(elt);
 	}
 

+ 77 - 0
config/src/main/java/org/springframework/security/config/http/PathPatternRequestMatcherFactoryBean.java

@@ -0,0 +1,77 @@
+/*
+ * Copyright 2002-2025 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.security.config.http;
+
+import org.jspecify.annotations.Nullable;
+
+import org.springframework.beans.BeansException;
+import org.springframework.beans.factory.FactoryBean;
+import org.springframework.beans.factory.InitializingBean;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.ApplicationContextAware;
+import org.springframework.http.HttpMethod;
+import org.springframework.security.web.servlet.util.matcher.PathPatternRequestMatcher;
+import org.springframework.util.StringUtils;
+
+public final class PathPatternRequestMatcherFactoryBean
+		implements FactoryBean<PathPatternRequestMatcher>, ApplicationContextAware, InitializingBean {
+
+	private final String pattern;
+
+	private String basePath;
+
+	private HttpMethod method;
+
+	private PathPatternRequestMatcher.Builder builder;
+
+	PathPatternRequestMatcherFactoryBean(String pattern) {
+		this.pattern = pattern;
+	}
+
+	PathPatternRequestMatcherFactoryBean(String pattern, String method) {
+		this.pattern = pattern;
+		this.method = StringUtils.hasText(method) ? HttpMethod.valueOf(method) : null;
+	}
+
+	@Override
+	public @Nullable PathPatternRequestMatcher getObject() throws Exception {
+		return this.builder.matcher(this.method, this.pattern);
+	}
+
+	@Override
+	public @Nullable Class<?> getObjectType() {
+		return PathPatternRequestMatcher.class;
+	}
+
+	public void setBasePath(String basePath) {
+		this.basePath = basePath;
+	}
+
+	@Override
+	public void setApplicationContext(ApplicationContext context) throws BeansException {
+		this.builder = context.getBeanProvider(PathPatternRequestMatcher.Builder.class)
+			.getIfUnique(PathPatternRequestMatcher::withDefaults);
+	}
+
+	@Override
+	public void afterPropertiesSet() throws Exception {
+		if (this.basePath != null) {
+			this.builder.basePath(this.basePath);
+		}
+	}
+
+}

+ 3 - 6
config/src/main/java/org/springframework/security/config/http/RequestMatcherFactoryBean.java

@@ -22,7 +22,6 @@ import org.springframework.context.ApplicationContext;
 import org.springframework.context.ApplicationContextAware;
 import org.springframework.http.HttpMethod;
 import org.springframework.security.web.servlet.util.matcher.PathPatternRequestMatcher;
-import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
 import org.springframework.security.web.util.matcher.RequestMatcher;
 
 @Deprecated
@@ -45,10 +44,7 @@ public final class RequestMatcherFactoryBean implements FactoryBean<RequestMatch
 
 	@Override
 	public RequestMatcher getObject() throws Exception {
-		if (this.builder != null) {
-			return this.builder.matcher(this.method, this.path);
-		}
-		return new AntPathRequestMatcher(this.path, (this.method != null) ? this.method.name() : null);
+		return this.builder.matcher(this.method, this.path);
 	}
 
 	@Override
@@ -58,7 +54,8 @@ public final class RequestMatcherFactoryBean implements FactoryBean<RequestMatch
 
 	@Override
 	public void setApplicationContext(ApplicationContext context) throws BeansException {
-		this.builder = context.getBeanProvider(PathPatternRequestMatcher.Builder.class).getIfUnique();
+		this.builder = context.getBeanProvider(PathPatternRequestMatcher.Builder.class)
+			.getIfUnique(PathPatternRequestMatcher::withDefaults);
 	}
 
 }

+ 1 - 1
config/src/main/kotlin/org/springframework/security/config/annotation/web/AbstractRequestMatcherDsl.kt

@@ -58,6 +58,6 @@ abstract class AbstractRequestMatcherDsl {
     protected abstract class AuthorizationManagerRule(open val rule: AuthorizationManager<RequestAuthorizationContext>)
 
     protected enum class PatternType {
-        ANT, MVC
+        PATH;
     }
 }

+ 8 - 19
config/src/main/kotlin/org/springframework/security/config/annotation/web/AuthorizeHttpRequestsDsl.kt

@@ -31,11 +31,9 @@ import org.springframework.security.core.Authentication
 import org.springframework.security.web.access.IpAddressAuthorizationManager
 import org.springframework.security.web.access.intercept.AuthorizationFilter
 import org.springframework.security.web.access.intercept.RequestAuthorizationContext
-import org.springframework.security.web.servlet.util.matcher.MvcRequestMatcher
+import org.springframework.security.web.servlet.util.matcher.PathPatternRequestMatcher
 import org.springframework.security.web.util.matcher.AnyRequestMatcher
 import org.springframework.security.web.util.matcher.RequestMatcher
-import org.springframework.util.ClassUtils
-import org.springframework.web.servlet.handler.HandlerMappingIntrospector
 import java.util.function.Supplier
 
 /**
@@ -69,12 +67,7 @@ class AuthorizeHttpRequestsDsl : AbstractRequestMatcherDsl {
     private val rolePrefix: String
     private val roleHierarchy: RoleHierarchy
 
-    private val HANDLER_MAPPING_INTROSPECTOR_BEAN_NAME = "mvcHandlerMappingIntrospector"
-    private val HANDLER_MAPPING_INTROSPECTOR = "org.springframework.web.servlet.handler.HandlerMappingIntrospector"
-    private val MVC_PRESENT = ClassUtils.isPresent(
-        HANDLER_MAPPING_INTROSPECTOR,
-        AuthorizeHttpRequestsDsl::class.java.classLoader)
-    private val PATTERN_TYPE = if (MVC_PRESENT) PatternType.MVC else PatternType.ANT
+    private val PATTERN_TYPE = PatternType.PATH
 
     /**
      * Adds a request authorization rule.
@@ -288,17 +281,13 @@ class AuthorizeHttpRequestsDsl : AbstractRequestMatcherDsl {
                 when (rule) {
                     is MatcherAuthorizationManagerRule -> requests.requestMatchers(rule.matcher).access(rule.rule)
                     is PatternAuthorizationManagerRule -> {
-                        when (rule.patternType) {
-                            PatternType.ANT -> requests.requestMatchers(rule.httpMethod, rule.pattern).access(rule.rule)
-                            PatternType.MVC -> {
-                                val introspector = requests.applicationContext.getBean(HANDLER_MAPPING_INTROSPECTOR_BEAN_NAME, HandlerMappingIntrospector::class.java)
-                                val mvcMatcher = MvcRequestMatcher.Builder(introspector)
-                                    .servletPath(rule.servletPath)
-                                    .pattern(rule.pattern)
-                                mvcMatcher.setMethod(rule.httpMethod)
-                                requests.requestMatchers(mvcMatcher).access(rule.rule)
-                            }
+                        var builder = requests.applicationContext.getBeanProvider(
+                            PathPatternRequestMatcher.Builder::class.java)
+                            .getIfUnique(PathPatternRequestMatcher::withDefaults)
+                        if (rule.servletPath != null) {
+                            builder = builder.basePath(rule.servletPath)
                         }
+                        requests.requestMatchers(builder.matcher(rule.httpMethod, rule.pattern)).access(rule.rule)
                     }
                 }
             }

+ 8 - 20
config/src/main/kotlin/org/springframework/security/config/annotation/web/AuthorizeRequestsDsl.kt

@@ -19,11 +19,9 @@ package org.springframework.security.config.annotation.web
 import org.springframework.http.HttpMethod
 import org.springframework.security.config.annotation.web.builders.HttpSecurity
 import org.springframework.security.config.annotation.web.configurers.ExpressionUrlAuthorizationConfigurer
-import org.springframework.security.web.servlet.util.matcher.MvcRequestMatcher
+import org.springframework.security.web.servlet.util.matcher.PathPatternRequestMatcher
 import org.springframework.security.web.util.matcher.AnyRequestMatcher
 import org.springframework.security.web.util.matcher.RequestMatcher
-import org.springframework.util.ClassUtils
-import org.springframework.web.servlet.handler.HandlerMappingIntrospector
 
 /**
  * A Kotlin DSL to configure [HttpSecurity] request authorization using idiomatic Kotlin code.
@@ -33,13 +31,7 @@ import org.springframework.web.servlet.handler.HandlerMappingIntrospector
  */
 class AuthorizeRequestsDsl : AbstractRequestMatcherDsl() {
     private val authorizationRules = mutableListOf<AuthorizationRule>()
-
-    private val HANDLER_MAPPING_INTROSPECTOR_BEAN_NAME = "mvcHandlerMappingIntrospector"
-    private val HANDLER_MAPPING_INTROSPECTOR = "org.springframework.web.servlet.handler.HandlerMappingIntrospector"
-    private val MVC_PRESENT = ClassUtils.isPresent(
-            HANDLER_MAPPING_INTROSPECTOR,
-            AuthorizeRequestsDsl::class.java.classLoader)
-    private val PATTERN_TYPE = if (MVC_PRESENT) PatternType.MVC else PatternType.ANT
+    private val PATTERN_TYPE = PatternType.PATH;
 
     /**
      * Adds a request authorization rule.
@@ -226,17 +218,13 @@ class AuthorizeRequestsDsl : AbstractRequestMatcherDsl() {
                 when (rule) {
                     is MatcherAuthorizationRule -> requests.requestMatchers(rule.matcher).access(rule.rule)
                     is PatternAuthorizationRule -> {
-                        when (rule.patternType) {
-                            PatternType.ANT -> requests.requestMatchers(rule.httpMethod, rule.pattern).access(rule.rule)
-                            PatternType.MVC -> {
-                                val introspector = requests.applicationContext.getBean(HANDLER_MAPPING_INTROSPECTOR_BEAN_NAME, HandlerMappingIntrospector::class.java)
-                                val mvcMatcher = MvcRequestMatcher.Builder(introspector)
-                                    .servletPath(rule.servletPath)
-                                    .pattern(rule.pattern)
-                                mvcMatcher.setMethod(rule.httpMethod)
-                                requests.requestMatchers(mvcMatcher).access(rule.rule)
-                            }
+                        var builder = requests.applicationContext.getBeanProvider(
+                            PathPatternRequestMatcher.Builder::class.java)
+                                .getIfUnique(PathPatternRequestMatcher::withDefaults);
+                        if (rule.servletPath != null) {
+                            builder = builder.basePath(rule.servletPath)
                         }
+                        requests.requestMatchers(builder.matcher(rule.httpMethod, rule.pattern)).access(rule.rule)
                     }
                 }
             }

+ 0 - 1
config/src/main/kotlin/org/springframework/security/config/annotation/web/HttpSecurityDsl.kt

@@ -73,7 +73,6 @@ operator fun HttpSecurity.invoke(httpConfiguration: HttpSecurityDsl.() -> Unit)
  */
 @SecurityMarker
 class HttpSecurityDsl(private val http: HttpSecurity, private val init: HttpSecurityDsl.() -> Unit) {
-    private val HANDLER_MAPPING_INTROSPECTOR = "org.springframework.web.servlet.handler.HandlerMappingIntrospector"
 
     var authenticationManager: AuthenticationManager? = null
     val context: ApplicationContext = http.getSharedObject(ApplicationContext::class.java)

+ 8 - 19
config/src/main/kotlin/org/springframework/security/config/annotation/web/RequiresChannelDsl.kt

@@ -20,11 +20,9 @@ import org.springframework.security.config.annotation.web.builders.HttpSecurity
 import org.springframework.security.config.annotation.web.configurers.ChannelSecurityConfigurer
 import org.springframework.security.web.access.channel.ChannelDecisionManagerImpl
 import org.springframework.security.web.access.channel.ChannelProcessor
-import org.springframework.security.web.servlet.util.matcher.MvcRequestMatcher
+import org.springframework.security.web.servlet.util.matcher.PathPatternRequestMatcher
 import org.springframework.security.web.util.matcher.AnyRequestMatcher
 import org.springframework.security.web.util.matcher.RequestMatcher
-import org.springframework.util.ClassUtils
-import org.springframework.web.servlet.handler.HandlerMappingIntrospector
 
 /**
  * A Kotlin DSL to configure [HttpSecurity] channel security using idiomatic
@@ -38,12 +36,7 @@ import org.springframework.web.servlet.handler.HandlerMappingIntrospector
 class RequiresChannelDsl : AbstractRequestMatcherDsl() {
     private val channelSecurityRules = mutableListOf<AuthorizationRule>()
 
-    private val HANDLER_MAPPING_INTROSPECTOR_BEAN_NAME = "mvcHandlerMappingIntrospector"
-    private val HANDLER_MAPPING_INTROSPECTOR = "org.springframework.web.servlet.handler.HandlerMappingIntrospector"
-    private val MVC_PRESENT = ClassUtils.isPresent(
-            HANDLER_MAPPING_INTROSPECTOR,
-            RequiresChannelDsl::class.java.classLoader)
-    private val PATTERN_TYPE = if (MVC_PRESENT) PatternType.MVC else PatternType.ANT
+    private val PATTERN_TYPE = PatternType.PATH
 
     var channelProcessors: List<ChannelProcessor>? = null
 
@@ -121,17 +114,13 @@ class RequiresChannelDsl : AbstractRequestMatcherDsl() {
                 when (rule) {
                     is MatcherAuthorizationRule -> channelSecurity.requestMatchers(rule.matcher).requires(rule.rule)
                     is PatternAuthorizationRule -> {
-                        when (rule.patternType) {
-                            PatternType.ANT -> channelSecurity.requestMatchers(rule.pattern).requires(rule.rule)
-                            PatternType.MVC -> {
-                                val introspector = channelSecurity.applicationContext.getBean(HANDLER_MAPPING_INTROSPECTOR_BEAN_NAME, HandlerMappingIntrospector::class.java)
-                                val mvcMatcher = MvcRequestMatcher.Builder(introspector)
-                                    .servletPath(rule.servletPath)
-                                    .pattern(rule.pattern)
-                                mvcMatcher.setMethod(rule.httpMethod)
-                                channelSecurity.requestMatchers(mvcMatcher).requires(rule.rule)
-                            }
+                        var builder = channelSecurity.applicationContext.getBeanProvider(
+                            PathPatternRequestMatcher.Builder::class.java)
+                            .getIfUnique(PathPatternRequestMatcher::withDefaults);
+                        if (rule.servletPath != null) {
+                            builder = builder.basePath(rule.servletPath)
                         }
+                        channelSecurity.requestMatchers(builder.matcher(rule.httpMethod, rule.pattern)).requires(rule.rule)
                     }
                 }
             }

+ 1 - 1
config/src/main/resources/org/springframework/security/config/spring-security-7.0.rnc

@@ -1183,7 +1183,7 @@ hsts-options.attlist &=
 	attribute preload {xsd:boolean}?
 
 cors =
-## Element for configuration of CorsFilter. If no CorsFilter or CorsConfigurationSource is specified a HandlerMappingIntrospector is used as the CorsConfigurationSource
+## Element for configuration of CorsFilter. A CorsConfigurationSource must be specified
 element cors { cors-options.attlist }
 cors-options.attlist &=
 	ref?

+ 1 - 2
config/src/main/resources/org/springframework/security/config/spring-security-7.0.xsd

@@ -3317,8 +3317,7 @@
   </xs:attributeGroup>
   <xs:element name="cors">
       <xs:annotation>
-         <xs:documentation>Element for configuration of CorsFilter. If no CorsFilter or CorsConfigurationSource is
-                specified a HandlerMappingIntrospector is used as the CorsConfigurationSource
+         <xs:documentation>Element for configuration of CorsFilter. A CorsConfigurationSource must be specified
                 </xs:documentation>
       </xs:annotation>
       <xs:complexType>

+ 2 - 1
config/src/test/java/org/springframework/security/config/FilterChainProxyConfigTests.java

@@ -39,6 +39,7 @@ import org.springframework.security.web.servletapi.SecurityContextHolderAwareReq
 import org.springframework.security.web.util.matcher.AnyRequestMatcher;
 import org.springframework.security.web.util.matcher.RequestMatcher;
 import org.springframework.test.util.ReflectionTestUtils;
+import org.springframework.web.util.pattern.PathPattern;
 
 import static org.assertj.core.api.Assertions.assertThat;
 import static org.mockito.ArgumentMatchers.any;
@@ -120,7 +121,7 @@ public class FilterChainProxyConfigTests {
 
 	private String getPattern(SecurityFilterChain chain) {
 		RequestMatcher requestMatcher = ((DefaultSecurityFilterChain) chain).getRequestMatcher();
-		return (String) ReflectionTestUtils.getField(requestMatcher, "pattern");
+		return ((PathPattern) ReflectionTestUtils.getField(requestMatcher, "pattern")).getPatternString();
 	}
 
 	private void checkPathAndFilterOrder(FilterChainProxy filterChainProxy) {

+ 2 - 2
config/src/test/java/org/springframework/security/config/annotation/issue50/SecurityConfig.java

@@ -32,7 +32,7 @@ import org.springframework.security.core.Authentication;
 import org.springframework.security.core.AuthenticationException;
 import org.springframework.security.core.userdetails.UsernameNotFoundException;
 import org.springframework.security.web.SecurityFilterChain;
-import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
+import org.springframework.security.web.servlet.util.matcher.PathPatternRequestMatcher;
 import org.springframework.util.Assert;
 
 /**
@@ -52,7 +52,7 @@ public class SecurityConfig {
 		// @formatter:off
 		http
 			.authorizeRequests((requests) -> requests
-				.requestMatchers(new AntPathRequestMatcher("/*")).permitAll())
+				.requestMatchers(PathPatternRequestMatcher.withDefaults().matcher("/*")).permitAll())
 			.authenticationProvider(authenticationProvider());
 		// @formatter:on
 		return http.build();

+ 11 - 7
config/src/test/java/org/springframework/security/config/annotation/web/AbstractRequestMatcherRegistryAnyMatcherTests.java

@@ -24,12 +24,11 @@ import org.springframework.context.annotation.Configuration;
 import org.springframework.mock.web.MockServletContext;
 import org.springframework.security.config.annotation.web.builders.HttpSecurity;
 import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
+import org.springframework.security.config.web.PathPatternRequestMatcherBuilderFactoryBean;
 import org.springframework.security.web.SecurityFilterChain;
-import org.springframework.security.web.servlet.util.matcher.MvcRequestMatcher;
-import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
+import org.springframework.security.web.servlet.util.matcher.PathPatternRequestMatcher;
 import org.springframework.security.web.util.matcher.RegexRequestMatcher;
 import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
-import org.springframework.web.servlet.handler.HandlerMappingIntrospector;
 
 import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
 
@@ -88,7 +87,7 @@ public class AbstractRequestMatcherRegistryAnyMatcherTests {
 			http
 				.authorizeRequests((requests) -> requests
 					.anyRequest().authenticated()
-					.requestMatchers(new AntPathRequestMatcher("/demo/**")).permitAll());
+					.requestMatchers(PathPatternRequestMatcher.withDefaults().matcher("/demo/**")).permitAll());
 			return http.build();
 			// @formatter:on
 		}
@@ -100,12 +99,17 @@ public class AbstractRequestMatcherRegistryAnyMatcherTests {
 	static class MvcMatchersAfterAnyRequestConfig {
 
 		@Bean
-		SecurityFilterChain filterChain(HttpSecurity http, HandlerMappingIntrospector introspector) throws Exception {
+		PathPatternRequestMatcherBuilderFactoryBean pathPattern() {
+			return new PathPatternRequestMatcherBuilderFactoryBean();
+		}
+
+		@Bean
+		SecurityFilterChain filterChain(HttpSecurity http, PathPatternRequestMatcher.Builder builder) throws Exception {
 			// @formatter:off
 			http
 				.authorizeRequests((requests) -> requests
 					.anyRequest().authenticated()
-					.requestMatchers(new MvcRequestMatcher(introspector, "/demo/**")).permitAll());
+					.requestMatchers(builder.matcher("/demo/**")).permitAll());
 			return http.build();
 			// @formatter:on
 		}
@@ -156,7 +160,7 @@ public class AbstractRequestMatcherRegistryAnyMatcherTests {
 			http
 				.authorizeRequests((requests) -> requests
 					.anyRequest().authenticated()
-					.requestMatchers(new AntPathRequestMatcher("/**")).permitAll());
+					.requestMatchers(PathPatternRequestMatcher.withDefaults().matcher("/**")).permitAll());
 			return http.build();
 			// @formatter:on
 		}

+ 10 - 6
config/src/test/java/org/springframework/security/config/annotation/web/AbstractRequestMatcherRegistryNoMvcTests.java

@@ -21,9 +21,10 @@ import java.util.List;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
 
+import org.springframework.context.support.GenericApplicationContext;
 import org.springframework.http.HttpMethod;
 import org.springframework.security.test.support.ClassPathExclusions;
-import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
+import org.springframework.security.web.servlet.util.matcher.PathPatternRequestMatcher;
 import org.springframework.security.web.util.matcher.RequestMatcher;
 
 import static org.assertj.core.api.Assertions.assertThat;
@@ -41,22 +42,25 @@ public class AbstractRequestMatcherRegistryNoMvcTests {
 	@BeforeEach
 	public void setUp() {
 		this.matcherRegistry = new TestRequestMatcherRegistry();
+		GenericApplicationContext context = new GenericApplicationContext();
+		context.refresh();
+		this.matcherRegistry.setApplicationContext(context);
 	}
 
 	@Test
-	public void requestMatchersWhenPatternAndMvcNotPresentThenReturnAntPathRequestMatcherType() {
+	public void requestMatchersWhenPatternAndMvcNotPresentThenReturnPathPatternRequestMatcherType() {
 		List<RequestMatcher> requestMatchers = this.matcherRegistry.requestMatchers("/path");
 		assertThat(requestMatchers).isNotEmpty();
 		assertThat(requestMatchers).hasSize(1);
-		assertThat(requestMatchers.get(0)).isExactlyInstanceOf(AntPathRequestMatcher.class);
+		assertThat(requestMatchers.get(0)).isExactlyInstanceOf(PathPatternRequestMatcher.class);
 	}
 
 	@Test
-	public void requestMatchersWhenHttpMethodAndPatternAndMvcNotPresentThenReturnAntPathRequestMatcherType() {
+	public void requestMatchersWhenHttpMethodAndPatternAndMvcNotPresentThenReturnPathPatternRequestMatcherType() {
 		List<RequestMatcher> requestMatchers = this.matcherRegistry.requestMatchers(HttpMethod.GET, "/path");
 		assertThat(requestMatchers).isNotEmpty();
 		assertThat(requestMatchers).hasSize(1);
-		assertThat(requestMatchers.get(0)).isExactlyInstanceOf(AntPathRequestMatcher.class);
+		assertThat(requestMatchers.get(0)).isExactlyInstanceOf(PathPatternRequestMatcher.class);
 	}
 
 	@Test
@@ -64,7 +68,7 @@ public class AbstractRequestMatcherRegistryNoMvcTests {
 		List<RequestMatcher> requestMatchers = this.matcherRegistry.requestMatchers(HttpMethod.GET);
 		assertThat(requestMatchers).isNotEmpty();
 		assertThat(requestMatchers).hasSize(1);
-		assertThat(requestMatchers.get(0)).isExactlyInstanceOf(AntPathRequestMatcher.class);
+		assertThat(requestMatchers.get(0)).isExactlyInstanceOf(PathPatternRequestMatcher.class);
 	}
 
 	private static class TestRequestMatcherRegistry extends AbstractRequestMatcherRegistry<List<RequestMatcher>> {

+ 24 - 252
config/src/test/java/org/springframework/security/config/annotation/web/AbstractRequestMatcherRegistryTests.java

@@ -16,47 +16,30 @@
 
 package org.springframework.security.config.annotation.web;
 
-import java.util.ArrayList;
 import java.util.List;
+import java.util.stream.Stream;
 
 import jakarta.servlet.DispatcherType;
-import jakarta.servlet.Servlet;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
 
-import org.springframework.beans.factory.NoSuchBeanDefinitionException;
 import org.springframework.beans.factory.ObjectProvider;
-import org.springframework.context.ApplicationContext;
 import org.springframework.context.annotation.Configuration;
 import org.springframework.core.ResolvableType;
 import org.springframework.http.HttpMethod;
-import org.springframework.mock.web.MockHttpServletRequest;
 import org.springframework.security.config.ObjectPostProcessor;
-import org.springframework.security.config.annotation.web.AbstractRequestMatcherRegistry.DispatcherServletDelegatingRequestMatcher;
 import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
-import org.springframework.security.config.test.SpringTestContext;
-import org.springframework.security.web.servlet.MockServletContext;
-import org.springframework.security.web.servlet.TestMockHttpServletMappings;
-import org.springframework.security.web.servlet.util.matcher.MvcRequestMatcher;
-import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
+import org.springframework.security.web.servlet.util.matcher.PathPatternRequestMatcher;
 import org.springframework.security.web.util.matcher.DispatcherTypeRequestMatcher;
 import org.springframework.security.web.util.matcher.RegexRequestMatcher;
 import org.springframework.security.web.util.matcher.RequestMatcher;
-import org.springframework.test.web.servlet.MockMvc;
-import org.springframework.test.web.servlet.setup.MockMvcBuilders;
 import org.springframework.web.context.WebApplicationContext;
-import org.springframework.web.servlet.DispatcherServlet;
 import org.springframework.web.servlet.config.annotation.EnableWebMvc;
 
 import static org.assertj.core.api.Assertions.assertThat;
-import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
-import static org.assertj.core.api.InstanceOfAssertFactories.type;
+import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.BDDMockito.given;
 import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyNoInteractions;
-import static org.mockito.Mockito.verifyNoMoreInteractions;
-import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
 
 /**
  * Tests for {@link AbstractRequestMatcherRegistry}.
@@ -86,9 +69,13 @@ public class AbstractRequestMatcherRegistryTests {
 		ObjectProvider<ObjectPostProcessor<Object>> given = this.context.getBeanProvider(type);
 		given(given).willReturn(postProcessors);
 		given(postProcessors.getObject()).willReturn(NO_OP_OBJECT_POST_PROCESSOR);
-		given(this.context.getServletContext()).willReturn(MockServletContext.mvc());
+		given(this.context.getBeanProvider(any(Class.class))).willReturn(new ObjectProvider<>() {
+			@Override
+			public Stream<Object> stream() {
+				return Stream.of();
+			}
+		});
 		this.matcherRegistry.setApplicationContext(this.context);
-		mockMvcIntrospector(true);
 	}
 
 	@Test
@@ -110,24 +97,25 @@ public class AbstractRequestMatcherRegistryTests {
 	}
 
 	@Test
-	public void antMatchersWhenHttpMethodAndPatternParamsThenReturnAntPathRequestMatcherType() {
+	public void pathPatternWhenHttpMethodAndPatternParamsThenReturnPathPatternRequestMatcherType() {
 		List<RequestMatcher> requestMatchers = this.matcherRegistry
-			.requestMatchers(new AntPathRequestMatcher("/a.*", HttpMethod.GET.name()));
+			.requestMatchers(PathPatternRequestMatcher.withDefaults().matcher(HttpMethod.GET, "/a.*"));
 		assertThat(requestMatchers).isNotEmpty();
 		assertThat(requestMatchers).hasSize(1);
-		assertThat(requestMatchers.get(0)).isExactlyInstanceOf(AntPathRequestMatcher.class);
+		assertThat(requestMatchers.get(0)).isExactlyInstanceOf(PathPatternRequestMatcher.class);
 	}
 
 	@Test
-	public void antMatchersWhenPatternParamThenReturnAntPathRequestMatcherType() {
-		List<RequestMatcher> requestMatchers = this.matcherRegistry.requestMatchers(new AntPathRequestMatcher("/a.*"));
+	public void pathPatternWhenPatternParamThenReturnPathPatternRequestMatcherType() {
+		List<RequestMatcher> requestMatchers = this.matcherRegistry
+			.requestMatchers(PathPatternRequestMatcher.withDefaults().matcher("/a.*"));
 		assertThat(requestMatchers).isNotEmpty();
 		assertThat(requestMatchers).hasSize(1);
-		assertThat(requestMatchers.get(0)).isExactlyInstanceOf(AntPathRequestMatcher.class);
+		assertThat(requestMatchers.get(0)).isExactlyInstanceOf(PathPatternRequestMatcher.class);
 	}
 
 	@Test
-	public void dispatcherTypeMatchersWhenHttpMethodAndPatternParamsThenReturnAntPathRequestMatcherType() {
+	public void dispatcherTypeMatchersWhenHttpMethodAndPatternParamsThenReturnPathPatternRequestMatcherType() {
 		List<RequestMatcher> requestMatchers = this.matcherRegistry.dispatcherTypeMatchers(HttpMethod.GET,
 				DispatcherType.ASYNC);
 		assertThat(requestMatchers).isNotEmpty();
@@ -136,7 +124,7 @@ public class AbstractRequestMatcherRegistryTests {
 	}
 
 	@Test
-	public void dispatcherMatchersWhenPatternParamThenReturnAntPathRequestMatcherType() {
+	public void dispatcherMatchersWhenPatternParamThenReturnPathPatternRequestMatcherType() {
 		List<RequestMatcher> requestMatchers = this.matcherRegistry.dispatcherTypeMatchers(DispatcherType.INCLUDE);
 		assertThat(requestMatchers).isNotEmpty();
 		assertThat(requestMatchers).hasSize(1);
@@ -144,252 +132,36 @@ public class AbstractRequestMatcherRegistryTests {
 	}
 
 	@Test
-	public void requestMatchersWhenPatternAndMvcPresentThenReturnMvcRequestMatcherType() {
+	public void requestMatchersWhenPatternAndMvcPresentThenReturnPathPatternRequestMatcherType() {
 		List<RequestMatcher> requestMatchers = this.matcherRegistry.requestMatchers("/path");
 		assertThat(requestMatchers).isNotEmpty();
 		assertThat(requestMatchers).hasSize(1);
-		assertThat(requestMatchers.get(0)).isExactlyInstanceOf(MvcRequestMatcher.class);
+		assertThat(requestMatchers.get(0)).isExactlyInstanceOf(PathPatternRequestMatcher.class);
 	}
 
 	@Test
-	public void requestMatchersWhenHttpMethodAndPatternAndMvcPresentThenReturnMvcRequestMatcherType() {
+	public void requestMatchersWhenHttpMethodAndPatternAndMvcPresentThenReturnPathPatternRequestMatcherType() {
 		List<RequestMatcher> requestMatchers = this.matcherRegistry.requestMatchers(HttpMethod.GET, "/path");
 		assertThat(requestMatchers).isNotEmpty();
 		assertThat(requestMatchers).hasSize(1);
-		assertThat(requestMatchers.get(0)).isExactlyInstanceOf(MvcRequestMatcher.class);
+		assertThat(requestMatchers.get(0)).isExactlyInstanceOf(PathPatternRequestMatcher.class);
 	}
 
 	@Test
-	public void requestMatchersWhenHttpMethodAndMvcPresentThenReturnMvcRequestMatcherType() {
+	public void requestMatchersWhenHttpMethodAndMvcPresentThenReturnPathPatternRequestMatcherType() {
 		List<RequestMatcher> requestMatchers = this.matcherRegistry.requestMatchers(HttpMethod.GET);
 		assertThat(requestMatchers).isNotEmpty();
 		assertThat(requestMatchers).hasSize(1);
-		assertThat(requestMatchers.get(0)).isExactlyInstanceOf(MvcRequestMatcher.class);
-	}
-
-	@Test
-	public void requestMatchersWhenMvcPresentInClassPathAndMvcIntrospectorBeanNotAvailableThenException() {
-		mockMvcIntrospector(false);
-		assertThatExceptionOfType(NoSuchBeanDefinitionException.class)
-			.isThrownBy(() -> this.matcherRegistry.requestMatchers("/path"))
-			.withMessageContaining(
-					"Please ensure Spring Security & Spring MVC are configured in a shared ApplicationContext");
-	}
-
-	@Test
-	public void requestMatchersWhenNoDispatcherServletThenAntPathRequestMatcherType() {
-		mockMvcIntrospector(true);
-		MockServletContext servletContext = new MockServletContext();
-		given(this.context.getServletContext()).willReturn(servletContext);
-		MockHttpServletRequest request = new MockHttpServletRequest();
-		List<RequestMatcher> requestMatchers = this.matcherRegistry.requestMatchers("/**");
-		assertThat(requestMatchers).isNotEmpty();
-		assertThat(requestMatchers).hasSize(1);
-		assertThat(requestMatchers.get(0)).asInstanceOf(type(DispatcherServletDelegatingRequestMatcher.class))
-			.extracting((matcher) -> matcher.requestMatcher(request))
-			.isInstanceOf(AntPathRequestMatcher.class);
-		servletContext.addServlet("servletOne", Servlet.class).addMapping("/one");
-		servletContext.addServlet("servletTwo", Servlet.class).addMapping("/two");
-		requestMatchers = this.matcherRegistry.requestMatchers("/**");
-		assertThat(requestMatchers).isNotEmpty();
-		assertThat(requestMatchers).hasSize(1);
-		assertThat(requestMatchers.get(0)).asInstanceOf(type(DispatcherServletDelegatingRequestMatcher.class))
-			.extracting((matcher) -> matcher.requestMatcher(request))
-			.isInstanceOf(AntPathRequestMatcher.class);
-		servletContext.addServlet("servletOne", Servlet.class);
-		servletContext.addServlet("servletTwo", Servlet.class);
-		requestMatchers = this.matcherRegistry.requestMatchers("/**");
-		assertThat(requestMatchers).isNotEmpty();
-		assertThat(requestMatchers).hasSize(1);
-		assertThat(requestMatchers.get(0)).asInstanceOf(type(DispatcherServletDelegatingRequestMatcher.class))
-			.extracting((matcher) -> matcher.requestMatcher(request))
-			.isInstanceOf(AntPathRequestMatcher.class);
-	}
-
-	// gh-14418
-	@Test
-	public void requestMatchersWhenNoDispatcherServletMockMvcThenMvcRequestMatcherType() throws Exception {
-		MockServletContext servletContext = new MockServletContext();
-		try (SpringTestContext spring = new SpringTestContext(this)) {
-			spring.register(MockMvcConfiguration.class)
-				.postProcessor((context) -> context.setServletContext(servletContext))
-				.autowire();
-			this.matcherRegistry.setApplicationContext(spring.getContext());
-			MockMvc mvc = MockMvcBuilders.webAppContextSetup(spring.getContext()).build();
-			MockHttpServletRequest request = mvc.perform(get("/")).andReturn().getRequest();
-			List<RequestMatcher> requestMatchers = this.matcherRegistry.requestMatchers("/**");
-			assertThat(requestMatchers).isNotEmpty();
-			assertThat(requestMatchers).hasSize(1);
-			assertThat(requestMatchers.get(0)).asInstanceOf(type(DispatcherServletDelegatingRequestMatcher.class))
-				.extracting((matcher) -> matcher.requestMatcher(request))
-				.isInstanceOf(MvcRequestMatcher.class);
-			servletContext.addServlet("servletOne", Servlet.class).addMapping("/one");
-			servletContext.addServlet("servletTwo", Servlet.class).addMapping("/two");
-			requestMatchers = this.matcherRegistry.requestMatchers("/**");
-			assertThat(requestMatchers).isNotEmpty();
-			assertThat(requestMatchers).hasSize(1);
-			assertThat(requestMatchers.get(0)).asInstanceOf(type(DispatcherServletDelegatingRequestMatcher.class))
-				.extracting((matcher) -> matcher.requestMatcher(request))
-				.isInstanceOf(MvcRequestMatcher.class);
-			servletContext.addServlet("servletOne", Servlet.class);
-			servletContext.addServlet("servletTwo", Servlet.class);
-			requestMatchers = this.matcherRegistry.requestMatchers("/**");
-			assertThat(requestMatchers).isNotEmpty();
-			assertThat(requestMatchers).hasSize(1);
-			assertThat(requestMatchers.get(0)).asInstanceOf(type(DispatcherServletDelegatingRequestMatcher.class))
-				.extracting((matcher) -> matcher.requestMatcher(request))
-				.isInstanceOf(MvcRequestMatcher.class);
-		}
-	}
-
-	@Test
-	public void requestMatchersWhenAmbiguousServletsThenException() {
-		mockMvcIntrospector(true);
-		MockServletContext servletContext = new MockServletContext();
-		given(this.context.getServletContext()).willReturn(servletContext);
-		servletContext.addServlet("dispatcherServlet", DispatcherServlet.class).addMapping("/");
-		servletContext.addServlet("servletTwo", DispatcherServlet.class).addMapping("/servlet/*");
-		assertThatExceptionOfType(IllegalArgumentException.class)
-			.isThrownBy(() -> this.matcherRegistry.requestMatchers("/**"));
-	}
-
-	@Test
-	public void requestMatchersWhenMultipleDispatcherServletMappingsThenException() {
-		mockMvcIntrospector(true);
-		MockServletContext servletContext = new MockServletContext();
-		given(this.context.getServletContext()).willReturn(servletContext);
-		servletContext.addServlet("dispatcherServlet", DispatcherServlet.class).addMapping("/", "/mvc/*");
-		assertThatExceptionOfType(IllegalArgumentException.class)
-			.isThrownBy(() -> this.matcherRegistry.requestMatchers("/**"));
-	}
-
-	@Test
-	public void requestMatchersWhenPathDispatcherServletAndOtherServletsThenException() {
-		mockMvcIntrospector(true);
-		MockServletContext servletContext = new MockServletContext();
-		given(this.context.getServletContext()).willReturn(servletContext);
-		servletContext.addServlet("dispatcherServlet", DispatcherServlet.class).addMapping("/mvc/*");
-		servletContext.addServlet("default", Servlet.class).addMapping("/");
-		assertThatExceptionOfType(IllegalArgumentException.class)
-			.isThrownBy(() -> this.matcherRegistry.requestMatchers("/**"));
-	}
-
-	@Test
-	public void requestMatchersWhenUnmappableServletsThenSkips() {
-		mockMvcIntrospector(true);
-		MockServletContext servletContext = new MockServletContext();
-		given(this.context.getServletContext()).willReturn(servletContext);
-		servletContext.addServlet("dispatcherServlet", DispatcherServlet.class).addMapping("/");
-		servletContext.addServlet("servletTwo", Servlet.class);
-		List<RequestMatcher> requestMatchers = this.matcherRegistry.requestMatchers("/**");
-		assertThat(requestMatchers).hasSize(1);
-		assertThat(requestMatchers.get(0)).isInstanceOf(MvcRequestMatcher.class);
-	}
-
-	@Test
-	public void requestMatchersWhenOnlyDispatcherServletThenAllows() {
-		MockServletContext servletContext = new MockServletContext();
-		given(this.context.getServletContext()).willReturn(servletContext);
-		servletContext.addServlet("dispatcherServlet", DispatcherServlet.class).addMapping("/mvc/*");
-		List<RequestMatcher> requestMatchers = this.matcherRegistry.requestMatchers("/**");
-		assertThat(requestMatchers).hasSize(1);
-		assertThat(requestMatchers.get(0)).isInstanceOf(MvcRequestMatcher.class);
-	}
-
-	@Test
-	public void requestMatchersWhenImplicitServletsThenAllows() {
-		mockMvcIntrospector(true);
-		MockServletContext servletContext = new MockServletContext();
-		given(this.context.getServletContext()).willReturn(servletContext);
-		servletContext.addServlet("defaultServlet", Servlet.class);
-		servletContext.addServlet("jspServlet", Servlet.class).addMapping("*.jsp", "*.jspx");
-		servletContext.addServlet("dispatcherServlet", DispatcherServlet.class).addMapping("/");
-		List<RequestMatcher> requestMatchers = this.matcherRegistry.requestMatchers("/**");
-		assertThat(requestMatchers).hasSize(1);
-		assertThat(requestMatchers.get(0)).isInstanceOf(DispatcherServletDelegatingRequestMatcher.class);
-	}
-
-	@Test
-	public void requestMatchersWhenPathBasedNonDispatcherServletThenAllows() {
-		MockServletContext servletContext = new MockServletContext();
-		given(this.context.getServletContext()).willReturn(servletContext);
-		servletContext.addServlet("path", Servlet.class).addMapping("/services/*");
-		servletContext.addServlet("default", DispatcherServlet.class).addMapping("/");
-		List<RequestMatcher> requestMatchers = this.matcherRegistry.requestMatchers("/services/*");
-		assertThat(requestMatchers).hasSize(1);
-		assertThat(requestMatchers.get(0)).isInstanceOf(DispatcherServletDelegatingRequestMatcher.class);
-		MockHttpServletRequest request = new MockHttpServletRequest(servletContext, "GET", "/services/endpoint");
-		request.setHttpServletMapping(TestMockHttpServletMappings.defaultMapping());
-		assertThat(requestMatchers.get(0).matcher(request).isMatch()).isTrue();
-		request.setHttpServletMapping(TestMockHttpServletMappings.path(request, "/services"));
-		request.setServletPath("/services");
-		request.setPathInfo("/endpoint");
-		assertThat(requestMatchers.get(0).matcher(request).isMatch()).isTrue();
-	}
-
-	@Test
-	public void matchesWhenDispatcherServletThenMvc() {
-		MockServletContext servletContext = new MockServletContext();
-		servletContext.addServlet("default", DispatcherServlet.class).addMapping("/");
-		servletContext.addServlet("path", Servlet.class).addMapping("/services/*");
-		MvcRequestMatcher mvc = mock(MvcRequestMatcher.class);
-		AntPathRequestMatcher ant = mock(AntPathRequestMatcher.class);
-		RequestMatcher requestMatcher = new DispatcherServletDelegatingRequestMatcher(ant, mvc);
-		MockHttpServletRequest request = new MockHttpServletRequest(servletContext, "GET", "/services/endpoint");
-		request.setHttpServletMapping(TestMockHttpServletMappings.defaultMapping());
-		assertThat(requestMatcher.matches(request)).isFalse();
-		verify(mvc).matches(request);
-		verifyNoInteractions(ant);
-		request.setHttpServletMapping(TestMockHttpServletMappings.path(request, "/services"));
-		assertThat(requestMatcher.matches(request)).isFalse();
-		verify(ant).matches(request);
-		verifyNoMoreInteractions(mvc);
-	}
-
-	@Test
-	public void matchesWhenNoMappingThenException() {
-		MockServletContext servletContext = new MockServletContext();
-		servletContext.addServlet("default", DispatcherServlet.class).addMapping("/");
-		servletContext.addServlet("path", Servlet.class).addMapping("/services/*");
-		MvcRequestMatcher mvc = mock(MvcRequestMatcher.class);
-		AntPathRequestMatcher ant = mock(AntPathRequestMatcher.class);
-		RequestMatcher requestMatcher = new DispatcherServletDelegatingRequestMatcher(ant, mvc);
-		MockHttpServletRequest request = new MockHttpServletRequest(servletContext, "GET", "/services/endpoint");
-		assertThatExceptionOfType(IllegalArgumentException.class).isThrownBy(() -> requestMatcher.matcher(request));
-	}
-
-	private void mockMvcIntrospector(boolean isPresent) {
-		ApplicationContext context = this.matcherRegistry.getApplicationContext();
-		given(context.containsBean("mvcHandlerMappingIntrospector")).willReturn(isPresent);
+		assertThat(requestMatchers.get(0)).isExactlyInstanceOf(PathPatternRequestMatcher.class);
 	}
 
 	private static class TestRequestMatcherRegistry extends AbstractRequestMatcherRegistry<List<RequestMatcher>> {
 
-		@Override
-		public List<RequestMatcher> requestMatchers(RequestMatcher... requestMatchers) {
-			return unwrap(super.requestMatchers(requestMatchers));
-		}
-
 		@Override
 		protected List<RequestMatcher> chainRequestMatchers(List<RequestMatcher> requestMatchers) {
 			return requestMatchers;
 		}
 
-		private List<RequestMatcher> unwrap(List<RequestMatcher> wrappedMatchers) {
-			List<RequestMatcher> requestMatchers = new ArrayList<>();
-			for (RequestMatcher requestMatcher : wrappedMatchers) {
-				if (requestMatcher instanceof DeferredRequestMatcher) {
-					DeferredRequestMatcher deferred = (DeferredRequestMatcher) requestMatcher;
-					WebApplicationContext web = (WebApplicationContext) getApplicationContext();
-					requestMatchers.add(deferred.requestMatcher(web.getServletContext()));
-				}
-				else {
-					requestMatchers.add(requestMatcher);
-				}
-			}
-			return requestMatchers;
-		}
-
 	}
 
 	@Configuration

+ 3 - 3
config/src/test/java/org/springframework/security/config/annotation/web/builders/HttpConfigurationTests.java

@@ -39,7 +39,7 @@ import org.springframework.security.core.userdetails.PasswordEncodedUser;
 import org.springframework.security.core.userdetails.UserDetailsService;
 import org.springframework.security.provisioning.InMemoryUserDetailsManager;
 import org.springframework.security.web.SecurityFilterChain;
-import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
+import org.springframework.security.web.servlet.util.matcher.PathPatternRequestMatcher;
 import org.springframework.test.web.servlet.MockMvc;
 import org.springframework.web.filter.OncePerRequestFilter;
 import org.springframework.web.servlet.config.annotation.EnableWebMvc;
@@ -150,8 +150,8 @@ public class HttpConfigurationTests {
 			// @formatter:off
 			http
 				.securityMatchers((security) -> security
-					.requestMatchers(new AntPathRequestMatcher("/api/**"))
-					.requestMatchers(new AntPathRequestMatcher("/oauth/**")))
+					.requestMatchers(PathPatternRequestMatcher.withDefaults().matcher("/api/**"))
+					.requestMatchers(PathPatternRequestMatcher.withDefaults().matcher("/oauth/**")))
 				.authorizeRequests((requests) -> requests
 					.anyRequest().hasRole("USER"))
 				.httpBasic(withDefaults());

+ 13 - 12
config/src/test/java/org/springframework/security/config/annotation/web/builders/NamespaceHttpTests.java

@@ -54,8 +54,8 @@ import org.springframework.security.web.access.intercept.FilterSecurityIntercept
 import org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint;
 import org.springframework.security.web.context.NullSecurityContextRepository;
 import org.springframework.security.web.jaasapi.JaasApiIntegrationFilter;
+import org.springframework.security.web.servlet.util.matcher.PathPatternRequestMatcher;
 import org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestWrapper;
-import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
 import org.springframework.security.web.util.matcher.RegexRequestMatcher;
 import org.springframework.security.web.util.matcher.RequestMatcher;
 import org.springframework.stereotype.Controller;
@@ -195,13 +195,13 @@ public class NamespaceHttpTests {
 	}
 
 	@Test // http@request-matcher-ref ant
-	public void configureWhenAntPatternMatchingThenAntPathRequestMatcherUsed() {
+	public void configureWhenAntPatternMatchingThenPathPatternRequestMatcherUsed() {
 		this.spring.register(RequestMatcherAntConfig.class).autowire();
 		FilterChainProxy filterChainProxy = this.spring.getContext().getBean(FilterChainProxy.class);
 		assertThat(filterChainProxy.getFilterChains().get(0)).isInstanceOf(DefaultSecurityFilterChain.class);
 		DefaultSecurityFilterChain securityFilterChain = (DefaultSecurityFilterChain) filterChainProxy.getFilterChains()
 			.get(0);
-		assertThat(securityFilterChain.getRequestMatcher()).isInstanceOf(AntPathRequestMatcher.class);
+		assertThat(securityFilterChain.getRequestMatcher()).isInstanceOf(PathPatternRequestMatcher.class);
 	}
 
 	@Test // http@request-matcher-ref regex
@@ -226,21 +226,21 @@ public class NamespaceHttpTests {
 	}
 
 	@Test // http@security=none
-	public void configureWhenIgnoredAntPatternsThenAntPathRequestMatcherUsedWithNoFilters() {
+	public void configureWhenIgnoredAntPatternsThenPathPatternRequestMatcherUsedWithNoFilters() {
 		this.spring.register(SecurityNoneConfig.class).autowire();
 		FilterChainProxy filterChainProxy = this.spring.getContext().getBean(FilterChainProxy.class);
 		assertThat(filterChainProxy.getFilterChains().get(0)).isInstanceOf(DefaultSecurityFilterChain.class);
 		DefaultSecurityFilterChain securityFilterChain = (DefaultSecurityFilterChain) filterChainProxy.getFilterChains()
 			.get(0);
-		assertThat(securityFilterChain.getRequestMatcher()).isInstanceOf(AntPathRequestMatcher.class);
-		assertThat(((AntPathRequestMatcher) securityFilterChain.getRequestMatcher()).getPattern())
-			.isEqualTo("/resources/**");
+		assertThat(securityFilterChain.getRequestMatcher()).isInstanceOf(PathPatternRequestMatcher.class);
+		assertThat(securityFilterChain.getRequestMatcher())
+			.isEqualTo(PathPatternRequestMatcher.withDefaults().matcher("/resources/**"));
 		assertThat(securityFilterChain.getFilters()).isEmpty();
 		assertThat(filterChainProxy.getFilterChains().get(1)).isInstanceOf(DefaultSecurityFilterChain.class);
 		securityFilterChain = (DefaultSecurityFilterChain) filterChainProxy.getFilterChains().get(1);
-		assertThat(securityFilterChain.getRequestMatcher()).isInstanceOf(AntPathRequestMatcher.class);
-		assertThat(((AntPathRequestMatcher) securityFilterChain.getRequestMatcher()).getPattern())
-			.isEqualTo("/public/**");
+		assertThat(securityFilterChain.getRequestMatcher()).isInstanceOf(PathPatternRequestMatcher.class);
+		assertThat(securityFilterChain.getRequestMatcher())
+			.isEqualTo(PathPatternRequestMatcher.withDefaults().matcher("/public/**"));
 		assertThat(securityFilterChain.getFilters()).isEmpty();
 	}
 
@@ -482,7 +482,7 @@ public class NamespaceHttpTests {
 		SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
 			// @formatter:off
 			http
-				.securityMatcher(new AntPathRequestMatcher("/api/**"));
+				.securityMatcher(PathPatternRequestMatcher.withDefaults().matcher("/api/**"));
 			return http.build();
 			// @formatter:on
 		}
@@ -534,8 +534,9 @@ public class NamespaceHttpTests {
 
 		@Bean
 		WebSecurityCustomizer webSecurityCustomizer() {
+			PathPatternRequestMatcher.Builder builder = PathPatternRequestMatcher.withDefaults();
 			return (web) -> web.ignoring()
-				.requestMatchers(new AntPathRequestMatcher("/resources/**"), new AntPathRequestMatcher("/public/**"));
+				.requestMatchers(builder.matcher("/resources/**"), builder.matcher("/public/**"));
 		}
 
 		@Bean

+ 13 - 9
config/src/test/java/org/springframework/security/config/annotation/web/builders/WebSecurityFilterChainValidatorTests.java

@@ -31,7 +31,7 @@ import org.springframework.security.web.UnreachableFilterChainException;
 import org.springframework.security.web.access.ExceptionTranslationFilter;
 import org.springframework.security.web.access.intercept.FilterSecurityInterceptor;
 import org.springframework.security.web.authentication.AnonymousAuthenticationFilter;
-import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
+import org.springframework.security.web.servlet.util.matcher.PathPatternRequestMatcher;
 import org.springframework.security.web.util.matcher.AnyRequestMatcher;
 import org.springframework.security.web.util.matcher.RequestMatcher;
 import org.springframework.security.web.util.matcher.RequestMatchers;
@@ -49,6 +49,8 @@ public class WebSecurityFilterChainValidatorTests {
 
 	private final WebSecurityFilterChainValidator validator = new WebSecurityFilterChainValidator();
 
+	private final PathPatternRequestMatcher.Builder builder = PathPatternRequestMatcher.withDefaults();
+
 	@Mock
 	private AnonymousAuthenticationFilter authenticationFilter;
 
@@ -60,7 +62,7 @@ public class WebSecurityFilterChainValidatorTests {
 
 	@Test
 	void validateWhenFilterSecurityInterceptorConfiguredThenValidates() {
-		SecurityFilterChain chain = new DefaultSecurityFilterChain(AntPathRequestMatcher.antMatcher("/api"),
+		SecurityFilterChain chain = new DefaultSecurityFilterChain(this.builder.matcher("/api"),
 				this.authenticationFilter, this.exceptionTranslationFilter, this.authorizationInterceptor);
 		FilterChainProxy proxy = new FilterChainProxy(List.of(chain));
 
@@ -69,7 +71,7 @@ public class WebSecurityFilterChainValidatorTests {
 
 	@Test
 	void validateWhenAnyRequestMatcherIsPresentThenUnreachableFilterChainException() {
-		SecurityFilterChain chain1 = new DefaultSecurityFilterChain(AntPathRequestMatcher.antMatcher("/api"),
+		SecurityFilterChain chain1 = new DefaultSecurityFilterChain(this.builder.matcher("/api"),
 				this.authenticationFilter, this.exceptionTranslationFilter, this.authorizationInterceptor);
 		SecurityFilterChain chain2 = new DefaultSecurityFilterChain(AnyRequestMatcher.INSTANCE,
 				this.authenticationFilter, this.exceptionTranslationFilter, this.authorizationInterceptor);
@@ -84,9 +86,9 @@ public class WebSecurityFilterChainValidatorTests {
 
 	@Test
 	void validateWhenSameRequestMatchersArePresentThenUnreachableFilterChainException() {
-		SecurityFilterChain chain1 = new DefaultSecurityFilterChain(AntPathRequestMatcher.antMatcher("/api"),
+		SecurityFilterChain chain1 = new DefaultSecurityFilterChain(this.builder.matcher("/api"),
 				this.authenticationFilter, this.exceptionTranslationFilter, this.authorizationInterceptor);
-		SecurityFilterChain chain2 = new DefaultSecurityFilterChain(AntPathRequestMatcher.antMatcher("/api"),
+		SecurityFilterChain chain2 = new DefaultSecurityFilterChain(this.builder.matcher("/api"),
 				this.authenticationFilter, this.exceptionTranslationFilter, this.authorizationInterceptor);
 		List<SecurityFilterChain> chains = new ArrayList<>();
 		chains.add(chain2);
@@ -99,10 +101,12 @@ public class WebSecurityFilterChainValidatorTests {
 
 	@Test
 	void validateWhenSameComposedRequestMatchersArePresentThenUnreachableFilterChainException() {
-		RequestMatcher matcher1 = RequestMatchers.anyOf(RequestMatchers.allOf(AntPathRequestMatcher.antMatcher("/api"),
-				AntPathRequestMatcher.antMatcher("*.do")), AntPathRequestMatcher.antMatcher("/admin"));
-		RequestMatcher matcher2 = RequestMatchers.anyOf(RequestMatchers.allOf(AntPathRequestMatcher.antMatcher("/api"),
-				AntPathRequestMatcher.antMatcher("*.do")), AntPathRequestMatcher.antMatcher("/admin"));
+		RequestMatcher matcher1 = RequestMatchers.anyOf(
+				RequestMatchers.allOf(this.builder.matcher("/api"), this.builder.matcher("/*.do")),
+				this.builder.matcher("/admin"));
+		RequestMatcher matcher2 = RequestMatchers.anyOf(
+				RequestMatchers.allOf(this.builder.matcher("/api"), this.builder.matcher("/*.do")),
+				this.builder.matcher("/admin"));
 		SecurityFilterChain chain1 = new DefaultSecurityFilterChain(matcher1, this.authenticationFilter,
 				this.exceptionTranslationFilter, this.authorizationInterceptor);
 		SecurityFilterChain chain2 = new DefaultSecurityFilterChain(matcher2, this.authenticationFilter,

+ 18 - 7
config/src/test/java/org/springframework/security/config/annotation/web/builders/WebSecurityTests.java

@@ -37,17 +37,17 @@ import org.springframework.mock.web.MockHttpServletResponse;
 import org.springframework.mock.web.MockServletContext;
 import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
 import org.springframework.security.config.annotation.web.configuration.WebSecurityCustomizer;
+import org.springframework.security.config.web.PathPatternRequestMatcherBuilderFactoryBean;
 import org.springframework.security.core.userdetails.PasswordEncodedUser;
 import org.springframework.security.core.userdetails.UserDetailsService;
 import org.springframework.security.provisioning.InMemoryUserDetailsManager;
 import org.springframework.security.web.SecurityFilterChain;
 import org.springframework.security.web.firewall.HttpStatusRequestRejectedHandler;
-import org.springframework.security.web.servlet.util.matcher.MvcRequestMatcher;
+import org.springframework.security.web.servlet.util.matcher.PathPatternRequestMatcher;
 import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.RestController;
 import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
 import org.springframework.web.servlet.config.annotation.EnableWebMvc;
-import org.springframework.web.servlet.handler.HandlerMappingIntrospector;
 
 import static org.assertj.core.api.Assertions.assertThat;
 import static org.springframework.security.config.Customizer.withDefaults;
@@ -130,8 +130,13 @@ public class WebSecurityTests {
 	static class MvcMatcherConfig {
 
 		@Bean
-		WebSecurityCustomizer webSecurityCustomizer(HandlerMappingIntrospector introspector) {
-			return (web) -> web.ignoring().requestMatchers(new MvcRequestMatcher(introspector, "/path"));
+		PathPatternRequestMatcherBuilderFactoryBean pathPatternRequestMatcherBuilder() {
+			return new PathPatternRequestMatcherBuilderFactoryBean();
+		}
+
+		@Bean
+		WebSecurityCustomizer webSecurityCustomizer(PathPatternRequestMatcher.Builder builder) {
+			return (web) -> web.ignoring().requestMatchers(builder.matcher("/path"));
 		}
 
 		@Bean
@@ -168,9 +173,15 @@ public class WebSecurityTests {
 	static class MvcMatcherServletPathConfig {
 
 		@Bean
-		WebSecurityCustomizer webSecurityCustomizer(HandlerMappingIntrospector introspector) {
-			MvcRequestMatcher.Builder builder = new MvcRequestMatcher.Builder(introspector).servletPath("/spring");
-			return (web) -> web.ignoring().requestMatchers(builder.pattern("/path")).requestMatchers("/notused");
+		PathPatternRequestMatcherBuilderFactoryBean pathPatternRequestMatcherBuilder() {
+			return new PathPatternRequestMatcherBuilderFactoryBean();
+		}
+
+		@Bean
+		WebSecurityCustomizer webSecurityCustomizer(PathPatternRequestMatcher.Builder builder) {
+			return (web) -> web.ignoring()
+				.requestMatchers(builder.basePath("/spring").matcher("/path"))
+				.requestMatchers("/notused");
 		}
 
 		@Bean

+ 6 - 26
config/src/test/java/org/springframework/security/config/annotation/web/configuration/AuthorizationManagerWebInvocationPrivilegeEvaluatorConfigTests.java

@@ -26,20 +26,19 @@ import org.springframework.security.authentication.TestAuthentication;
 import org.springframework.security.config.test.SpringTestContext;
 import org.springframework.security.test.context.annotation.SecurityTestExecutionListeners;
 import org.springframework.security.web.access.AuthorizationManagerWebInvocationPrivilegeEvaluator.HttpServletRequestTransformer;
-import org.springframework.security.web.access.HandlerMappingIntrospectorRequestTransformer;
 import org.springframework.security.web.access.WebInvocationPrivilegeEvaluator;
 import org.springframework.test.context.ContextConfiguration;
 import org.springframework.test.context.junit.jupiter.SpringExtension;
 import org.springframework.test.context.web.WebAppConfiguration;
-import org.springframework.web.servlet.config.annotation.EnableWebMvc;
 
-import static org.assertj.core.api.Assertions.assertThat;
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.verify;
 
 /**
- * Checks that HandlerMappingIntrospectorRequestTransformer is autowired into
+ * Checks that
+ * {@link org.springframework.security.web.access.PathPatternRequestTransformer} is
+ * autowired into
  * {@link org.springframework.security.web.access.AuthorizationManagerWebInvocationPrivilegeEvaluator}.
  *
  * @author Rob Winch
@@ -59,20 +58,8 @@ public class AuthorizationManagerWebInvocationPrivilegeEvaluatorConfigTests {
 	WebInvocationPrivilegeEvaluator wipe;
 
 	@Test
-	void mvcEnabledConfigThenHandlerMappingIntrospectorRequestTransformerBeanExists() {
-		this.spring.register(MvcEnabledConfig.class).autowire();
-		assertThat(this.requestTransformer).isInstanceOf(HandlerMappingIntrospectorRequestTransformer.class);
-	}
-
-	@Test
-	void mvcNotEnabledThenNoRequestTransformerBeanExists() {
-		this.spring.register(MvcNotEnabledConfig.class).autowire();
-		assertThat(this.requestTransformer).isNull();
-	}
-
-	@Test
-	void mvcNotEnabledAndTransformerThenWIPEDelegatesToTransformer() {
-		this.spring.register(MvcNotEnabledConfig.class, TransformerConfig.class).autowire();
+	void webAndTransformerThenWIPEDelegatesToTransformer() {
+		this.spring.register(WebConfig.class, TransformerConfig.class).autowire();
 
 		this.wipe.isAllowed("/uri", TestAuthentication.authenticatedUser());
 
@@ -89,16 +76,9 @@ public class AuthorizationManagerWebInvocationPrivilegeEvaluatorConfigTests {
 
 	}
 
-	@Configuration
-	@EnableWebMvc
-	@EnableWebSecurity
-	static class MvcEnabledConfig {
-
-	}
-
 	@Configuration
 	@EnableWebSecurity
-	static class MvcNotEnabledConfig {
+	static class WebConfig {
 
 	}
 

+ 0 - 127
config/src/test/java/org/springframework/security/config/annotation/web/configuration/HandlerMappingIntrospectorCacheFilterConfigTests.java

@@ -1,127 +0,0 @@
-/*
- * Copyright 2002-2023 the original author or authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      https://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.springframework.security.config.annotation.web.configuration;
-
-import java.io.IOException;
-
-import jakarta.servlet.Filter;
-import jakarta.servlet.FilterChain;
-import jakarta.servlet.ServletException;
-import jakarta.servlet.ServletRequest;
-import jakarta.servlet.ServletResponse;
-import jakarta.servlet.http.HttpServletRequest;
-import org.junit.jupiter.api.Test;
-import org.junit.jupiter.api.extension.ExtendWith;
-
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.context.annotation.Configuration;
-import org.springframework.security.config.test.SpringTestContext;
-import org.springframework.security.test.context.annotation.SecurityTestExecutionListeners;
-import org.springframework.security.test.context.support.WithMockUser;
-import org.springframework.stereotype.Component;
-import org.springframework.test.context.ContextConfiguration;
-import org.springframework.test.context.junit.jupiter.SpringExtension;
-import org.springframework.test.context.web.WebAppConfiguration;
-import org.springframework.test.web.servlet.MockMvc;
-import org.springframework.test.web.servlet.setup.MockMvcBuilders;
-import org.springframework.web.context.WebApplicationContext;
-import org.springframework.web.servlet.config.annotation.EnableWebMvc;
-import org.springframework.web.servlet.handler.HandlerMappingIntrospector;
-import org.springframework.web.servlet.handler.HandlerMappingIntrospector.CachedResult;
-
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.springframework.security.test.web.servlet.setup.SecurityMockMvcConfigurers.springSecurity;
-import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
-
-/**
- * @author Rob Winch
- */
-@ContextConfiguration
-@WebAppConfiguration
-@ExtendWith({ SpringExtension.class })
-@SecurityTestExecutionListeners
-class HandlerMappingIntrospectorCacheFilterConfigTests {
-
-	@Autowired
-	WebApplicationContext context;
-
-	MockMvc mockMvc;
-
-	public final SpringTestContext spring = new SpringTestContext(this);
-
-	@Autowired(required = false)
-	MvcEnabledConfig.CaptureHandlerMappingIntrospectorCache captureCacheFilter;
-
-	@Autowired(required = false)
-	HandlerMappingIntrospector hmi;
-
-	@Test
-	@WithMockUser
-	void hmiIsCached() throws Exception {
-		this.spring.register(MvcEnabledConfig.class).autowire();
-		this.mockMvc = MockMvcBuilders.webAppContextSetup(this.context)
-			.apply(springSecurity())
-			.addFilter(this.captureCacheFilter)
-			.build();
-		this.mockMvc.perform(get("/"));
-		assertThat(this.captureCacheFilter.cachedResult).isNotNull();
-	}
-
-	@Test
-	@WithMockUser
-	void configurationLoadsIfNoHMI() {
-		// no BeanCreationException due to missing HandlerMappingIntrospector
-		this.spring.register(MvcNotEnabledConfig.class).autowire();
-		// ensure assumption of HandlerMappingIntrospector is null is true
-		assertThat(this.hmi).isNull();
-	}
-
-	@Configuration
-	@EnableWebMvc
-	@EnableWebSecurity
-	static class MvcEnabledConfig {
-
-		@Component
-		static class CaptureHandlerMappingIntrospectorCache implements Filter {
-
-			final HandlerMappingIntrospector hmi;
-
-			private CachedResult cachedResult;
-
-			CaptureHandlerMappingIntrospectorCache(HandlerMappingIntrospector hmi) {
-				this.hmi = hmi;
-			}
-
-			@Override
-			public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
-					throws IOException, ServletException {
-				// capture the old cached value to check that caching has already occurred
-				this.cachedResult = this.hmi.setCache((HttpServletRequest) request);
-				chain.doFilter(request, response);
-			}
-
-		}
-
-	}
-
-	@Configuration
-	@EnableWebSecurity
-	static class MvcNotEnabledConfig {
-
-	}
-
-}

+ 26 - 32
config/src/test/java/org/springframework/security/config/annotation/web/configuration/WebSecurityConfigurationTests.java

@@ -63,7 +63,6 @@ import org.springframework.security.web.access.RequestMatcherDelegatingWebInvoca
 import org.springframework.security.web.access.WebInvocationPrivilegeEvaluator;
 import org.springframework.security.web.access.expression.DefaultWebSecurityExpressionHandler;
 import org.springframework.security.web.servlet.util.matcher.PathPatternRequestMatcher;
-import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
 import org.springframework.test.web.servlet.MockMvc;
 import org.springframework.util.ClassUtils;
 import org.springframework.web.bind.annotation.GetMapping;
@@ -106,14 +105,13 @@ public class WebSecurityConfigurationTests {
 		FilterChainProxy filterChainProxy = this.spring.getContext().getBean(FilterChainProxy.class);
 		List<SecurityFilterChain> filterChains = filterChainProxy.getFilterChains();
 		assertThat(filterChains).hasSize(4);
-		MockHttpServletRequest request = new MockHttpServletRequest("GET", "");
-		request.setServletPath("/role1/**");
+		MockHttpServletRequest request = new MockHttpServletRequest("GET", "/role1/**");
 		assertThat(filterChains.get(0).matches(request)).isTrue();
-		request.setServletPath("/role2/**");
+		request = new MockHttpServletRequest("GET", "/role2/**");
 		assertThat(filterChains.get(1).matches(request)).isTrue();
-		request.setServletPath("/role3/**");
+		request = new MockHttpServletRequest("GET", "/role3/**");
 		assertThat(filterChains.get(2).matches(request)).isTrue();
-		request.setServletPath("/**");
+		request = new MockHttpServletRequest("GET", "/**");
 		assertThat(filterChains.get(3).matches(request)).isTrue();
 	}
 
@@ -123,10 +121,9 @@ public class WebSecurityConfigurationTests {
 		FilterChainProxy filterChainProxy = this.spring.getContext().getBean(FilterChainProxy.class);
 		List<SecurityFilterChain> filterChains = filterChainProxy.getFilterChains();
 		assertThat(filterChains).hasSize(2);
-		MockHttpServletRequest request = new MockHttpServletRequest("GET", "");
-		request.setServletPath("/role1/**");
+		MockHttpServletRequest request = new MockHttpServletRequest("GET", "/role1/**");
 		assertThat(filterChains.get(0).matches(request)).isTrue();
-		request.setServletPath("/role2/**");
+		request = new MockHttpServletRequest("GET", "/role2/**");
 		assertThat(filterChains.get(1).matches(request)).isTrue();
 	}
 
@@ -240,14 +237,13 @@ public class WebSecurityConfigurationTests {
 		FilterChainProxy filterChainProxy = this.spring.getContext().getBean(FilterChainProxy.class);
 		List<SecurityFilterChain> filterChains = filterChainProxy.getFilterChains();
 		assertThat(filterChains).hasSize(3);
-		MockHttpServletRequest request = new MockHttpServletRequest("GET", "");
-		request.setServletPath("/ignore1");
+		MockHttpServletRequest request = new MockHttpServletRequest("GET", "/ignore1");
 		assertThat(filterChains.get(0).matches(request)).isTrue();
 		assertThat(filterChains.get(0).getFilters()).isEmpty();
-		request.setServletPath("/ignore2");
+		request = new MockHttpServletRequest("GET", "/ignore2");
 		assertThat(filterChains.get(1).matches(request)).isTrue();
 		assertThat(filterChains.get(1).getFilters()).isEmpty();
-		request.setServletPath("/test/**");
+		request = new MockHttpServletRequest("GET", "/test/**");
 		assertThat(filterChains.get(2).matches(request)).isTrue();
 	}
 
@@ -257,16 +253,15 @@ public class WebSecurityConfigurationTests {
 		FilterChainProxy filterChainProxy = this.spring.getContext().getBean(FilterChainProxy.class);
 		List<SecurityFilterChain> filterChains = filterChainProxy.getFilterChains();
 		assertThat(filterChains).hasSize(3);
-		MockHttpServletRequest request = new MockHttpServletRequest("GET", "");
-		request.setServletPath("/ignore1");
+		MockHttpServletRequest request = new MockHttpServletRequest("GET", "/ignore1");
 		assertThat(filterChains.get(0).matches(request)).isTrue();
 		assertThat(filterChains.get(0).getFilters()).isEmpty();
-		request.setServletPath("/ignore2");
+		request = new MockHttpServletRequest("GET", "/ignore2");
 		assertThat(filterChains.get(1).matches(request)).isTrue();
 		assertThat(filterChains.get(1).getFilters()).isEmpty();
-		request.setServletPath("/role1/**");
+		request = new MockHttpServletRequest("GET", "/role1/**");
 		assertThat(filterChains.get(2).matches(request)).isTrue();
-		request.setServletPath("/test/**");
+		request = new MockHttpServletRequest("GET", "/test/**");
 		assertThat(filterChains.get(2).matches(request)).isFalse();
 	}
 
@@ -276,11 +271,10 @@ public class WebSecurityConfigurationTests {
 		FilterChainProxy filterChainProxy = this.spring.getContext().getBean(FilterChainProxy.class);
 		List<SecurityFilterChain> filterChains = filterChainProxy.getFilterChains();
 		assertThat(filterChains).hasSize(3);
-		MockHttpServletRequest request = new MockHttpServletRequest("GET", "");
-		request.setServletPath("/ignore1");
+		MockHttpServletRequest request = new MockHttpServletRequest("GET", "/ignore1");
 		assertThat(filterChains.get(0).matches(request)).isTrue();
 		assertThat(filterChains.get(0).getFilters()).isEmpty();
-		request.setServletPath("/ignore2");
+		request = new MockHttpServletRequest("GET", "/ignore2");
 		assertThat(filterChains.get(1).matches(request)).isTrue();
 		assertThat(filterChains.get(1).getFilters()).isEmpty();
 	}
@@ -420,7 +414,7 @@ public class WebSecurityConfigurationTests {
 		SecurityFilterChain filterChain1(HttpSecurity http) throws Exception {
 			// @formatter:off
 			return http
-					.securityMatcher(new AntPathRequestMatcher("/role1/**"))
+					.securityMatcher(PathPatternRequestMatcher.withDefaults().matcher("/role1/**"))
 					.authorizeRequests((authorize) -> authorize
 							.anyRequest().hasRole("1")
 					)
@@ -433,7 +427,7 @@ public class WebSecurityConfigurationTests {
 		SecurityFilterChain filterChain2(HttpSecurity http) throws Exception {
 			// @formatter:off
 			return http
-					.securityMatcher(new AntPathRequestMatcher("/role2/**"))
+					.securityMatcher(PathPatternRequestMatcher.withDefaults().matcher("/role2/**"))
 					.authorizeRequests((authorize) -> authorize
 							.anyRequest().hasRole("2")
 					)
@@ -446,7 +440,7 @@ public class WebSecurityConfigurationTests {
 		SecurityFilterChain filterChain3(HttpSecurity http) throws Exception {
 			// @formatter:off
 			return http
-					.securityMatcher(new AntPathRequestMatcher("/role3/**"))
+					.securityMatcher(PathPatternRequestMatcher.withDefaults().matcher("/role3/**"))
 					.authorizeRequests((authorize) -> authorize
 							.anyRequest().hasRole("3")
 					)
@@ -477,7 +471,7 @@ public class WebSecurityConfigurationTests {
 		SecurityFilterChain securityFilterChain1(HttpSecurity http) throws Exception {
 			// @formatter:off
 			return http
-					.securityMatcher(new AntPathRequestMatcher("/role1/**"))
+					.securityMatcher(PathPatternRequestMatcher.withDefaults().matcher("/role1/**"))
 					.authorizeRequests((authorize) -> authorize
 							.anyRequest().hasRole("1")
 					)
@@ -734,7 +728,7 @@ public class WebSecurityConfigurationTests {
 		SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
 			// @formatter:off
 			return http
-					.securityMatcher(new AntPathRequestMatcher("/role1/**"))
+					.securityMatcher(PathPatternRequestMatcher.withDefaults().matcher("/role1/**"))
 					.authorizeRequests((authorize) -> authorize
 							.anyRequest().hasRole("1")
 					)
@@ -773,7 +767,7 @@ public class WebSecurityConfigurationTests {
 		public SecurityFilterChain path1(HttpSecurity http) throws Exception {
 			// @formatter:off
 			http
-				.securityMatchers((requests) -> requests.requestMatchers(new AntPathRequestMatcher("/path1/**")))
+				.securityMatchers((requests) -> requests.requestMatchers(PathPatternRequestMatcher.withDefaults().matcher("/path1/**")))
 				.authorizeRequests((requests) -> requests.anyRequest().authenticated());
 			// @formatter:on
 			return http.build();
@@ -797,7 +791,7 @@ public class WebSecurityConfigurationTests {
 		public SecurityFilterChain path1(HttpSecurity http) throws Exception {
 			// @formatter:off
 			http
-					.securityMatchers((requests) -> requests.requestMatchers(new AntPathRequestMatcher("/path1/**")))
+					.securityMatchers((requests) -> requests.requestMatchers(PathPatternRequestMatcher.withDefaults().matcher("/path1/**")))
 					.authorizeRequests((requests) -> requests.anyRequest().authenticated());
 			// @formatter:on
 			return http.build();
@@ -822,7 +816,7 @@ public class WebSecurityConfigurationTests {
 		public SecurityFilterChain notAuthorized(HttpSecurity http) throws Exception {
 			// @formatter:off
 			http
-				.securityMatchers((requests) -> requests.requestMatchers(new AntPathRequestMatcher("/user")))
+				.securityMatchers((requests) -> requests.requestMatchers(PathPatternRequestMatcher.withDefaults().matcher("/user")))
 				.authorizeRequests((requests) -> requests.anyRequest().hasRole("USER"));
 			// @formatter:on
 			return http.build();
@@ -833,7 +827,7 @@ public class WebSecurityConfigurationTests {
 		public SecurityFilterChain path1(HttpSecurity http) throws Exception {
 			// @formatter:off
 			http
-				.securityMatchers((requests) -> requests.requestMatchers(new AntPathRequestMatcher("/admin")))
+				.securityMatchers((requests) -> requests.requestMatchers(PathPatternRequestMatcher.withDefaults().matcher("/admin")))
 				.authorizeRequests((requests) -> requests.anyRequest().hasRole("ADMIN"));
 			// @formatter:on
 			return http.build();
@@ -864,7 +858,7 @@ public class WebSecurityConfigurationTests {
 		public SecurityFilterChain notAuthorized(HttpSecurity http) throws Exception {
 			// @formatter:off
 			http
-					.securityMatchers((requests) -> requests.requestMatchers(new AntPathRequestMatcher("/user")))
+					.securityMatchers((requests) -> requests.requestMatchers(PathPatternRequestMatcher.withDefaults().matcher("/user")))
 					.authorizeRequests((requests) -> requests.anyRequest().hasRole("USER"));
 			// @formatter:on
 			return http.build();
@@ -875,7 +869,7 @@ public class WebSecurityConfigurationTests {
 		public SecurityFilterChain admin(HttpSecurity http) throws Exception {
 			// @formatter:off
 			http
-					.securityMatchers((requests) -> requests.requestMatchers(new AntPathRequestMatcher("/admin")))
+					.securityMatchers((requests) -> requests.requestMatchers(PathPatternRequestMatcher.withDefaults().matcher("/admin")))
 					.authorizeRequests((requests) -> requests.anyRequest().hasRole("ADMIN"));
 			// @formatter:on
 			return http.build();

+ 8 - 7
config/src/test/java/org/springframework/security/config/annotation/web/configurers/AbstractConfigAttributeRequestMatcherRegistryTests.java

@@ -22,7 +22,7 @@ import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
 
 import org.springframework.http.HttpMethod;
-import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
+import org.springframework.security.web.servlet.util.matcher.PathPatternRequestMatcher;
 import org.springframework.security.web.util.matcher.RegexRequestMatcher;
 import org.springframework.security.web.util.matcher.RequestMatcher;
 
@@ -55,19 +55,20 @@ public class AbstractConfigAttributeRequestMatcherRegistryTests {
 	}
 
 	@Test
-	public void testGetRequestMatcherIsTypeAntPathRequestMatcher() {
+	public void testGetRequestMatcherIsTypePathPatternRequestMatcher() {
 		List<RequestMatcher> requestMatchers = this.registry
-			.requestMatchers(new AntPathRequestMatcher("/a.*", HttpMethod.GET.name()));
+			.requestMatchers(PathPatternRequestMatcher.withDefaults().matcher(HttpMethod.GET, "/a.*"));
 		for (RequestMatcher requestMatcher : requestMatchers) {
-			assertThat(requestMatcher).isInstanceOf(AntPathRequestMatcher.class);
+			assertThat(requestMatcher).isInstanceOf(PathPatternRequestMatcher.class);
 		}
 	}
 
 	@Test
-	public void testRequestMatcherIsTypeAntPathRequestMatcher() {
-		List<RequestMatcher> requestMatchers = this.registry.requestMatchers(new AntPathRequestMatcher("/a.*"));
+	public void testRequestMatcherIsTypePathPatternRequestMatcher() {
+		List<RequestMatcher> requestMatchers = this.registry
+			.requestMatchers(PathPatternRequestMatcher.withDefaults().matcher("/a.*"));
 		for (RequestMatcher requestMatcher : requestMatchers) {
-			assertThat(requestMatcher).isInstanceOf(AntPathRequestMatcher.class);
+			assertThat(requestMatcher).isInstanceOf(PathPatternRequestMatcher.class);
 		}
 	}
 

+ 10 - 9
config/src/test/java/org/springframework/security/config/annotation/web/configurers/AuthorizeHttpRequestsConfigurerTests.java

@@ -68,7 +68,6 @@ import org.springframework.security.web.access.expression.WebExpressionAuthoriza
 import org.springframework.security.web.access.intercept.AuthorizationFilter;
 import org.springframework.security.web.access.intercept.RequestAuthorizationContext;
 import org.springframework.security.web.access.intercept.RequestMatcherDelegatingAuthorizationManager;
-import org.springframework.security.web.servlet.util.matcher.MvcRequestMatcher;
 import org.springframework.security.web.servlet.util.matcher.PathPatternRequestMatcher;
 import org.springframework.stereotype.Component;
 import org.springframework.test.web.servlet.MockMvc;
@@ -81,7 +80,6 @@ import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.RestController;
 import org.springframework.web.servlet.DispatcherServlet;
 import org.springframework.web.servlet.config.annotation.EnableWebMvc;
-import org.springframework.web.servlet.handler.HandlerMappingIntrospector;
 
 import static org.assertj.core.api.Assertions.assertThat;
 import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
@@ -148,7 +146,7 @@ public class AuthorizeHttpRequestsConfigurerTests {
 	public void configureWhenMvcMatcherAfterAnyRequestThenException() {
 		assertThatExceptionOfType(BeanCreationException.class)
 			.isThrownBy(() -> this.spring.register(AfterAnyRequestConfig.class).autowire())
-			.withMessageContaining("Can't configure mvcMatchers after anyRequest");
+			.withMessageContaining("Can't configure requestMatchers after anyRequest");
 	}
 
 	@Test
@@ -689,7 +687,7 @@ public class AuthorizeHttpRequestsConfigurerTests {
 
 	@Test
 	public void requestMatchersWhenMultipleDispatcherServletsAndPathBeanThenAllows() throws Exception {
-		this.spring.register(MvcRequestMatcherBuilderConfig.class, BasicController.class)
+		this.spring.register(PathPatternRequestMatcherBuilderConfig.class, BasicController.class)
 			.postProcessor((context) -> context.getServletContext()
 				.addServlet("otherDispatcherServlet", DispatcherServlet.class)
 				.addMapping("/mvc"))
@@ -1063,13 +1061,16 @@ public class AuthorizeHttpRequestsConfigurerTests {
 	static class ServletPathConfig {
 
 		@Bean
-		SecurityFilterChain filterChain(HttpSecurity http, HandlerMappingIntrospector introspector) throws Exception {
-			MvcRequestMatcher.Builder mvcMatcherBuilder = new MvcRequestMatcher.Builder(introspector)
-				.servletPath("/spring");
+		PathPatternRequestMatcherBuilderFactoryBean pathPattern() {
+			return new PathPatternRequestMatcherBuilderFactoryBean();
+		}
+
+		@Bean
+		SecurityFilterChain filterChain(HttpSecurity http, PathPatternRequestMatcher.Builder builder) throws Exception {
 			// @formatter:off
 			return http
 					.authorizeHttpRequests((authorize) -> authorize
-						.requestMatchers(mvcMatcherBuilder.pattern("/")).hasRole("ADMIN")
+						.requestMatchers(builder.basePath("/spring").matcher("/")).hasRole("ADMIN")
 					)
 					.build();
 			// @formatter:on
@@ -1358,7 +1359,7 @@ public class AuthorizeHttpRequestsConfigurerTests {
 	@Configuration
 	@EnableWebSecurity
 	@EnableWebMvc
-	static class MvcRequestMatcherBuilderConfig {
+	static class PathPatternRequestMatcherBuilderConfig {
 
 		@Bean
 		SecurityFilterChain security(HttpSecurity http) throws Exception {

+ 35 - 15
config/src/test/java/org/springframework/security/config/annotation/web/configurers/AuthorizeRequestsTests.java

@@ -33,6 +33,7 @@ import org.springframework.security.access.hierarchicalroles.RoleHierarchyImpl;
 import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
 import org.springframework.security.config.annotation.web.builders.HttpSecurity;
 import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
+import org.springframework.security.config.web.PathPatternRequestMatcherBuilderFactoryBean;
 import org.springframework.security.core.authority.AuthorityUtils;
 import org.springframework.security.core.context.SecurityContext;
 import org.springframework.security.core.context.SecurityContextImpl;
@@ -42,13 +43,12 @@ import org.springframework.security.web.FilterChainProxy;
 import org.springframework.security.web.SecurityFilterChain;
 import org.springframework.security.web.context.HttpSessionSecurityContextRepository;
 import org.springframework.security.web.servlet.MockServletContext;
-import org.springframework.security.web.servlet.util.matcher.MvcRequestMatcher;
-import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
+import org.springframework.security.web.servlet.util.matcher.PathPatternRequestMatcher;
 import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.RestController;
 import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
 import org.springframework.web.servlet.config.annotation.EnableWebMvc;
-import org.springframework.web.servlet.handler.HandlerMappingIntrospector;
+import org.springframework.web.util.pattern.PathPatternParser;
 
 import static org.assertj.core.api.Assertions.assertThat;
 import static org.mockito.Mockito.spy;
@@ -111,10 +111,12 @@ public class AuthorizeRequestsTests {
 	public void antMatchersPathVariables() throws Exception {
 		loadConfig(AntPatchersPathVariables.class);
 		this.request.setServletPath("/user/user");
+		this.request.setRequestURI("/user/user");
 		this.springSecurityFilterChain.doFilter(this.request, this.response, this.chain);
 		assertThat(this.response.getStatus()).isEqualTo(HttpServletResponse.SC_OK);
 		this.setup();
 		this.request.setServletPath("/user/deny");
+		this.request.setRequestURI("/user/deny");
 		this.springSecurityFilterChain.doFilter(this.request, this.response, this.chain);
 		assertThat(this.response.getStatus()).isEqualTo(HttpServletResponse.SC_FORBIDDEN);
 	}
@@ -124,10 +126,12 @@ public class AuthorizeRequestsTests {
 	public void antMatchersPathVariablesCaseInsensitive() throws Exception {
 		loadConfig(AntPatchersPathVariables.class);
 		this.request.setServletPath("/USER/user");
+		this.request.setRequestURI("/USER/user");
 		this.springSecurityFilterChain.doFilter(this.request, this.response, this.chain);
 		assertThat(this.response.getStatus()).isEqualTo(HttpServletResponse.SC_OK);
 		this.setup();
 		this.request.setServletPath("/USER/deny");
+		this.request.setRequestURI("/USER/deny");
 		this.springSecurityFilterChain.doFilter(this.request, this.response, this.chain);
 		assertThat(this.response.getStatus()).isEqualTo(HttpServletResponse.SC_FORBIDDEN);
 	}
@@ -137,10 +141,12 @@ public class AuthorizeRequestsTests {
 	public void antMatchersPathVariablesCaseInsensitiveCamelCaseVariables() throws Exception {
 		loadConfig(AntMatchersPathVariablesCamelCaseVariables.class);
 		this.request.setServletPath("/USER/user");
+		this.request.setRequestURI("/USER/user");
 		this.springSecurityFilterChain.doFilter(this.request, this.response, this.chain);
 		assertThat(this.response.getStatus()).isEqualTo(HttpServletResponse.SC_OK);
 		this.setup();
 		this.request.setServletPath("/USER/deny");
+		this.request.setRequestURI("/USER/deny");
 		this.springSecurityFilterChain.doFilter(this.request, this.response, this.chain);
 		assertThat(this.response.getStatus()).isEqualTo(HttpServletResponse.SC_FORBIDDEN);
 	}
@@ -199,7 +205,7 @@ public class AuthorizeRequestsTests {
 			// @formatter:off
 			http
 				.authorizeRequests((requests) -> requests
-					.requestMatchers(new AntPathRequestMatcher("/**", HttpMethod.POST.name())).denyAll());
+					.requestMatchers(PathPatternRequestMatcher.withDefaults().matcher(HttpMethod.POST, "/**")).denyAll());
 			// @formatter:on
 			return http.build();
 		}
@@ -220,7 +226,7 @@ public class AuthorizeRequestsTests {
 			// @formatter:off
 			http
 				.authorizeRequests((authorize) -> authorize
-						.requestMatchers(new AntPathRequestMatcher("/**", HttpMethod.POST.name())).denyAll()
+						.requestMatchers(PathPatternRequestMatcher.withDefaults().matcher(HttpMethod.POST, "/**")).denyAll()
 				);
 			// @formatter:on
 			return http.build();
@@ -239,10 +245,13 @@ public class AuthorizeRequestsTests {
 
 		@Bean
 		SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
+			PathPatternParser parser = new PathPatternParser();
+			parser.setCaseSensitive(false);
+			PathPatternRequestMatcher.Builder builder = PathPatternRequestMatcher.withPathPatternParser(parser);
 			// @formatter:off
 			http
 				.authorizeRequests((requests) -> requests
-					.requestMatchers(new AntPathRequestMatcher("/user/{user}", null, false)).access("#user == 'user'")
+					.requestMatchers(builder.matcher("/user/{user}")).access("#user == 'user'")
 					.anyRequest().denyAll());
 			// @formatter:on
 			return http.build();
@@ -261,10 +270,13 @@ public class AuthorizeRequestsTests {
 
 		@Bean
 		SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
+			PathPatternParser parser = new PathPatternParser();
+			parser.setCaseSensitive(false);
+			PathPatternRequestMatcher.Builder builder = PathPatternRequestMatcher.withPathPatternParser(parser);
 			// @formatter:off
 			http
 				.authorizeRequests((requests) -> requests
-					.requestMatchers(new AntPathRequestMatcher("/user/{userName}", null, false)).access("#userName == 'user'")
+					.requestMatchers(builder.matcher("/user/{userName}")).access("#userName == 'user'")
 					.anyRequest().denyAll());
 			// @formatter:on
 			return http.build();
@@ -378,14 +390,18 @@ public class AuthorizeRequestsTests {
 	static class MvcMatcherServletPathConfig {
 
 		@Bean
-		SecurityFilterChain filterChain(HttpSecurity http, HandlerMappingIntrospector introspector) throws Exception {
-			MvcRequestMatcher.Builder mvcMatcherBuilder = new MvcRequestMatcher.Builder(introspector)
-				.servletPath("/spring");
+		PathPatternRequestMatcherBuilderFactoryBean pathPattern() {
+			return new PathPatternRequestMatcherBuilderFactoryBean();
+		}
+
+		@Bean
+		SecurityFilterChain filterChain(HttpSecurity http, PathPatternRequestMatcher.Builder builder) throws Exception {
+			PathPatternRequestMatcher.Builder spring = builder.basePath("/spring");
 			// @formatter:off
 			http
 				.httpBasic(withDefaults())
 				.authorizeRequests((requests) -> requests
-					.requestMatchers(mvcMatcherBuilder.pattern("/path")).denyAll());
+					.requestMatchers(spring.matcher("/path")).denyAll());
 			// @formatter:on
 			return http.build();
 		}
@@ -413,14 +429,18 @@ public class AuthorizeRequestsTests {
 	static class MvcMatcherServletPathInLambdaConfig {
 
 		@Bean
-		SecurityFilterChain filterChain(HttpSecurity http, HandlerMappingIntrospector introspector) throws Exception {
-			MvcRequestMatcher.Builder mvcMatcherBuilder = new MvcRequestMatcher.Builder(introspector)
-				.servletPath("/spring");
+		PathPatternRequestMatcherBuilderFactoryBean pathPattern() {
+			return new PathPatternRequestMatcherBuilderFactoryBean();
+		}
+
+		@Bean
+		SecurityFilterChain filterChain(HttpSecurity http, PathPatternRequestMatcher.Builder builder) throws Exception {
+			PathPatternRequestMatcher.Builder spring = builder.basePath("/spring");
 			// @formatter:off
 			http
 				.httpBasic(withDefaults())
 				.authorizeRequests((authorize) -> authorize
-						.requestMatchers(mvcMatcherBuilder.pattern("/path")).denyAll()
+						.requestMatchers(spring.matcher("/path")).denyAll()
 				);
 			// @formatter:on
 			return http.build();

+ 5 - 5
config/src/test/java/org/springframework/security/config/annotation/web/configurers/CsrfConfigurerIgnoringRequestMatchersTests.java

@@ -28,7 +28,7 @@ import org.springframework.security.config.annotation.web.configuration.EnableWe
 import org.springframework.security.config.test.SpringTestContext;
 import org.springframework.security.config.test.SpringTestContextExtension;
 import org.springframework.security.web.SecurityFilterChain;
-import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
+import org.springframework.security.web.servlet.util.matcher.PathPatternRequestMatcher;
 import org.springframework.security.web.util.matcher.RequestMatcher;
 import org.springframework.test.web.servlet.MockMvc;
 import org.springframework.web.bind.annotation.RequestMapping;
@@ -109,7 +109,7 @@ public class CsrfConfigurerIgnoringRequestMatchersTests {
 			// @formatter:off
 			http
 				.csrf((csrf) -> csrf
-					.requireCsrfProtectionMatcher(new AntPathRequestMatcher("/path"))
+					.requireCsrfProtectionMatcher(PathPatternRequestMatcher.withDefaults().matcher("/path"))
 					.ignoringRequestMatchers(this.requestMatcher));
 			return http.build();
 			// @formatter:on
@@ -129,7 +129,7 @@ public class CsrfConfigurerIgnoringRequestMatchersTests {
 			// @formatter:off
 			http
 				.csrf((csrf) -> csrf
-						.requireCsrfProtectionMatcher(new AntPathRequestMatcher("/path"))
+						.requireCsrfProtectionMatcher(PathPatternRequestMatcher.withDefaults().matcher("/path"))
 						.ignoringRequestMatchers(this.requestMatcher)
 				);
 			return http.build();
@@ -149,7 +149,7 @@ public class CsrfConfigurerIgnoringRequestMatchersTests {
 			// @formatter:off
 			http
 				.csrf((csrf) -> csrf
-					.ignoringRequestMatchers(new AntPathRequestMatcher("/no-csrf"))
+					.ignoringRequestMatchers(PathPatternRequestMatcher.withDefaults().matcher("/no-csrf"))
 					.ignoringRequestMatchers(this.requestMatcher));
 			return http.build();
 			// @formatter:on
@@ -169,7 +169,7 @@ public class CsrfConfigurerIgnoringRequestMatchersTests {
 			// @formatter:off
 			http
 				.csrf((csrf) -> csrf
-						.ignoringRequestMatchers(new AntPathRequestMatcher("/no-csrf"))
+						.ignoringRequestMatchers(PathPatternRequestMatcher.withDefaults().matcher("/no-csrf"))
 						.ignoringRequestMatchers(this.requestMatcher)
 				);
 			return http.build();

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

@@ -57,7 +57,7 @@ import org.springframework.security.web.csrf.XorCsrfTokenRequestAttributeHandler
 import org.springframework.security.web.firewall.StrictHttpFirewall;
 import org.springframework.security.web.savedrequest.HttpSessionRequestCache;
 import org.springframework.security.web.savedrequest.RequestCache;
-import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
+import org.springframework.security.web.servlet.util.matcher.PathPatternRequestMatcher;
 import org.springframework.security.web.util.matcher.RequestMatcher;
 import org.springframework.test.web.servlet.MockMvc;
 import org.springframework.test.web.servlet.MvcResult;
@@ -906,7 +906,7 @@ public class CsrfConfigurerTests {
 			http
 				.formLogin(withDefaults())
 				.logout((logout) -> logout
-					.logoutRequestMatcher(new AntPathRequestMatcher("/logout")));
+					.logoutRequestMatcher(PathPatternRequestMatcher.withDefaults().matcher("/logout")));
 			return http.build();
 			// @formatter:on
 		}

+ 1 - 2
config/src/test/java/org/springframework/security/config/annotation/web/configurers/DefaultFiltersTests.java

@@ -128,8 +128,7 @@ public class DefaultFiltersTests {
 	public void defaultFiltersPermitAll() throws IOException, ServletException {
 		this.spring.register(DefaultFiltersConfigPermitAll.class, UserDetailsServiceConfig.class);
 		MockHttpServletResponse response = new MockHttpServletResponse();
-		MockHttpServletRequest request = new MockHttpServletRequest("POST", "");
-		request.setServletPath("/logout");
+		MockHttpServletRequest request = new MockHttpServletRequest("POST", "/logout");
 		CsrfToken csrfToken = new DefaultCsrfToken("X-CSRF-TOKEN", "_csrf", "BaseSpringSpec_CSRFTOKEN");
 		CsrfTokenRepository repository = new HttpSessionCsrfTokenRepository();
 		repository.saveToken(csrfToken, request, response);

+ 4 - 4
config/src/test/java/org/springframework/security/config/annotation/web/configurers/ExceptionHandlingConfigurerAccessDeniedHandlerTests.java

@@ -32,7 +32,7 @@ import org.springframework.security.test.context.support.WithMockUser;
 import org.springframework.security.web.SecurityFilterChain;
 import org.springframework.security.web.access.AccessDeniedHandler;
 import org.springframework.security.web.access.AccessDeniedHandlerImpl;
-import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
+import org.springframework.security.web.servlet.util.matcher.PathPatternRequestMatcher;
 import org.springframework.security.web.util.matcher.AnyRequestMatcher;
 import org.springframework.test.context.junit.jupiter.SpringExtension;
 import org.springframework.test.web.servlet.MockMvc;
@@ -92,7 +92,7 @@ public class ExceptionHandlingConfigurerAccessDeniedHandlerTests {
 				.exceptionHandling((handling) -> handling
 					.defaultAccessDeniedHandlerFor(
 						this.teapotDeniedHandler,
-						new AntPathRequestMatcher("/hello/**"))
+						PathPatternRequestMatcher.withDefaults().matcher("/hello/**"))
 					.defaultAccessDeniedHandlerFor(
 						new AccessDeniedHandlerImpl(),
 						AnyRequestMatcher.INSTANCE));
@@ -119,7 +119,7 @@ public class ExceptionHandlingConfigurerAccessDeniedHandlerTests {
 				.exceptionHandling((exceptionHandling) -> exceptionHandling
 						.defaultAccessDeniedHandlerFor(
 								this.teapotDeniedHandler,
-								new AntPathRequestMatcher("/hello/**")
+								PathPatternRequestMatcher.withDefaults().matcher("/hello/**")
 						)
 						.defaultAccessDeniedHandlerFor(
 								new AccessDeniedHandlerImpl(),
@@ -148,7 +148,7 @@ public class ExceptionHandlingConfigurerAccessDeniedHandlerTests {
 				.exceptionHandling((handling) -> handling
 					.defaultAccessDeniedHandlerFor(
 						this.teapotDeniedHandler,
-						new AntPathRequestMatcher("/hello/**")));
+						PathPatternRequestMatcher.withDefaults().matcher("/hello/**")));
 			return http.build();
 			// @formatter:on
 		}

+ 59 - 32
config/src/test/java/org/springframework/security/config/annotation/web/configurers/HttpSecurityRequestMatchersTests.java

@@ -32,16 +32,16 @@ import org.springframework.mock.web.MockHttpServletResponse;
 import org.springframework.mock.web.MockServletContext;
 import org.springframework.security.config.annotation.web.builders.HttpSecurity;
 import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
+import org.springframework.security.config.web.PathPatternRequestMatcherBuilderFactoryBean;
 import org.springframework.security.core.userdetails.UserDetailsService;
 import org.springframework.security.provisioning.InMemoryUserDetailsManager;
 import org.springframework.security.web.FilterChainProxy;
 import org.springframework.security.web.SecurityFilterChain;
-import org.springframework.security.web.servlet.util.matcher.MvcRequestMatcher;
+import org.springframework.security.web.servlet.util.matcher.PathPatternRequestMatcher;
 import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.RestController;
 import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
 import org.springframework.web.servlet.config.annotation.EnableWebMvc;
-import org.springframework.web.servlet.handler.HandlerMappingIntrospector;
 
 import static org.assertj.core.api.Assertions.assertThat;
 import static org.springframework.security.config.Customizer.withDefaults;
@@ -167,16 +167,20 @@ public class HttpSecurityRequestMatchersTests {
 	@EnableWebMvc
 	static class MultiMvcMatcherInLambdaConfig {
 
+		@Bean
+		PathPatternRequestMatcherBuilderFactoryBean pathPattern() {
+			return new PathPatternRequestMatcherBuilderFactoryBean();
+		}
+
 		@Bean
 		@Order(Ordered.HIGHEST_PRECEDENCE)
-		SecurityFilterChain first(HttpSecurity http, HandlerMappingIntrospector introspector) throws Exception {
-			MvcRequestMatcher.Builder mvcMatcherBuilder = new MvcRequestMatcher.Builder(introspector);
+		SecurityFilterChain first(HttpSecurity http, PathPatternRequestMatcher.Builder builder) throws Exception {
 			// @formatter:off
 			http
 				.securityMatchers((requests) -> requests
-					.requestMatchers(mvcMatcherBuilder.pattern("/test-1"))
-					.requestMatchers(mvcMatcherBuilder.pattern("/test-2"))
-					.requestMatchers(mvcMatcherBuilder.pattern("/test-3"))
+					.requestMatchers(builder.matcher("/test-1"))
+					.requestMatchers(builder.matcher("/test-2"))
+					.requestMatchers(builder.matcher("/test-3"))
 				)
 				.authorizeRequests((authorize) -> authorize.anyRequest().denyAll())
 				.httpBasic(withDefaults());
@@ -185,12 +189,11 @@ public class HttpSecurityRequestMatchersTests {
 		}
 
 		@Bean
-		SecurityFilterChain second(HttpSecurity http, HandlerMappingIntrospector introspector) throws Exception {
-			MvcRequestMatcher.Builder mvcMatcherBuilder = new MvcRequestMatcher.Builder(introspector);
+		SecurityFilterChain second(HttpSecurity http, PathPatternRequestMatcher.Builder builder) throws Exception {
 			// @formatter:off
 			http
 				.securityMatchers((requests) -> requests
-					.requestMatchers(mvcMatcherBuilder.pattern("/test-1"))
+					.requestMatchers(builder.matcher("/test-1"))
 				)
 				.authorizeRequests((authorize) -> authorize
 					.anyRequest().permitAll()
@@ -216,16 +219,20 @@ public class HttpSecurityRequestMatchersTests {
 	@EnableWebMvc
 	static class MultiMvcMatcherConfig {
 
+		@Bean
+		PathPatternRequestMatcherBuilderFactoryBean pathPattern() {
+			return new PathPatternRequestMatcherBuilderFactoryBean();
+		}
+
 		@Bean
 		@Order(Ordered.HIGHEST_PRECEDENCE)
-		SecurityFilterChain first(HttpSecurity http, HandlerMappingIntrospector introspector) throws Exception {
-			MvcRequestMatcher.Builder mvcMatcherBuilder = new MvcRequestMatcher.Builder(introspector);
+		SecurityFilterChain first(HttpSecurity http, PathPatternRequestMatcher.Builder builder) throws Exception {
 			// @formatter:off
 			http
 				.securityMatchers((security) -> security
-					.requestMatchers(mvcMatcherBuilder.pattern("/test-1"))
-					.requestMatchers(mvcMatcherBuilder.pattern("/test-2"))
-					.requestMatchers(mvcMatcherBuilder.pattern("/test-3")))
+					.requestMatchers(builder.matcher("/test-1"))
+					.requestMatchers(builder.matcher("/test-2"))
+					.requestMatchers(builder.matcher("/test-3")))
 				.authorizeRequests((requests) -> requests
 					.anyRequest().denyAll())
 				.httpBasic(withDefaults());
@@ -234,12 +241,11 @@ public class HttpSecurityRequestMatchersTests {
 		}
 
 		@Bean
-		SecurityFilterChain second(HttpSecurity http, HandlerMappingIntrospector introspector) throws Exception {
-			MvcRequestMatcher.Builder mvcMatcherBuilder = new MvcRequestMatcher.Builder(introspector);
+		SecurityFilterChain second(HttpSecurity http, PathPatternRequestMatcher.Builder builder) throws Exception {
 			// @formatter:off
 			http
 				.securityMatchers((security) -> security
-					.requestMatchers(mvcMatcherBuilder.pattern("/test-1")))
+					.requestMatchers(builder.matcher("/test-1")))
 				.authorizeRequests((requests) -> requests
 					.anyRequest().permitAll());
 			// @formatter:on
@@ -264,10 +270,15 @@ public class HttpSecurityRequestMatchersTests {
 	static class MvcMatcherConfig {
 
 		@Bean
-		SecurityFilterChain filterChain(HttpSecurity http, HandlerMappingIntrospector introspector) throws Exception {
+		PathPatternRequestMatcherBuilderFactoryBean pathPattern() {
+			return new PathPatternRequestMatcherBuilderFactoryBean();
+		}
+
+		@Bean
+		SecurityFilterChain filterChain(HttpSecurity http, PathPatternRequestMatcher.Builder builder) throws Exception {
 			// @formatter:off
 			http
-				.securityMatcher(new MvcRequestMatcher(introspector, "/path"))
+				.securityMatcher(builder.matcher("/path"))
 				.httpBasic(withDefaults())
 				.authorizeRequests((requests) -> requests
 					.anyRequest().denyAll());
@@ -298,11 +309,16 @@ public class HttpSecurityRequestMatchersTests {
 	static class RequestMatchersMvcMatcherConfig {
 
 		@Bean
-		SecurityFilterChain filterChain(HttpSecurity http, HandlerMappingIntrospector introspector) throws Exception {
+		PathPatternRequestMatcherBuilderFactoryBean pathPattern() {
+			return new PathPatternRequestMatcherBuilderFactoryBean();
+		}
+
+		@Bean
+		SecurityFilterChain filterChain(HttpSecurity http, PathPatternRequestMatcher.Builder builder) throws Exception {
 			// @formatter:off
 			http
 				.securityMatchers((security) -> security
-					.requestMatchers(new MvcRequestMatcher(introspector, "/path")))
+					.requestMatchers(builder.matcher("/path")))
 				.httpBasic(withDefaults())
 				.authorizeRequests((requests) -> requests
 					.anyRequest().denyAll());
@@ -333,11 +349,16 @@ public class HttpSecurityRequestMatchersTests {
 	static class RequestMatchersMvcMatcherInLambdaConfig {
 
 		@Bean
-		SecurityFilterChain filterChain(HttpSecurity http, HandlerMappingIntrospector introspector) throws Exception {
+		PathPatternRequestMatcherBuilderFactoryBean pathPattern() {
+			return new PathPatternRequestMatcherBuilderFactoryBean();
+		}
+
+		@Bean
+		SecurityFilterChain filterChain(HttpSecurity http, PathPatternRequestMatcher.Builder builder) throws Exception {
 			// @formatter:off
 			http
 				.securityMatchers((secure) -> secure
-						.requestMatchers(new MvcRequestMatcher(introspector, "/path"))
+						.requestMatchers(builder.matcher("/path"))
 				)
 				.httpBasic(withDefaults())
 				.authorizeRequests((authorize) -> authorize
@@ -365,13 +386,16 @@ public class HttpSecurityRequestMatchersTests {
 	static class RequestMatchersMvcMatcherServeltPathConfig {
 
 		@Bean
-		SecurityFilterChain filterChain(HttpSecurity http, HandlerMappingIntrospector introspector) throws Exception {
-			MvcRequestMatcher.Builder mvcMatcherBuilder = new MvcRequestMatcher.Builder(introspector);
-			mvcMatcherBuilder.servletPath("/spring");
+		PathPatternRequestMatcherBuilderFactoryBean pathPattern() {
+			return new PathPatternRequestMatcherBuilderFactoryBean();
+		}
+
+		@Bean
+		SecurityFilterChain filterChain(HttpSecurity http, PathPatternRequestMatcher.Builder builder) throws Exception {
 			// @formatter:off
 			http
 				.securityMatchers((security) -> security
-					.requestMatchers(mvcMatcherBuilder.pattern("/path"))
+					.requestMatchers(builder.basePath("/spring").matcher("/path"))
 					.requestMatchers("/never-match"))
 				.httpBasic(withDefaults())
 				.authorizeRequests((requests) -> requests
@@ -403,13 +427,16 @@ public class HttpSecurityRequestMatchersTests {
 	static class RequestMatchersMvcMatcherServletPathInLambdaConfig {
 
 		@Bean
-		SecurityFilterChain filterChain(HttpSecurity http, HandlerMappingIntrospector introspector) throws Exception {
-			MvcRequestMatcher.Builder mvcMatcherBuilder = new MvcRequestMatcher.Builder(introspector);
-			mvcMatcherBuilder.servletPath("/spring");
+		PathPatternRequestMatcherBuilderFactoryBean pathPattern() {
+			return new PathPatternRequestMatcherBuilderFactoryBean();
+		}
+
+		@Bean
+		SecurityFilterChain filterChain(HttpSecurity http, PathPatternRequestMatcher.Builder builder) throws Exception {
 			// @formatter:off
 			http
 				.securityMatchers((secure) -> secure
-						.requestMatchers(mvcMatcherBuilder.pattern("/path"))
+						.requestMatchers(builder.basePath("/spring").matcher("/path"))
 						.requestMatchers("/never-match")
 				)
 				.httpBasic(withDefaults())

+ 2 - 2
config/src/test/java/org/springframework/security/config/annotation/web/configurers/HttpSecuritySecurityMatchersNoMvcTests.java

@@ -37,7 +37,7 @@ import org.springframework.security.test.support.ClassPathExclusions;
 import org.springframework.security.web.DefaultSecurityFilterChain;
 import org.springframework.security.web.FilterChainProxy;
 import org.springframework.security.web.SecurityFilterChain;
-import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
+import org.springframework.security.web.servlet.util.matcher.PathPatternRequestMatcher;
 import org.springframework.security.web.util.matcher.RequestMatcher;
 import org.springframework.test.util.ReflectionTestUtils;
 import org.springframework.web.bind.annotation.RequestMapping;
@@ -101,7 +101,7 @@ public class HttpSecuritySecurityMatchersNoMvcTests {
 			.findFirst()
 			.get();
 		assertThat(this.response.getStatus()).isEqualTo(HttpServletResponse.SC_OK);
-		assertThat(requestMatchers).hasOnlyElementsOfType(AntPathRequestMatcher.class);
+		assertThat(requestMatchers).hasOnlyElementsOfType(PathPatternRequestMatcher.class);
 	}
 
 	public void loadConfig(Class<?>... configs) {

+ 20 - 12
config/src/test/java/org/springframework/security/config/annotation/web/configurers/HttpSecuritySecurityMatchersTests.java

@@ -32,6 +32,7 @@ import org.springframework.mock.web.MockHttpServletRequest;
 import org.springframework.mock.web.MockHttpServletResponse;
 import org.springframework.security.config.annotation.web.builders.HttpSecurity;
 import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
+import org.springframework.security.config.web.PathPatternRequestMatcherBuilderFactoryBean;
 import org.springframework.security.core.userdetails.User;
 import org.springframework.security.core.userdetails.UserDetails;
 import org.springframework.security.core.userdetails.UserDetailsService;
@@ -39,12 +40,11 @@ import org.springframework.security.provisioning.InMemoryUserDetailsManager;
 import org.springframework.security.web.FilterChainProxy;
 import org.springframework.security.web.SecurityFilterChain;
 import org.springframework.security.web.servlet.MockServletContext;
-import org.springframework.security.web.servlet.util.matcher.MvcRequestMatcher;
+import org.springframework.security.web.servlet.util.matcher.PathPatternRequestMatcher;
 import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.RestController;
 import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
 import org.springframework.web.servlet.config.annotation.EnableWebMvc;
-import org.springframework.web.servlet.handler.HandlerMappingIntrospector;
 
 import static org.assertj.core.api.Assertions.assertThat;
 import static org.springframework.security.config.Customizer.withDefaults;
@@ -356,14 +356,18 @@ public class HttpSecuritySecurityMatchersTests {
 	static class SecurityMatchersMvcMatcherServletPathConfig {
 
 		@Bean
-		SecurityFilterChain appSecurity(HttpSecurity http, HandlerMappingIntrospector introspector) throws Exception {
-			MvcRequestMatcher.Builder mvcMatcherBuilder = new MvcRequestMatcher.Builder(introspector)
-				.servletPath("/spring");
+		PathPatternRequestMatcherBuilderFactoryBean pathPattern() {
+			return new PathPatternRequestMatcherBuilderFactoryBean();
+		}
+
+		@Bean
+		SecurityFilterChain appSecurity(HttpSecurity http, PathPatternRequestMatcher.Builder builder) throws Exception {
+			PathPatternRequestMatcher.Builder spring = builder.basePath("/spring");
 			// @formatter:off
 			http
 				.securityMatchers((security) -> security
-					.requestMatchers(mvcMatcherBuilder.pattern("/path"))
-					.requestMatchers(mvcMatcherBuilder.pattern("/never-match"))
+					.requestMatchers(spring.matcher("/path"))
+					.requestMatchers(spring.matcher("/never-match"))
 				)
 				.httpBasic(withDefaults())
 				.authorizeHttpRequests((authorize) -> authorize
@@ -391,14 +395,18 @@ public class HttpSecuritySecurityMatchersTests {
 	static class SecurityMatchersMvcMatcherServletPathInLambdaConfig {
 
 		@Bean
-		SecurityFilterChain appSecurity(HttpSecurity http, HandlerMappingIntrospector introspector) throws Exception {
-			MvcRequestMatcher.Builder mvcMatcherBuilder = new MvcRequestMatcher.Builder(introspector)
-				.servletPath("/spring");
+		PathPatternRequestMatcherBuilderFactoryBean pathPattern() {
+			return new PathPatternRequestMatcherBuilderFactoryBean();
+		}
+
+		@Bean
+		SecurityFilterChain appSecurity(HttpSecurity http, PathPatternRequestMatcher.Builder builder) throws Exception {
+			PathPatternRequestMatcher.Builder spring = builder.basePath("/spring");
 			// @formatter:off
 			http
 				.securityMatchers((matchers) -> matchers
-					.requestMatchers(mvcMatcherBuilder.pattern("/path"))
-					.requestMatchers(mvcMatcherBuilder.pattern("/never-match"))
+					.requestMatchers(spring.matcher("/path"))
+					.requestMatchers(spring.matcher("/never-match"))
 				)
 				.httpBasic(withDefaults())
 				.authorizeHttpRequests((authorize) -> authorize

+ 1 - 2
config/src/test/java/org/springframework/security/config/annotation/web/configurers/NamespaceRememberMeTests.java

@@ -43,7 +43,6 @@ import org.springframework.security.web.authentication.RememberMeServices;
 import org.springframework.security.web.authentication.rememberme.AbstractRememberMeServices;
 import org.springframework.security.web.authentication.rememberme.PersistentRememberMeToken;
 import org.springframework.security.web.authentication.rememberme.PersistentTokenRepository;
-import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
 import org.springframework.test.web.servlet.MockMvc;
 import org.springframework.test.web.servlet.MvcResult;
 import org.springframework.test.web.servlet.request.MockHttpServletRequestBuilder;
@@ -349,7 +348,7 @@ public class NamespaceRememberMeTests {
 		SecurityFilterChain withoutKeyFilterChain(HttpSecurity http) throws Exception {
 			// @formatter:off
 			http
-				.securityMatcher(new AntPathRequestMatcher("/without-key/**"))
+				.securityMatcher("/without-key/**")
 				.authorizeHttpRequests((authorize) -> authorize.anyRequest().authenticated())
 				.formLogin((login) -> login
 					.loginProcessingUrl("/without-key/login"))

+ 5 - 5
config/src/test/java/org/springframework/security/config/annotation/web/configurers/RequestMatcherConfigurerTests.java

@@ -27,7 +27,7 @@ import org.springframework.security.config.annotation.web.configuration.EnableWe
 import org.springframework.security.config.test.SpringTestContext;
 import org.springframework.security.config.test.SpringTestContextExtension;
 import org.springframework.security.web.SecurityFilterChain;
-import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
+import org.springframework.security.web.servlet.util.matcher.PathPatternRequestMatcher;
 import org.springframework.test.web.servlet.MockMvc;
 
 import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
@@ -79,9 +79,9 @@ public class RequestMatcherConfigurerTests {
 			// @formatter:off
 			http
 				.securityMatchers((security) -> security
-					.requestMatchers(new AntPathRequestMatcher("/api/**")))
+					.requestMatchers(PathPatternRequestMatcher.withDefaults().matcher("/api/**")))
 				.securityMatchers((security) -> security
-					.requestMatchers(new AntPathRequestMatcher("/oauth/**")))
+					.requestMatchers(PathPatternRequestMatcher.withDefaults().matcher("/oauth/**")))
 				.authorizeRequests((requests) -> requests
 					.anyRequest().denyAll());
 			return http.build();
@@ -99,10 +99,10 @@ public class RequestMatcherConfigurerTests {
 			// @formatter:off
 			http
 				.securityMatchers((secure) -> secure
-						.requestMatchers(new AntPathRequestMatcher("/api/**"))
+						.requestMatchers(PathPatternRequestMatcher.withDefaults().matcher("/api/**"))
 				)
 				.securityMatchers((securityMatchers) -> securityMatchers
-						.requestMatchers(new AntPathRequestMatcher("/oauth/**"))
+						.requestMatchers(PathPatternRequestMatcher.withDefaults().matcher("/oauth/**"))
 				)
 				.authorizeRequests((authorize) -> authorize
 						.anyRequest().denyAll()

+ 1 - 1
config/src/test/java/org/springframework/security/config/annotation/web/configurers/SessionManagementConfigurerServlet31Tests.java

@@ -78,7 +78,7 @@ public class SessionManagementConfigurerServlet31Tests {
 
 	@Test
 	public void changeSessionIdThenPreserveParameters() throws Exception {
-		MockHttpServletRequest request = new MockHttpServletRequest("GET", "");
+		MockHttpServletRequest request = new MockHttpServletRequest("GET", "/login");
 		String id = request.getSession().getId();
 		request.getSession();
 		request.setServletPath("/login");

+ 17 - 8
config/src/test/java/org/springframework/security/config/annotation/web/configurers/UrlAuthorizationConfigurerTests.java

@@ -33,6 +33,7 @@ import org.springframework.mock.web.MockHttpServletResponse;
 import org.springframework.security.config.Customizer;
 import org.springframework.security.config.annotation.web.builders.HttpSecurity;
 import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
+import org.springframework.security.config.web.PathPatternRequestMatcherBuilderFactoryBean;
 import org.springframework.security.core.userdetails.PasswordEncodedUser;
 import org.springframework.security.core.userdetails.User;
 import org.springframework.security.core.userdetails.UserDetails;
@@ -41,12 +42,11 @@ import org.springframework.security.provisioning.InMemoryUserDetailsManager;
 import org.springframework.security.web.FilterChainProxy;
 import org.springframework.security.web.SecurityFilterChain;
 import org.springframework.security.web.servlet.MockServletContext;
-import org.springframework.security.web.servlet.util.matcher.MvcRequestMatcher;
+import org.springframework.security.web.servlet.util.matcher.PathPatternRequestMatcher;
 import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.RestController;
 import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
 import org.springframework.web.servlet.config.annotation.EnableWebMvc;
-import org.springframework.web.servlet.handler.HandlerMappingIntrospector;
 
 import static org.assertj.core.api.Assertions.assertThat;
 import static org.springframework.security.config.Customizer.withDefaults;
@@ -131,14 +131,19 @@ public class UrlAuthorizationConfigurerTests {
 	@EnableWebMvc
 	static class MvcMatcherConfig {
 
+		@Bean
+		PathPatternRequestMatcherBuilderFactoryBean pathPattern() {
+			return new PathPatternRequestMatcherBuilderFactoryBean();
+		}
+
 		@Bean
 		SecurityFilterChain filterChain(HttpSecurity http, ApplicationContext context,
-				HandlerMappingIntrospector introspector) throws Exception {
+				PathPatternRequestMatcher.Builder builder) throws Exception {
 			// @formatter:off
 			http
 				.httpBasic(withDefaults())
 				.apply(new UrlAuthorizationConfigurer(context)).getRegistry()
-				.requestMatchers(new MvcRequestMatcher(introspector, "/path")).hasRole("ADMIN");
+				.requestMatchers(builder.matcher("/path")).hasRole("ADMIN");
 			// @formatter:on
 			return http.build();
 		}
@@ -165,16 +170,20 @@ public class UrlAuthorizationConfigurerTests {
 	@EnableWebMvc
 	static class MvcMatcherServletPathConfig {
 
+		@Bean
+		PathPatternRequestMatcherBuilderFactoryBean pathPattern() {
+			return new PathPatternRequestMatcherBuilderFactoryBean();
+		}
+
 		@Bean
 		SecurityFilterChain filterChain(HttpSecurity http, ApplicationContext context,
-				HandlerMappingIntrospector introspector) throws Exception {
-			MvcRequestMatcher mvcRequestMatcher = new MvcRequestMatcher(introspector, "/path");
-			mvcRequestMatcher.setServletPath("/spring");
+				PathPatternRequestMatcher.Builder builder) throws Exception {
+			PathPatternRequestMatcher.Builder spring = builder.basePath("/spring");
 			// @formatter:off
 			http
 				.httpBasic(withDefaults())
 				.apply(new UrlAuthorizationConfigurer(context)).getRegistry()
-				.requestMatchers(mvcRequestMatcher).hasRole("ADMIN");
+				.requestMatchers(builder.matcher("/path")).hasRole("ADMIN");
 			// @formatter:on
 			return http.build();
 		}

+ 1 - 1
config/src/test/java/org/springframework/security/config/annotation/web/configurers/oauth2/client/OAuth2LoginConfigurerTests.java

@@ -185,7 +185,7 @@ public class OAuth2LoginConfigurerTests {
 
 	@BeforeEach
 	public void setup() {
-		this.request = new MockHttpServletRequest("GET", "");
+		this.request = new MockHttpServletRequest("GET", "/login/oauth2/code/google");
 		this.request.setServletPath("/login/oauth2/code/google");
 		this.response = new MockHttpServletResponse();
 		this.filterChain = new MockFilterChain();

+ 3 - 2
config/src/test/java/org/springframework/security/config/annotation/web/configurers/saml2/Saml2LogoutConfigurerTests.java

@@ -38,6 +38,7 @@ import org.springframework.context.ConfigurableApplicationContext;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
 import org.springframework.context.annotation.Import;
+import org.springframework.http.HttpMethod;
 import org.springframework.mock.web.MockHttpServletRequest;
 import org.springframework.mock.web.MockHttpServletResponse;
 import org.springframework.mock.web.MockHttpSession;
@@ -76,7 +77,7 @@ import org.springframework.security.web.SecurityFilterChain;
 import org.springframework.security.web.authentication.logout.LogoutFilter;
 import org.springframework.security.web.authentication.logout.LogoutHandler;
 import org.springframework.security.web.authentication.logout.LogoutSuccessHandler;
-import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
+import org.springframework.security.web.servlet.util.matcher.PathPatternRequestMatcher;
 import org.springframework.test.web.servlet.MockMvc;
 import org.springframework.test.web.servlet.MvcResult;
 import org.springframework.test.web.servlet.request.RequestPostProcessor;
@@ -620,7 +621,7 @@ public class Saml2LogoutConfigurerTests {
 				.saml2Logout((saml2) -> saml2.addObjectPostProcessor(new ObjectPostProcessor<LogoutFilter>() {
 					@Override
 					public <O extends LogoutFilter> O postProcess(O filter) {
-						filter.setLogoutRequestMatcher(new AntPathRequestMatcher("/logout", "GET"));
+						filter.setLogoutRequestMatcher(PathPatternRequestMatcher.withDefaults().matcher(HttpMethod.GET, "/logout"));
 						return filter;
 					}
 				}));

+ 0 - 8
config/src/test/java/org/springframework/security/config/aot/hint/WebMvcSecurityConfigurationRuntimeHintsTests.java

@@ -53,12 +53,4 @@ class WebMvcSecurityConfigurationRuntimeHintsTests {
 			.withMemberCategory(MemberCategory.INVOKE_DECLARED_CONSTRUCTORS)).accepts(this.hints);
 	}
 
-	@Test
-	void handlerMappingIntrospectorCacheFilterFactoryBeanHasHints() {
-		assertThat(RuntimeHintsPredicates.reflection()
-			.onType(TypeReference
-				.of("org.springframework.security.config.annotation.web.configuration.WebMvcSecurityConfiguration$HandlerMappingIntrospectorCacheFilterFactoryBean"))
-			.withMemberCategory(MemberCategory.INVOKE_DECLARED_CONSTRUCTORS)).accepts(this.hints);
-	}
-
 }

+ 6 - 5
config/src/test/java/org/springframework/security/config/http/DefaultFilterChainValidatorTests.java

@@ -44,7 +44,7 @@ import org.springframework.security.web.access.intercept.FilterInvocationSecurit
 import org.springframework.security.web.access.intercept.FilterSecurityInterceptor;
 import org.springframework.security.web.authentication.AnonymousAuthenticationFilter;
 import org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint;
-import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
+import org.springframework.security.web.servlet.util.matcher.PathPatternRequestMatcher;
 import org.springframework.security.web.util.matcher.AnyRequestMatcher;
 import org.springframework.test.util.ReflectionTestUtils;
 
@@ -144,12 +144,13 @@ public class DefaultFilterChainValidatorTests {
 
 	@Test
 	void validateWhenSameRequestMatchersArePresentThenUnreachableFilterChainException() {
+		PathPatternRequestMatcher.Builder builder = PathPatternRequestMatcher.withDefaults();
 		AnonymousAuthenticationFilter authenticationFilter = mock(AnonymousAuthenticationFilter.class);
 		ExceptionTranslationFilter exceptionTranslationFilter = mock(ExceptionTranslationFilter.class);
-		SecurityFilterChain chain1 = new DefaultSecurityFilterChain(AntPathRequestMatcher.antMatcher("/api"),
-				authenticationFilter, exceptionTranslationFilter, this.authorizationInterceptor);
-		SecurityFilterChain chain2 = new DefaultSecurityFilterChain(AntPathRequestMatcher.antMatcher("/api"),
-				authenticationFilter, exceptionTranslationFilter, this.authorizationInterceptor);
+		SecurityFilterChain chain1 = new DefaultSecurityFilterChain(builder.matcher("/api"), authenticationFilter,
+				exceptionTranslationFilter, this.authorizationInterceptor);
+		SecurityFilterChain chain2 = new DefaultSecurityFilterChain(builder.matcher("/api"), authenticationFilter,
+				exceptionTranslationFilter, this.authorizationInterceptor);
 		List<SecurityFilterChain> chains = new ArrayList<>();
 		chains.add(chain2);
 		chains.add(chain1);

+ 5 - 8
config/src/test/java/org/springframework/security/config/http/FilterSecurityMetadataSourceBeanDefinitionParserTests.java

@@ -92,12 +92,10 @@ public class FilterSecurityMetadataSourceBeanDefinitionParserTests {
 	public void interceptUrlsSupportPropertyPlaceholders() {
 		System.setProperty("secure.url", "/secure");
 		System.setProperty("secure.role", "ROLE_A");
-		setContext(
-				"<b:bean class=\"org.springframework.web.servlet.handler.HandlerMappingIntrospector\" name=\"mvcHandlerMappingIntrospector\"/>"
-						+ "<b:bean class='org.springframework.beans.factory.config.PropertyPlaceholderConfigurer'/>"
-						+ "<filter-security-metadata-source id='fids' use-expressions='false'>"
-						+ "   <intercept-url pattern='${secure.url}' access='${secure.role}'/>"
-						+ "</filter-security-metadata-source>");
+		setContext("<b:bean class='org.springframework.beans.factory.config.PropertyPlaceholderConfigurer'/>"
+				+ "<filter-security-metadata-source id='fids' use-expressions='false'>"
+				+ "   <intercept-url pattern='${secure.url}' access='${secure.role}'/>"
+				+ "</filter-security-metadata-source>");
 		DefaultFilterInvocationSecurityMetadataSource fids = (DefaultFilterInvocationSecurityMetadataSource) this.appContext
 			.getBean("fids");
 		Collection<ConfigAttribute> cad = fids.getAttributes(createFilterInvocation("/secure", "GET"));
@@ -107,8 +105,7 @@ public class FilterSecurityMetadataSourceBeanDefinitionParserTests {
 	@Test
 	public void parsingWithinFilterSecurityInterceptorIsSuccessful() {
 		// @formatter:off
-		setContext("<b:bean class=\"org.springframework.web.servlet.handler.HandlerMappingIntrospector\" name=\"mvcHandlerMappingIntrospector\"/>" +
-				"<http auto-config='true' use-expressions='false' use-authorization-manager='false'/>"
+		setContext("<http auto-config='true' use-expressions='false' use-authorization-manager='false'/>"
 				+ "<b:bean id='fsi' class='org.springframework.security.web.access.intercept.FilterSecurityInterceptor' autowire='byType'>"
 				+ "   <b:property name='securityMetadataSource'>"
 				+ "       <filter-security-metadata-source use-expressions='false'>"

+ 1 - 1
config/src/test/java/org/springframework/security/config/http/FormLoginConfigTests.java

@@ -72,7 +72,7 @@ public class FormLoginConfigTests {
 
 	@Test
 	public void getProtectedPageWhenFormLoginConfiguredThenRedirectsToDefaultLoginPage() throws Exception {
-		this.spring.configLocations(this.xml("WithAntRequestMatcher")).autowire();
+		this.spring.configLocations(this.xml("WithRequestMatcher")).autowire();
 		// @formatter:off
 		this.mvc.perform(get("/"))
 				.andExpect(redirectedUrl("http://localhost/login"));

+ 0 - 65
config/src/test/java/org/springframework/security/config/http/InterceptUrlConfigTests.java

@@ -25,7 +25,6 @@ import org.junit.jupiter.api.Test;
 import org.junit.jupiter.api.extension.ExtendWith;
 import org.mockito.stubbing.Answer;
 
-import org.springframework.beans.factory.BeanCreationException;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.parsing.BeanDefinitionParsingException;
 import org.springframework.mock.web.MockServletContext;
@@ -38,7 +37,6 @@ import org.springframework.web.bind.annotation.GetMapping;
 import org.springframework.web.bind.annotation.PathVariable;
 import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.RestController;
-import org.springframework.web.context.ConfigurableWebApplicationContext;
 import org.springframework.web.util.WebUtils;
 
 import static org.assertj.core.api.Assertions.assertThat;
@@ -250,21 +248,6 @@ public class InterceptUrlConfigTests {
 		assertThat(this.spring.getContext().getBean(AuthorizationManager.class)).isNotNull();
 	}
 
-	@Test
-	public void requestWhenUsingMvcMatchersThenAuthorizesRequestsAccordingly() throws Exception {
-		this.spring.configLocations(this.xml("MvcMatchers")).autowire();
-		this.mvc.perform(get("/path")).andExpect(status().isUnauthorized());
-	}
-
-	@Test
-	public void requestWhenUsingMvcMatchersAndAuthorizationManagerThenAuthorizesRequestsAccordingly() throws Exception {
-		this.spring.configLocations(this.xml("MvcMatchersAuthorizationManager")).autowire();
-		this.mvc.perform(get("/path")).andExpect(status().isUnauthorized());
-		this.mvc.perform(get("/path.html")).andExpect(status().isUnauthorized());
-		this.mvc.perform(get("/path/")).andExpect(status().isUnauthorized());
-		assertThat(this.spring.getContext().getBean(AuthorizationManager.class)).isNotNull();
-	}
-
 	@Test
 	public void requestWhenUsingMvcMatchersAndPathVariablesThenAuthorizesRequestsAccordingly() throws Exception {
 		this.spring.configLocations(this.xml("MvcMatchersPathVariables")).autowire();
@@ -293,48 +276,6 @@ public class InterceptUrlConfigTests {
 		assertThat(this.spring.getContext().getBean(AuthorizationManager.class)).isNotNull();
 	}
 
-	@Test
-	public void requestWhenUsingMvcMatchersAndServletPathThenAuthorizesRequestsAccordingly() throws Exception {
-		this.spring.configLocations(this.xml("MvcMatchersServletPath")).autowire();
-		MockServletContext servletContext = mockServletContext("/spring");
-		ConfigurableWebApplicationContext context = this.spring.getContext();
-		context.setServletContext(servletContext);
-		// @formatter:off
-		this.mvc.perform(get("/spring/path").servletPath("/spring"))
-				.andExpect(status().isUnauthorized());
-		// @formatter:on
-	}
-
-	@Test
-	public void requestWhenUsingMvcMatchersAndServletPathAndAuthorizationManagerThenAuthorizesRequestsAccordingly()
-			throws Exception {
-		this.spring.configLocations(this.xml("MvcMatchersServletPathAuthorizationManager")).autowire();
-		MockServletContext servletContext = mockServletContext("/spring");
-		ConfigurableWebApplicationContext context = this.spring.getContext();
-		context.setServletContext(servletContext);
-		// @formatter:off
-		this.mvc.perform(get("/spring/path").servletPath("/spring"))
-				.andExpect(status().isUnauthorized());
-		this.mvc.perform(get("/spring/path.html").servletPath("/spring"))
-				.andExpect(status().isUnauthorized());
-		this.mvc.perform(get("/spring/path/").servletPath("/spring"))
-				.andExpect(status().isUnauthorized());
-		// @formatter:on
-		assertThat(this.spring.getContext().getBean(AuthorizationManager.class)).isNotNull();
-	}
-
-	@Test
-	public void configureWhenUsingAntMatcherAndServletPathThenThrowsException() {
-		assertThatExceptionOfType(BeanDefinitionParsingException.class)
-			.isThrownBy(() -> this.spring.configLocations(this.xml("AntMatcherServletPath")).autowire());
-	}
-
-	@Test
-	public void configureWhenUsingAntMatcherAndServletPathAndAuthorizationManagerThenThrowsException() {
-		assertThatExceptionOfType(BeanDefinitionParsingException.class).isThrownBy(
-				() -> this.spring.configLocations(this.xml("AntMatcherServletPathAuthorizationManager")).autowire());
-	}
-
 	@Test
 	public void configureWhenUsingRegexMatcherAndServletPathThenThrowsException() {
 		assertThatExceptionOfType(BeanDefinitionParsingException.class)
@@ -366,12 +307,6 @@ public class InterceptUrlConfigTests {
 			.isThrownBy(() -> this.spring.configLocations(this.xml("DefaultMatcherServletPath")).autowire());
 	}
 
-	@Test
-	public void configureWhenUsingDefaultMatcherAndNoIntrospectorBeanThenException() {
-		assertThatExceptionOfType(BeanCreationException.class)
-			.isThrownBy(() -> this.spring.configLocations(this.xml("DefaultMatcherNoIntrospectorBean")).autowire());
-	}
-
 	@Test
 	public void configureWhenUsingDefaultMatcherAndServletPathAndAuthorizationManagerThenNoException() {
 		assertThatNoException()

+ 2 - 2
config/src/test/java/org/springframework/security/config/http/customconfigurer/CustomConfigurer.java

@@ -22,7 +22,7 @@ import org.springframework.security.config.annotation.SecurityConfigurerAdapter;
 import org.springframework.security.config.annotation.web.builders.HttpSecurity;
 import org.springframework.security.config.annotation.web.configurers.FormLoginConfigurer;
 import org.springframework.security.web.DefaultSecurityFilterChain;
-import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
+import org.springframework.security.web.servlet.util.matcher.PathPatternRequestMatcher;
 
 /**
  * @author Rob Winch
@@ -44,7 +44,7 @@ public class CustomConfigurer extends SecurityConfigurerAdapter<DefaultSecurityF
 		// @formatter:off
 		http
 			.authorizeRequests((requests) -> requests
-				.requestMatchers(new AntPathRequestMatcher(this.permitAllPattern)).permitAll()
+				.requestMatchers(PathPatternRequestMatcher.withDefaults().matcher(this.permitAllPattern)).permitAll()
 				.anyRequest().authenticated());
 		// @formatter:on
 		if (http.getConfigurer(FormLoginConfigurer.class) == null) {

+ 5 - 5
config/src/test/kotlin/org/springframework/security/config/annotation/web/CsrfDslTests.kt

@@ -43,7 +43,7 @@ import org.springframework.security.web.csrf.CsrfTokenRequestAttributeHandler
 import org.springframework.security.web.csrf.CsrfTokenRequestHandler
 import org.springframework.security.web.csrf.DefaultCsrfToken
 import org.springframework.security.web.csrf.HttpSessionCsrfTokenRepository
-import org.springframework.security.web.util.matcher.AntPathRequestMatcher
+import org.springframework.security.web.servlet.util.matcher.PathPatternRequestMatcher
 import org.springframework.test.web.servlet.MockMvc
 import org.springframework.test.web.servlet.get
 import org.springframework.test.web.servlet.post
@@ -176,7 +176,7 @@ class CsrfDslTests {
         open fun securityFilterChain(http: HttpSecurity): SecurityFilterChain {
             http {
                 csrf {
-                    requireCsrfProtectionMatcher = AntPathRequestMatcher("/test1")
+                    requireCsrfProtectionMatcher = PathPatternRequestMatcher.withDefaults().matcher("/test1")
                 }
             }
             return http.build()
@@ -247,8 +247,8 @@ class CsrfDslTests {
         open fun securityFilterChain(http: HttpSecurity): SecurityFilterChain {
             http {
                 csrf {
-                    requireCsrfProtectionMatcher = AntPathRequestMatcher("/**")
-                    ignoringRequestMatchers(AntPathRequestMatcher("/test2"))
+                    requireCsrfProtectionMatcher = PathPatternRequestMatcher.withDefaults().matcher("/**")
+                    ignoringRequestMatchers(PathPatternRequestMatcher.withDefaults().matcher("/test2"))
                 }
             }
             return http.build()
@@ -279,7 +279,7 @@ class CsrfDslTests {
         open fun filterChain(http: HttpSecurity): SecurityFilterChain {
             http {
                 csrf {
-                    requireCsrfProtectionMatcher = AntPathRequestMatcher("/**")
+                    requireCsrfProtectionMatcher = PathPatternRequestMatcher.withDefaults().matcher("/**")
                     ignoringRequestMatchers("/test2")
                 }
             }

+ 7 - 5
config/src/test/kotlin/org/springframework/security/config/annotation/web/ExceptionHandlingDslTests.kt

@@ -32,7 +32,7 @@ import org.springframework.security.test.web.servlet.request.SecurityMockMvcRequ
 import org.springframework.security.web.SecurityFilterChain
 import org.springframework.security.web.access.AccessDeniedHandlerImpl
 import org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint
-import org.springframework.security.web.util.matcher.AntPathRequestMatcher
+import org.springframework.security.web.servlet.util.matcher.PathPatternRequestMatcher
 import org.springframework.test.web.servlet.MockMvc
 import org.springframework.test.web.servlet.get
 import org.springframework.web.servlet.config.annotation.EnableWebMvc
@@ -195,6 +195,7 @@ class ExceptionHandlingDslTests {
             customAccessDeniedHandler1.setErrorPage("/access-denied1")
             val customAccessDeniedHandler2 = AccessDeniedHandlerImpl()
             customAccessDeniedHandler2.setErrorPage("/access-denied2")
+            val builder = PathPatternRequestMatcher.withDefaults()
             http {
                 authorizeRequests {
                     authorize("/admin1", hasAuthority("ROLE_ADMIN"))
@@ -202,8 +203,8 @@ class ExceptionHandlingDslTests {
                     authorize(anyRequest, authenticated)
                 }
                 exceptionHandling {
-                    defaultAccessDeniedHandlerFor(customAccessDeniedHandler1, AntPathRequestMatcher("/admin1"))
-                    defaultAccessDeniedHandlerFor(customAccessDeniedHandler2, AntPathRequestMatcher("/admin2"))
+                    defaultAccessDeniedHandlerFor(customAccessDeniedHandler1, builder.matcher("/admin1"))
+                    defaultAccessDeniedHandlerFor(customAccessDeniedHandler2, builder.matcher("/admin2"))
                 }
             }
             return http.build()
@@ -264,13 +265,14 @@ class ExceptionHandlingDslTests {
         open fun securityFilterChain(http: HttpSecurity): SecurityFilterChain {
             val customAuthenticationEntryPoint1 = LoginUrlAuthenticationEntryPoint("/custom-login1")
             val customAuthenticationEntryPoint2 = LoginUrlAuthenticationEntryPoint("/custom-login2")
+            val builder = PathPatternRequestMatcher.withDefaults();
             http {
                 authorizeRequests {
                     authorize(anyRequest, authenticated)
                 }
                 exceptionHandling {
-                    defaultAuthenticationEntryPointFor(customAuthenticationEntryPoint1, AntPathRequestMatcher("/secured1"))
-                    defaultAuthenticationEntryPointFor(customAuthenticationEntryPoint2, AntPathRequestMatcher("/secured2"))
+                    defaultAuthenticationEntryPointFor(customAuthenticationEntryPoint1, builder.matcher("/secured1"))
+                    defaultAuthenticationEntryPointFor(customAuthenticationEntryPoint2, builder.matcher("/secured2"))
                 }
             }
             return http.build()

+ 4 - 4
config/src/test/kotlin/org/springframework/security/config/annotation/web/LogoutDslTests.kt

@@ -40,7 +40,7 @@ import org.springframework.security.web.SecurityFilterChain
 import org.springframework.security.web.authentication.logout.LogoutHandler
 import org.springframework.security.web.authentication.logout.SimpleUrlLogoutSuccessHandler
 import org.springframework.security.web.context.HttpSessionSecurityContextRepository
-import org.springframework.security.web.util.matcher.AntPathRequestMatcher
+import org.springframework.security.web.servlet.util.matcher.PathPatternRequestMatcher
 import org.springframework.test.web.servlet.MockMvc
 import org.springframework.test.web.servlet.post
 
@@ -102,7 +102,7 @@ class LogoutDslTests {
         open fun securityFilterChain(http: HttpSecurity): SecurityFilterChain {
             http {
                 logout {
-                    logoutRequestMatcher = AntPathRequestMatcher("/custom/logout")
+                    logoutRequestMatcher = PathPatternRequestMatcher.withDefaults().matcher("/custom/logout")
                 }
             }
             return http.build()
@@ -307,8 +307,8 @@ class LogoutDslTests {
         open fun securityFilterChain(http: HttpSecurity): SecurityFilterChain {
             http {
                 logout {
-                    logoutRequestMatcher = AntPathRequestMatcher("/logout/**")
-                    defaultLogoutSuccessHandlerFor(SimpleUrlLogoutSuccessHandler(), AntPathRequestMatcher("/logout/custom"))
+                    logoutRequestMatcher = PathPatternRequestMatcher.withDefaults().matcher("/logout/**")
+                    defaultLogoutSuccessHandlerFor(SimpleUrlLogoutSuccessHandler(), PathPatternRequestMatcher.withDefaults().matcher("/logout/custom"))
                 }
             }
             return http.build()

+ 1 - 2
config/src/test/kotlin/org/springframework/security/config/annotation/web/RememberMeDslTests.kt

@@ -51,7 +51,6 @@ import org.springframework.security.web.authentication.RememberMeServices
 import org.springframework.security.web.authentication.SimpleUrlAuthenticationSuccessHandler
 import org.springframework.security.web.authentication.rememberme.AbstractRememberMeServices
 import org.springframework.security.web.authentication.rememberme.PersistentTokenRepository
-import org.springframework.security.web.util.matcher.AntPathRequestMatcher
 import org.springframework.test.web.servlet.MockHttpServletRequestDsl
 import org.springframework.test.web.servlet.MockMvc
 import org.springframework.test.web.servlet.get
@@ -472,7 +471,7 @@ internal class RememberMeDslTests {
         @Order(0)
         open fun securityFilterChainWithoutKey(http: HttpSecurity): SecurityFilterChain {
             http {
-                securityMatcher(AntPathRequestMatcher("/without-key/**"))
+                securityMatcher("/without-key/**")
                 formLogin {
                     loginProcessingUrl = "/without-key/login"
                 }

+ 2 - 2
config/src/test/kotlin/org/springframework/security/config/annotation/web/headers/HttpStrictTransportSecurityDslTests.kt

@@ -29,7 +29,7 @@ import org.springframework.security.config.test.SpringTestContext
 import org.springframework.security.config.test.SpringTestContextExtension
 import org.springframework.security.web.SecurityFilterChain
 import org.springframework.security.web.server.header.StrictTransportSecurityServerHttpHeadersWriter
-import org.springframework.security.web.util.matcher.AntPathRequestMatcher
+import org.springframework.security.web.servlet.util.matcher.PathPatternRequestMatcher
 import org.springframework.test.web.servlet.MockMvc
 import org.springframework.test.web.servlet.get
 
@@ -148,7 +148,7 @@ class HttpStrictTransportSecurityDslTests {
                 headers {
                     defaultsDisabled = true
                     httpStrictTransportSecurity {
-                        requestMatcher = AntPathRequestMatcher("/secure/**")
+                        requestMatcher = PathPatternRequestMatcher.withDefaults().matcher("/secure/**")
                     }
                 }
             }

+ 2 - 2
config/src/test/resources/org/springframework/security/config/http/CsrfBeanDefinitionParserTests-RegisterDataValueProcessorOnyIfNotRegistered.xml

@@ -43,7 +43,7 @@ http://www.springframework.org/schema/security https://www.springframework.org/s
 			</security:user-service>
 		</security:authentication-provider>
 	</security:authentication-manager>
-	
-	<import resource="handlermappingintrospector.xml"/>
+
+	<import resource="pathpatternrequestmatcherbuilder.xml"/>
 
 </beans>

+ 1 - 1
config/src/test/resources/org/springframework/security/config/http/CsrfConfigTests-CsrfEnabled.xml

@@ -30,7 +30,7 @@
 	</http>
 
 	<b:import resource="CsrfConfigTests-shared-userservice.xml"/>
-	<b:import resource="handlermappingintrospector.xml"/>
+	<b:import resource="pathpatternrequestmatcherbuilder.xml"/>
 
 	<b:bean id="firewall" class="org.springframework.security.web.firewall.StrictHttpFirewall"
 			p:unsafeAllowAnyHttpMethod="true"/>

+ 1 - 1
config/src/test/resources/org/springframework/security/config/http/FormLoginConfigTests-WithAntRequestMatcher.xml → config/src/test/resources/org/springframework/security/config/http/FormLoginConfigTests-WithRequestMatcher.xml

@@ -24,7 +24,7 @@
 			http://www.springframework.org/schema/beans
 			https://www.springframework.org/schema/beans/spring-beans.xsd">
 
-	<http auto-config="true" use-expressions="false" request-matcher="ant" use-authorization-manager="false">
+	<http auto-config="true" use-expressions="false" use-authorization-manager="false">
 		<intercept-url pattern="/**" access="ROLE_USER"/>
 		<form-login/>
 	</http>

+ 1 - 1
config/src/test/resources/org/springframework/security/config/http/FormLoginConfigTests-WithSuccessAndFailureHandlers.xml

@@ -24,7 +24,7 @@
 			http://www.springframework.org/schema/beans
 			https://www.springframework.org/schema/beans/spring-beans.xsd">
 
-	<http auto-config="true" use-expressions="false" request-matcher="ant" use-authorization-manager="false">
+	<http auto-config="true" use-expressions="false" use-authorization-manager="false">
 		<intercept-url pattern="/**" access="ROLE_USER"/>
 		<form-login authentication-success-handler-ref="fsh" authentication-failure-handler-ref="fsh"/>
 	</http>

+ 8 - 4
config/src/test/resources/org/springframework/security/config/http/HttpInterceptUrlTests-interceptUrlWhenRequestMatcherRefThenWorks.xml

@@ -16,8 +16,12 @@
 		<user name="user" password="password" authorities="ROLE_USER"/>
 	</user-service>
 
-	<b:bean id="matcherRef" class="org.springframework.security.web.util.matcher.AntPathRequestMatcher"
-		c:pattern="/foo"
-		c:httpMethod="GET"
-		c:caseSensitive="false"/>
+	<b:bean id="mvcPatternParser" class="org.springframework.web.util.pattern.PathPatternParser">
+		<b:property name="caseSensitive" value="false"/>
+	</b:bean>
+
+	<b:bean id="builderRef" class="org.springframework.security.config.web.PathPatternRequestMatcherBuilderFactoryBean"/>
+
+	<b:bean id="matcherRef" class="org.springframework.security.config.http.PathPatternRequestMatcherFactoryBean"
+		c:pattern="/foo" c:method="GET"/>
 </b:beans>

+ 4 - 4
config/src/test/resources/org/springframework/security/config/http/InterceptUrlConfigTests-AuthorizationManagerFilterAllDispatcherTypes.xml

@@ -33,15 +33,15 @@
 
 	<b:bean name="path" class="org.springframework.security.config.http.InterceptUrlConfigTests.PathController"/>
 	<b:bean name="error" class="org.springframework.security.config.http.InterceptUrlConfigTests.ErrorController"/>
-	
+
 	<b:bean name="errorRequestMatcher" class="org.springframework.security.web.util.matcher.DispatcherTypeRequestMatcher">
 		<b:constructor-arg value="ERROR"/>
 	</b:bean>
-	
-	<b:bean name="errorPathRequestMatcher" class="org.springframework.security.web.util.matcher.AntPathRequestMatcher">
+
+	<b:bean name="errorPathRequestMatcher" class="org.springframework.security.config.http.PathPatternRequestMatcherFactoryBean">
 		<b:constructor-arg value="/error"/>
 	</b:bean>
-	
+
 	<b:bean name="pathErrorRequestMatcher" class="org.springframework.security.web.util.matcher.AndRequestMatcher">
 		<b:constructor-arg>
 			<b:list>

+ 1 - 1
config/src/test/resources/org/springframework/security/config/http/InterceptUrlConfigTests-CamelCasePathVariables.xml

@@ -33,5 +33,5 @@
 	<b:bean name="path" class="org.springframework.security.config.http.InterceptUrlConfigTests.PathController"/>
 
 	<b:import resource="userservice.xml"/>
-	<b:import resource="handlermappingintrospector.xml"/>
+	<b:import resource="pathpatternrequestmatcherbuilder.xml"/>
 </b:beans>

+ 1 - 1
config/src/test/resources/org/springframework/security/config/http/InterceptUrlConfigTests-CamelCasePathVariablesAuthorizationManager.xml

@@ -33,5 +33,5 @@
 	<b:bean name="path" class="org.springframework.security.config.http.InterceptUrlConfigTests.PathController"/>
 
 	<b:import resource="userservice.xml"/>
-	<b:import resource="handlermappingintrospector.xml"/>
+	<b:import resource="pathpatternrequestmatcherbuilder.xml"/>
 </b:beans>

+ 1 - 1
config/src/test/resources/org/springframework/security/config/http/InterceptUrlConfigTests-DefaultMatcherServletPath.xml

@@ -30,5 +30,5 @@
 	</http>
 
 	<b:import resource="userservice.xml"/>
-	<b:import resource="handlermappingintrospector.xml"/>
+	<b:import resource="pathpatternrequestmatcherbuilder.xml"/>
 </b:beans>

+ 1 - 1
config/src/test/resources/org/springframework/security/config/http/InterceptUrlConfigTests-DefaultMatcherServletPathAuthorizationManager.xml

@@ -30,5 +30,5 @@
 	</http>
 
 	<b:import resource="userservice.xml"/>
-	<b:import resource="handlermappingintrospector.xml"/>
+	<b:import resource="pathpatternrequestmatcherbuilder.xml"/>
 </b:beans>

+ 4 - 4
config/src/test/resources/org/springframework/security/config/http/InterceptUrlConfigTests-FilterAllDispatcherTypesFalse.xml

@@ -33,15 +33,15 @@
 
 	<b:bean name="path" class="org.springframework.security.config.http.InterceptUrlConfigTests.PathController"/>
 	<b:bean name="error" class="org.springframework.security.config.http.InterceptUrlConfigTests.ErrorController"/>
-	
+
 	<b:bean name="errorRequestMatcher" class="org.springframework.security.web.util.matcher.DispatcherTypeRequestMatcher">
 		<b:constructor-arg value="ERROR"/>
 	</b:bean>
-	
-	<b:bean name="errorPathRequestMatcher" class="org.springframework.security.web.util.matcher.AntPathRequestMatcher">
+
+	<b:bean name="errorPathRequestMatcher" class="org.springframework.security.config.http.PathPatternRequestMatcherFactoryBean">
 		<b:constructor-arg value="/error"/>
 	</b:bean>
-	
+
 	<b:bean name="pathErrorRequestMatcher" class="org.springframework.security.web.util.matcher.AndRequestMatcher">
 		<b:constructor-arg>
 			<b:list>

+ 1 - 1
config/src/test/resources/org/springframework/security/config/http/InterceptUrlConfigTests-PatchMethod.xml

@@ -33,5 +33,5 @@
 	<b:bean name="path" class="org.springframework.security.config.http.InterceptUrlConfigTests.PathController"/>
 
 	<b:import resource="userservice.xml"/>
-	<b:import resource="handlermappingintrospector.xml"/>
+	<b:import resource="pathpatternrequestmatcherbuilder.xml"/>
 </b:beans>

+ 1 - 1
config/src/test/resources/org/springframework/security/config/http/InterceptUrlConfigTests-PatchMethodAuthorizationManager.xml

@@ -33,5 +33,5 @@
 	<b:bean name="path" class="org.springframework.security.config.http.InterceptUrlConfigTests.PathController"/>
 
 	<b:import resource="userservice.xml"/>
-	<b:import resource="handlermappingintrospector.xml"/>
+	<b:import resource="pathpatternrequestmatcherbuilder.xml"/>
 </b:beans>

+ 1 - 1
config/src/test/resources/org/springframework/security/config/http/InterceptUrlConfigTests-PathVariables.xml

@@ -33,5 +33,5 @@
 	<b:bean name="path" class="org.springframework.security.config.http.InterceptUrlConfigTests.PathController"/>
 
 	<b:import resource="userservice.xml"/>
-	<b:import resource="handlermappingintrospector.xml"/>
+	<b:import resource="pathpatternrequestmatcherbuilder.xml"/>
 </b:beans>

+ 1 - 1
config/src/test/resources/org/springframework/security/config/http/InterceptUrlConfigTests-PathVariablesAuthorizationManager.xml

@@ -33,5 +33,5 @@
 	<b:bean name="path" class="org.springframework.security.config.http.InterceptUrlConfigTests.PathController"/>
 
 	<b:import resource="userservice.xml"/>
-	<b:import resource="handlermappingintrospector.xml"/>
+	<b:import resource="pathpatternrequestmatcherbuilder.xml"/>
 </b:beans>

+ 1 - 1
config/src/test/resources/org/springframework/security/config/http/InterceptUrlConfigTests-Sec2256.xml

@@ -34,5 +34,5 @@
 	<b:bean name="path" class="org.springframework.security.config.http.InterceptUrlConfigTests.PathController"/>
 
 	<b:import resource="userservice.xml"/>
-	<b:import resource="handlermappingintrospector.xml"/>
+	<b:import resource="pathpatternrequestmatcherbuilder.xml"/>
 </b:beans>

+ 1 - 1
config/src/test/resources/org/springframework/security/config/http/InterceptUrlConfigTests-Sec2256AuthorizationManager.xml

@@ -34,5 +34,5 @@
 	<b:bean name="path" class="org.springframework.security.config.http.InterceptUrlConfigTests.PathController"/>
 
 	<b:import resource="userservice.xml"/>
-	<b:import resource="handlermappingintrospector.xml"/>
+	<b:import resource="pathpatternrequestmatcherbuilder.xml"/>
 </b:beans>

+ 1 - 1
config/src/test/resources/org/springframework/security/config/http/InterceptUrlConfigTests-TypeConversionPathVariables.xml

@@ -34,5 +34,5 @@
 	<b:bean name="id" class="org.springframework.security.config.http.InterceptUrlConfigTests.Id"/>
 
 	<b:import resource="userservice.xml"/>
-	<b:import resource="handlermappingintrospector.xml"/>
+	<b:import resource="pathpatternrequestmatcherbuilder.xml"/>
 </b:beans>

+ 1 - 1
config/src/test/resources/org/springframework/security/config/http/InterceptUrlConfigTests-TypeConversionPathVariablesAuthorizationManager.xml

@@ -34,5 +34,5 @@
 	<b:bean name="id" class="org.springframework.security.config.http.InterceptUrlConfigTests.Id"/>
 
 	<b:import resource="userservice.xml"/>
-	<b:import resource="handlermappingintrospector.xml"/>
+	<b:import resource="pathpatternrequestmatcherbuilder.xml"/>
 </b:beans>

+ 1 - 1
config/src/test/resources/org/springframework/security/config/http/MiscHttpConfigTests-AnonymousDisabled.xml

@@ -32,5 +32,5 @@
 	</http>
 
 	<b:import resource="userservice.xml"/>
-	<b:import resource="handlermappingintrospector.xml"/>
+	<b:import resource="pathpatternrequestmatcherbuilder.xml"/>
 </b:beans>

+ 1 - 1
config/src/test/resources/org/springframework/security/config/http/MiscHttpConfigTests-AnonymousEndpoints.xml

@@ -31,5 +31,5 @@
 	</http>
 
 	<b:import resource="userservice.xml"/>
-	<b:import resource="handlermappingintrospector.xml"/>
+	<b:import resource="pathpatternrequestmatcherbuilder.xml"/>
 </b:beans>

+ 1 - 1
config/src/test/resources/org/springframework/security/config/http/MiscHttpConfigTests-CustomHttpBasicEntryPointRef.xml

@@ -34,5 +34,5 @@
 	</b:bean>
 
 	<b:import resource="userservice.xml"/>
-	<b:import resource="handlermappingintrospector.xml"/>
+	<b:import resource="pathpatternrequestmatcherbuilder.xml"/>
 </b:beans>

+ 1 - 1
config/src/test/resources/org/springframework/security/config/http/MiscHttpConfigTests-CustomRequestMatcher.xml

@@ -32,7 +32,7 @@
 		<http-basic/>
 	</http>
 
-	<b:bean name="matcher" class="org.springframework.security.web.util.matcher.AntPathRequestMatcher">
+	<b:bean name="matcher" class="org.springframework.security.config.http.PathPatternRequestMatcherFactoryBean">
 		<b:constructor-arg value="/unprotected"/>
 	</b:bean>
 

+ 1 - 1
config/src/test/resources/org/springframework/security/config/http/MiscHttpConfigTests-NoSecurityForPattern.xml

@@ -29,5 +29,5 @@
 	<http pattern="/unprotected" security="none"/>
 
 	<b:import resource="userservice.xml"/>
-	<b:import resource="handlermappingintrospector.xml"/>
+	<b:import resource="pathpatternrequestmatcherbuilder.xml"/>
 </b:beans>

+ 1 - 1
config/src/test/resources/org/springframework/security/config/http/MiscHttpConfigTests-OncePerRequest.xml

@@ -31,5 +31,5 @@
 	</http>
 
 	<b:import resource="userservice.xml"/>
-	<b:import resource="handlermappingintrospector.xml"/>
+	<b:import resource="pathpatternrequestmatcherbuilder.xml"/>
 </b:beans>

+ 1 - 1
config/src/test/resources/org/springframework/security/config/http/MiscHttpConfigTests-OncePerRequestTrue.xml

@@ -31,5 +31,5 @@
 	</http>
 
 	<b:import resource="userservice.xml"/>
-	<b:import resource="handlermappingintrospector.xml"/>
+	<b:import resource="pathpatternrequestmatcherbuilder.xml"/>
 </b:beans>

+ 1 - 1
config/src/test/resources/org/springframework/security/config/http/MiscHttpConfigTests-ProtectedLoginPage.xml

@@ -30,5 +30,5 @@
 	</http>
 
 	<b:import resource="userservice.xml"/>
-	<b:import resource="handlermappingintrospector.xml"/>
+	<b:import resource="pathpatternrequestmatcherbuilder.xml"/>
 </b:beans>

+ 1 - 1
config/src/test/resources/org/springframework/security/config/http/MiscHttpConfigTests-ProtectedLoginPageAuthorizationManager.xml

@@ -30,5 +30,5 @@
 	</http>
 
 	<b:import resource="userservice.xml"/>
-	<b:import resource="handlermappingintrospector.xml"/>
+	<b:import resource="pathpatternrequestmatcherbuilder.xml"/>
 </b:beans>

+ 1 - 1
config/src/test/resources/org/springframework/security/config/http/MultiHttpBlockConfigTests-DistinctHttpElements.xml

@@ -35,5 +35,5 @@
 	<b:bean name="basicController" class="org.springframework.security.config.http.MultiHttpBlockConfigTests.BasicController"/>
 
 	<b:import resource="userservice.xml"/>
-	<b:import resource="handlermappingintrospector.xml"/>
+	<b:import resource="pathpatternrequestmatcherbuilder.xml"/>
 </b:beans>

+ 1 - 1
config/src/test/resources/org/springframework/security/config/http/MultiHttpBlockConfigTests-IdenticallyPatternedHttpElements.xml

@@ -33,5 +33,5 @@
 	</http>
 
 	<b:import resource="userservice.xml"/>
-	<b:import resource="handlermappingintrospector.xml"/>
+	<b:import resource="pathpatternrequestmatcherbuilder.xml"/>
 </b:beans>

+ 1 - 1
config/src/test/resources/org/springframework/security/config/http/MultiHttpBlockConfigTests-Sec1937.xml

@@ -50,5 +50,5 @@
 		</authentication-provider>
 	</authentication-manager>
 
-	<b:import resource="handlermappingintrospector.xml"/>
+	<b:import resource="pathpatternrequestmatcherbuilder.xml"/>
 </b:beans>

+ 1 - 1
config/src/test/resources/org/springframework/security/config/http/OAuth2ResourceServerBeanDefinitionParserTests-AuthenticationManagerResolver.xml

@@ -32,5 +32,5 @@
 	</http>
 
 	<b:import resource="userservice.xml"/>
-	<b:import resource="handlermappingintrospector.xml"/>
+	<b:import resource="pathpatternrequestmatcherbuilder.xml"/>
 </b:beans>

+ 1 - 1
config/src/test/resources/org/springframework/security/config/http/OAuth2ResourceServerBeanDefinitionParserTests-BasicAndResourceServer.xml

@@ -33,5 +33,5 @@
 	</http>
 
 	<b:import resource="userservice.xml"/>
-	<b:import resource="handlermappingintrospector.xml"/>
+	<b:import resource="pathpatternrequestmatcherbuilder.xml"/>
 </b:beans>

+ 1 - 1
config/src/test/resources/org/springframework/security/config/http/OAuth2ResourceServerBeanDefinitionParserTests-FormAndResourceServer.xml

@@ -33,5 +33,5 @@
 	</http>
 
 	<b:import resource="userservice.xml"/>
-	<b:import resource="handlermappingintrospector.xml"/>
+	<b:import resource="pathpatternrequestmatcherbuilder.xml"/>
 </b:beans>

+ 1 - 1
config/src/test/resources/org/springframework/security/config/http/OAuth2ResourceServerBeanDefinitionParserTests-JwkSetUri.xml

@@ -39,5 +39,5 @@
 	</http>
 
 	<b:import resource="userservice.xml"/>
-	<b:import resource="handlermappingintrospector.xml"/>
+	<b:import resource="pathpatternrequestmatcherbuilder.xml"/>
 </b:beans>

Nem az összes módosított fájl került megjelenítésre, mert túl sok fájl változott