From de07b1108f185823c0aa1734dee2767b1b4b22a8 Mon Sep 17 00:00:00 2001 From: Josh Cummings <3627351+jzheaux@users.noreply.github.com> Date: Wed, 26 Mar 2025 11:14:50 -0600 Subject: [PATCH] Use PathPatternRequestMatcher in Web Components This commit changes filters and resolvers that were using AntPathRequestMatcher as their default to using PathPatternRequestMatcher. Issue gh-16632 --- .../OidcLogoutAuthenticationConverter.java | 8 +++--- ...ultOAuth2AuthorizationRequestResolver.java | 9 ++++--- ...eOpenSamlAuthenticationTokenConverter.java | 8 +++--- ...faultRelyingPartyRegistrationResolver.java | 27 ++++++++++++++++--- .../service/web/Saml2MetadataFilter.java | 8 +++--- ...OpenSamlAuthenticationRequestResolver.java | 15 ++++++----- .../Saml2WebSsoAuthenticationFilter.java | 7 ++--- ...outRequestValidatorParametersResolver.java | 8 +++--- .../logout/Saml2LogoutRequestFilter.java | 7 ++--- .../logout/Saml2LogoutResponseFilter.java | 6 ++--- ...equestMatcherMetadataResponseResolver.java | 10 +++---- .../OpenSamlAuthenticationTokenConverter.java | 8 +++--- ...outRequestValidatorParametersResolver.java | 8 +++--- ...ilterInvocationSecurityMetadataSource.java | 18 +------------ ...bstractAuthenticationProcessingFilter.java | 6 ++--- .../UsernamePasswordAuthenticationFilter.java | 8 +++--- .../authentication/logout/LogoutFilter.java | 4 +-- .../ott/GenerateOneTimeTokenFilter.java | 6 ++--- .../ott/OneTimeTokenAuthenticationFilter.java | 5 ++-- .../ui/DefaultLogoutPageGeneratingFilter.java | 7 ++--- ...neTimeTokenSubmitPageGeneratingFilter.java | 6 +++-- .../ui/DefaultResourcesFilter.java | 10 ++++--- ...blicKeyCredentialRequestOptionsFilter.java | 8 +++--- .../WebAuthnAuthenticationFilter.java | 7 +++-- ...AuthnRegistrationPageGeneratingFilter.java | 7 ++--- ...licKeyCredentialCreationOptionsFilter.java | 6 ++--- .../WebAuthnRegistrationFilter.java | 11 ++++---- ...ctAuthenticationProcessingFilterTests.java | 2 +- .../ui/DefaultResourcesFilterTests.java | 6 ++--- 29 files changed, 133 insertions(+), 113 deletions(-) diff --git a/config/src/main/java/org/springframework/security/config/annotation/web/configurers/oauth2/client/OidcLogoutAuthenticationConverter.java b/config/src/main/java/org/springframework/security/config/annotation/web/configurers/oauth2/client/OidcLogoutAuthenticationConverter.java index 2809991894..42ff84f985 100644 --- a/config/src/main/java/org/springframework/security/config/annotation/web/configurers/oauth2/client/OidcLogoutAuthenticationConverter.java +++ b/config/src/main/java/org/springframework/security/config/annotation/web/configurers/oauth2/client/OidcLogoutAuthenticationConverter.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2023 the original author or authors. + * 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. @@ -20,13 +20,14 @@ import jakarta.servlet.http.HttpServletRequest; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import org.springframework.http.HttpMethod; import org.springframework.security.core.Authentication; import org.springframework.security.oauth2.client.registration.ClientRegistration; import org.springframework.security.oauth2.client.registration.ClientRegistrationRepository; import org.springframework.security.oauth2.core.OAuth2AuthenticationException; import org.springframework.security.oauth2.core.OAuth2ErrorCodes; import org.springframework.security.web.authentication.AuthenticationConverter; -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.util.Assert; @@ -45,7 +46,8 @@ final class OidcLogoutAuthenticationConverter implements AuthenticationConverter private final ClientRegistrationRepository clientRegistrationRepository; - private RequestMatcher requestMatcher = new AntPathRequestMatcher(DEFAULT_LOGOUT_URI, "POST"); + private RequestMatcher requestMatcher = PathPatternRequestMatcher.withDefaults() + .matcher(HttpMethod.POST, DEFAULT_LOGOUT_URI); OidcLogoutAuthenticationConverter(ClientRegistrationRepository clientRegistrationRepository) { Assert.notNull(clientRegistrationRepository, "clientRegistrationRepository cannot be null"); diff --git a/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/web/DefaultOAuth2AuthorizationRequestResolver.java b/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/web/DefaultOAuth2AuthorizationRequestResolver.java index 6ef3a29f14..63a78649ce 100644 --- a/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/web/DefaultOAuth2AuthorizationRequestResolver.java +++ b/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/web/DefaultOAuth2AuthorizationRequestResolver.java @@ -36,8 +36,9 @@ import org.springframework.security.oauth2.core.endpoint.OAuth2AuthorizationRequ import org.springframework.security.oauth2.core.endpoint.OAuth2ParameterNames; import org.springframework.security.oauth2.core.oidc.OidcScopes; import org.springframework.security.oauth2.core.oidc.endpoint.OidcParameterNames; +import org.springframework.security.web.servlet.util.matcher.PathPatternRequestMatcher; import org.springframework.security.web.util.UrlUtils; -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.CollectionUtils; import org.springframework.util.StringUtils; @@ -80,7 +81,7 @@ public final class DefaultOAuth2AuthorizationRequestResolver implements OAuth2Au private final ClientRegistrationRepository clientRegistrationRepository; - private final AntPathRequestMatcher authorizationRequestMatcher; + private final RequestMatcher authorizationRequestMatcher; private Consumer authorizationRequestCustomizer = (customizer) -> { }; @@ -97,8 +98,8 @@ public final class DefaultOAuth2AuthorizationRequestResolver implements OAuth2Au Assert.notNull(clientRegistrationRepository, "clientRegistrationRepository cannot be null"); Assert.hasText(authorizationRequestBaseUri, "authorizationRequestBaseUri cannot be empty"); this.clientRegistrationRepository = clientRegistrationRepository; - this.authorizationRequestMatcher = new AntPathRequestMatcher( - authorizationRequestBaseUri + "/{" + REGISTRATION_ID_URI_VARIABLE_NAME + "}"); + this.authorizationRequestMatcher = PathPatternRequestMatcher.withDefaults() + .matcher(authorizationRequestBaseUri + "/{" + REGISTRATION_ID_URI_VARIABLE_NAME + "}"); } @Override diff --git a/saml2/saml2-service-provider/src/main/java/org/springframework/security/saml2/provider/service/web/BaseOpenSamlAuthenticationTokenConverter.java b/saml2/saml2-service-provider/src/main/java/org/springframework/security/saml2/provider/service/web/BaseOpenSamlAuthenticationTokenConverter.java index 45b94c782b..a88847aeb6 100644 --- a/saml2/saml2-service-provider/src/main/java/org/springframework/security/saml2/provider/service/web/BaseOpenSamlAuthenticationTokenConverter.java +++ b/saml2/saml2-service-provider/src/main/java/org/springframework/security/saml2/provider/service/web/BaseOpenSamlAuthenticationTokenConverter.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2024 the original author or authors. + * 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. @@ -31,7 +31,7 @@ import org.springframework.security.saml2.provider.service.registration.RelyingP import org.springframework.security.saml2.provider.service.registration.RelyingPartyRegistrationRepository; import org.springframework.security.saml2.provider.service.web.RelyingPartyRegistrationPlaceholderResolvers.UriResolver; import org.springframework.security.web.authentication.AuthenticationConverter; -import org.springframework.security.web.util.matcher.AntPathRequestMatcher; +import org.springframework.security.web.servlet.util.matcher.PathPatternRequestMatcher; import org.springframework.security.web.util.matcher.OrRequestMatcher; import org.springframework.security.web.util.matcher.RequestMatcher; import org.springframework.util.Assert; @@ -47,8 +47,8 @@ final class BaseOpenSamlAuthenticationTokenConverter implements AuthenticationCo private final RelyingPartyRegistrationRepository registrations; private RequestMatcher requestMatcher = new OrRequestMatcher( - new AntPathRequestMatcher("/login/saml2/sso/{registrationId}"), - new AntPathRequestMatcher("/login/saml2/sso")); + PathPatternRequestMatcher.withDefaults().matcher("/login/saml2/sso/{registrationId}"), + PathPatternRequestMatcher.withDefaults().matcher("/login/saml2/sso")); private Saml2AuthenticationRequestRepository authenticationRequests = new HttpSessionSaml2AuthenticationRequestRepository(); diff --git a/saml2/saml2-service-provider/src/main/java/org/springframework/security/saml2/provider/service/web/DefaultRelyingPartyRegistrationResolver.java b/saml2/saml2-service-provider/src/main/java/org/springframework/security/saml2/provider/service/web/DefaultRelyingPartyRegistrationResolver.java index c2f71faa2c..62b139b720 100644 --- a/saml2/saml2-service-provider/src/main/java/org/springframework/security/saml2/provider/service/web/DefaultRelyingPartyRegistrationResolver.java +++ b/saml2/saml2-service-provider/src/main/java/org/springframework/security/saml2/provider/service/web/DefaultRelyingPartyRegistrationResolver.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * 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. @@ -16,15 +16,18 @@ package org.springframework.security.saml2.provider.service.web; +import java.util.Map; + import jakarta.servlet.http.HttpServletRequest; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.core.convert.converter.Converter; +import org.springframework.http.server.PathContainer; +import org.springframework.http.server.RequestPath; import org.springframework.security.saml2.provider.service.registration.RelyingPartyRegistration; import org.springframework.security.saml2.provider.service.registration.RelyingPartyRegistrationRepository; import org.springframework.security.saml2.provider.service.web.RelyingPartyRegistrationPlaceholderResolvers.UriResolver; -import org.springframework.security.web.util.matcher.AntPathRequestMatcher; import org.springframework.security.web.util.matcher.RequestMatcher; import org.springframework.util.Assert; @@ -43,7 +46,25 @@ public final class DefaultRelyingPartyRegistrationResolver private final RelyingPartyRegistrationRepository relyingPartyRegistrationRepository; - private final RequestMatcher registrationRequestMatcher = new AntPathRequestMatcher("/**/{registrationId}"); + private final RequestMatcher registrationRequestMatcher = new RequestMatcher() { + @Override + public boolean matches(HttpServletRequest request) { + return matcher(request).isMatch(); + } + + @Override + public MatchResult matcher(HttpServletRequest request) { + RequestPath path = RequestPath.parse(request.getRequestURI(), request.getContextPath()); + PathContainer contextPath = path.contextPath(); + PathContainer relativePath = path.subPath(contextPath.elements().size()); + int size = relativePath.elements().size(); + if (size > 0) { + return RequestMatcher.MatchResult + .match(Map.of("registrationId", relativePath.elements().get(size - 1).value())); + } + return RequestMatcher.MatchResult.notMatch(); + } + }; public DefaultRelyingPartyRegistrationResolver( RelyingPartyRegistrationRepository relyingPartyRegistrationRepository) { diff --git a/saml2/saml2-service-provider/src/main/java/org/springframework/security/saml2/provider/service/web/Saml2MetadataFilter.java b/saml2/saml2-service-provider/src/main/java/org/springframework/security/saml2/provider/service/web/Saml2MetadataFilter.java index 129f1d0498..87859bee86 100644 --- a/saml2/saml2-service-provider/src/main/java/org/springframework/security/saml2/provider/service/web/Saml2MetadataFilter.java +++ b/saml2/saml2-service-provider/src/main/java/org/springframework/security/saml2/provider/service/web/Saml2MetadataFilter.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2024 the original author or authors. + * 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. @@ -32,7 +32,7 @@ import org.springframework.security.saml2.provider.service.metadata.Saml2Metadat import org.springframework.security.saml2.provider.service.metadata.Saml2MetadataResponseResolver; import org.springframework.security.saml2.provider.service.registration.RelyingPartyRegistration; import org.springframework.security.saml2.provider.service.registration.RelyingPartyRegistrationRepository; -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.util.Assert; import org.springframework.web.filter.OncePerRequestFilter; @@ -146,8 +146,8 @@ public final class Saml2MetadataFilter extends OncePerRequestFilter { private final RelyingPartyRegistrationResolver registrations; - private RequestMatcher requestMatcher = new AntPathRequestMatcher( - "/saml2/service-provider-metadata/{registrationId}"); + private RequestMatcher requestMatcher = PathPatternRequestMatcher.withDefaults() + .matcher("/saml2/service-provider-metadata/{registrationId}"); private final Saml2MetadataResolver metadataResolver; diff --git a/saml2/saml2-service-provider/src/main/java/org/springframework/security/saml2/provider/service/web/authentication/BaseOpenSamlAuthenticationRequestResolver.java b/saml2/saml2-service-provider/src/main/java/org/springframework/security/saml2/provider/service/web/authentication/BaseOpenSamlAuthenticationRequestResolver.java index 1a19bacb60..8f9da90ea5 100644 --- a/saml2/saml2-service-provider/src/main/java/org/springframework/security/saml2/provider/service/web/authentication/BaseOpenSamlAuthenticationRequestResolver.java +++ b/saml2/saml2-service-provider/src/main/java/org/springframework/security/saml2/provider/service/web/authentication/BaseOpenSamlAuthenticationRequestResolver.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2024 the original author or authors. + * 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. @@ -50,8 +50,8 @@ import org.springframework.security.saml2.provider.service.registration.Saml2Mes import org.springframework.security.saml2.provider.service.web.RelyingPartyRegistrationPlaceholderResolvers; import org.springframework.security.saml2.provider.service.web.RelyingPartyRegistrationPlaceholderResolvers.UriResolver; import org.springframework.security.saml2.provider.service.web.RelyingPartyRegistrationResolver; +import org.springframework.security.web.servlet.util.matcher.PathPatternRequestMatcher; import org.springframework.security.web.util.matcher.AndRequestMatcher; -import org.springframework.security.web.util.matcher.AntPathRequestMatcher; import org.springframework.security.web.util.matcher.ParameterRequestMatcher; import org.springframework.security.web.util.matcher.RequestMatcher; import org.springframework.security.web.util.matcher.RequestMatchers; @@ -82,8 +82,9 @@ class BaseOpenSamlAuthenticationRequestResolver implements Saml2AuthenticationRe private final NameIDPolicyBuilder nameIdPolicyBuilder; private RequestMatcher requestMatcher = RequestMatchers.anyOf( - new AntPathRequestMatcher(Saml2AuthenticationRequestResolver.DEFAULT_AUTHENTICATION_REQUEST_URI), - new AntPathQueryRequestMatcher("/saml2/authenticate", "registrationId={registrationId}")); + PathPatternRequestMatcher.withDefaults() + .matcher(Saml2AuthenticationRequestResolver.DEFAULT_AUTHENTICATION_REQUEST_URI), + new PathPatternQueryRequestMatcher("/saml2/authenticate", "registrationId={registrationId}")); private Clock clock = Clock.systemUTC(); @@ -215,13 +216,13 @@ class BaseOpenSamlAuthenticationRequestResolver implements Saml2AuthenticationRe return this.saml.serialize(authnRequest).serialize(); } - private static final class AntPathQueryRequestMatcher implements RequestMatcher { + private static final class PathPatternQueryRequestMatcher implements RequestMatcher { private final RequestMatcher matcher; - AntPathQueryRequestMatcher(String path, String... params) { + PathPatternQueryRequestMatcher(String path, String... params) { List matchers = new ArrayList<>(); - matchers.add(new AntPathRequestMatcher(path)); + matchers.add(PathPatternRequestMatcher.withDefaults().matcher(path)); for (String param : params) { String[] parts = param.split("="); if (parts.length == 1) { diff --git a/saml2/saml2-service-provider/src/main/java/org/springframework/security/saml2/provider/service/web/authentication/Saml2WebSsoAuthenticationFilter.java b/saml2/saml2-service-provider/src/main/java/org/springframework/security/saml2/provider/service/web/authentication/Saml2WebSsoAuthenticationFilter.java index 334e8a51a8..af2f42ad41 100644 --- a/saml2/saml2-service-provider/src/main/java/org/springframework/security/saml2/provider/service/web/authentication/Saml2WebSsoAuthenticationFilter.java +++ b/saml2/saml2-service-provider/src/main/java/org/springframework/security/saml2/provider/service/web/authentication/Saml2WebSsoAuthenticationFilter.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2021 the original author or authors. + * 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. @@ -35,7 +35,7 @@ import org.springframework.security.saml2.provider.service.web.Saml2Authenticati import org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter; import org.springframework.security.web.authentication.AuthenticationConverter; import org.springframework.security.web.authentication.session.ChangeSessionIdAuthenticationStrategy; -import org.springframework.security.web.util.matcher.AntPathRequestMatcher; +import org.springframework.security.web.servlet.util.matcher.PathPatternRequestMatcher; import org.springframework.security.web.util.matcher.OrRequestMatcher; import org.springframework.security.web.util.matcher.RequestMatcher; import org.springframework.util.Assert; @@ -48,7 +48,8 @@ public class Saml2WebSsoAuthenticationFilter extends AbstractAuthenticationProce public static final String DEFAULT_FILTER_PROCESSES_URI = "/login/saml2/sso/{registrationId}"; private static final RequestMatcher DEFAULT_REQUEST_MATCHER = new OrRequestMatcher( - new AntPathRequestMatcher(DEFAULT_FILTER_PROCESSES_URI), new AntPathRequestMatcher("/login/saml2/sso")); + PathPatternRequestMatcher.withDefaults().matcher(DEFAULT_FILTER_PROCESSES_URI), + PathPatternRequestMatcher.withDefaults().matcher("/login/saml2/sso")); private final AuthenticationConverter authenticationConverter; diff --git a/saml2/saml2-service-provider/src/main/java/org/springframework/security/saml2/provider/service/web/authentication/logout/BaseOpenSamlLogoutRequestValidatorParametersResolver.java b/saml2/saml2-service-provider/src/main/java/org/springframework/security/saml2/provider/service/web/authentication/logout/BaseOpenSamlLogoutRequestValidatorParametersResolver.java index 95853fbe9f..2e58340aef 100644 --- a/saml2/saml2-service-provider/src/main/java/org/springframework/security/saml2/provider/service/web/authentication/logout/BaseOpenSamlLogoutRequestValidatorParametersResolver.java +++ b/saml2/saml2-service-provider/src/main/java/org/springframework/security/saml2/provider/service/web/authentication/logout/BaseOpenSamlLogoutRequestValidatorParametersResolver.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2024 the original author or authors. + * 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. @@ -33,7 +33,7 @@ import org.springframework.security.saml2.provider.service.registration.RelyingP import org.springframework.security.saml2.provider.service.registration.RelyingPartyRegistrationRepository; import org.springframework.security.saml2.provider.service.registration.Saml2MessageBinding; import org.springframework.security.saml2.provider.service.web.RelyingPartyRegistrationPlaceholderResolvers; -import org.springframework.security.web.util.matcher.AntPathRequestMatcher; +import org.springframework.security.web.servlet.util.matcher.PathPatternRequestMatcher; import org.springframework.security.web.util.matcher.OrRequestMatcher; import org.springframework.security.web.util.matcher.RequestMatcher; import org.springframework.util.Assert; @@ -54,8 +54,8 @@ final class BaseOpenSamlLogoutRequestValidatorParametersResolver private final RelyingPartyRegistrationRepository registrations; private RequestMatcher requestMatcher = new OrRequestMatcher( - new AntPathRequestMatcher("/logout/saml2/slo/{registrationId}"), - new AntPathRequestMatcher("/logout/saml2/slo")); + PathPatternRequestMatcher.withDefaults().matcher("/logout/saml2/slo/{registrationId}"), + PathPatternRequestMatcher.withDefaults().matcher("/logout/saml2/slo")); /** * Constructs a {@link BaseOpenSamlLogoutRequestValidatorParametersResolver} diff --git a/saml2/saml2-service-provider/src/main/java/org/springframework/security/saml2/provider/service/web/authentication/logout/Saml2LogoutRequestFilter.java b/saml2/saml2-service-provider/src/main/java/org/springframework/security/saml2/provider/service/web/authentication/logout/Saml2LogoutRequestFilter.java index 61a71ed31a..fd68bbc3a9 100644 --- a/saml2/saml2-service-provider/src/main/java/org/springframework/security/saml2/provider/service/web/authentication/logout/Saml2LogoutRequestFilter.java +++ b/saml2/saml2-service-provider/src/main/java/org/springframework/security/saml2/provider/service/web/authentication/logout/Saml2LogoutRequestFilter.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2023 the original author or authors. + * 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. @@ -49,7 +49,7 @@ import org.springframework.security.web.DefaultRedirectStrategy; import org.springframework.security.web.RedirectStrategy; import org.springframework.security.web.authentication.logout.CompositeLogoutHandler; import org.springframework.security.web.authentication.logout.LogoutHandler; -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.util.Assert; import org.springframework.util.StringUtils; @@ -245,7 +245,8 @@ public final class Saml2LogoutRequestFilter extends OncePerRequestFilter { private final RelyingPartyRegistrationResolver relyingPartyRegistrationResolver; - private RequestMatcher logoutRequestMatcher = new AntPathRequestMatcher("/logout/saml2/slo"); + private RequestMatcher logoutRequestMatcher = PathPatternRequestMatcher.withDefaults() + .matcher("/logout/saml2/slo"); Saml2AssertingPartyLogoutRequestResolver(RelyingPartyRegistrationResolver relyingPartyRegistrationResolver) { this.relyingPartyRegistrationResolver = relyingPartyRegistrationResolver; diff --git a/saml2/saml2-service-provider/src/main/java/org/springframework/security/saml2/provider/service/web/authentication/logout/Saml2LogoutResponseFilter.java b/saml2/saml2-service-provider/src/main/java/org/springframework/security/saml2/provider/service/web/authentication/logout/Saml2LogoutResponseFilter.java index a3891bc541..0d858386c4 100644 --- a/saml2/saml2-service-provider/src/main/java/org/springframework/security/saml2/provider/service/web/authentication/logout/Saml2LogoutResponseFilter.java +++ b/saml2/saml2-service-provider/src/main/java/org/springframework/security/saml2/provider/service/web/authentication/logout/Saml2LogoutResponseFilter.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2022 the original author or authors. + * 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. @@ -41,7 +41,7 @@ import org.springframework.security.saml2.provider.service.web.RelyingPartyRegis import org.springframework.security.saml2.provider.service.web.RelyingPartyRegistrationPlaceholderResolvers.UriResolver; import org.springframework.security.saml2.provider.service.web.RelyingPartyRegistrationResolver; 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.security.web.util.matcher.RequestMatcher; import org.springframework.util.Assert; import org.springframework.web.filter.OncePerRequestFilter; @@ -72,7 +72,7 @@ public final class Saml2LogoutResponseFilter extends OncePerRequestFilter { private Saml2LogoutRequestRepository logoutRequestRepository = new HttpSessionLogoutRequestRepository(); - private RequestMatcher logoutRequestMatcher = new AntPathRequestMatcher("/logout/saml2/slo"); + private RequestMatcher logoutRequestMatcher = PathPatternRequestMatcher.withDefaults().matcher("/logout/saml2/slo"); public Saml2LogoutResponseFilter(RelyingPartyRegistrationRepository registrations, Saml2LogoutResponseValidator logoutResponseValidator, LogoutSuccessHandler logoutSuccessHandler) { diff --git a/saml2/saml2-service-provider/src/main/java/org/springframework/security/saml2/provider/service/web/metadata/RequestMatcherMetadataResponseResolver.java b/saml2/saml2-service-provider/src/main/java/org/springframework/security/saml2/provider/service/web/metadata/RequestMatcherMetadataResponseResolver.java index 79dcb34dcc..e8348730d2 100644 --- a/saml2/saml2-service-provider/src/main/java/org/springframework/security/saml2/provider/service/web/metadata/RequestMatcherMetadataResponseResolver.java +++ b/saml2/saml2-service-provider/src/main/java/org/springframework/security/saml2/provider/service/web/metadata/RequestMatcherMetadataResponseResolver.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2024 the original author or authors. + * 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. @@ -34,7 +34,7 @@ import org.springframework.security.saml2.provider.service.registration.Iterable import org.springframework.security.saml2.provider.service.registration.RelyingPartyRegistration; import org.springframework.security.saml2.provider.service.registration.RelyingPartyRegistrationRepository; import org.springframework.security.saml2.provider.service.web.RelyingPartyRegistrationPlaceholderResolvers; -import org.springframework.security.web.util.matcher.AntPathRequestMatcher; +import org.springframework.security.web.servlet.util.matcher.PathPatternRequestMatcher; import org.springframework.security.web.util.matcher.OrRequestMatcher; import org.springframework.security.web.util.matcher.RequestMatcher; import org.springframework.util.Assert; @@ -51,9 +51,9 @@ public class RequestMatcherMetadataResponseResolver implements Saml2MetadataResp private static final String DEFAULT_METADATA_FILENAME = "saml-{registrationId}-metadata.xml"; private RequestMatcher matcher = new OrRequestMatcher( - new AntPathRequestMatcher("/saml2/service-provider-metadata/{registrationId}"), - new AntPathRequestMatcher("/saml2/metadata/{registrationId}"), - new AntPathRequestMatcher("/saml2/metadata")); + PathPatternRequestMatcher.withDefaults().matcher("/saml2/service-provider-metadata/{registrationId}"), + PathPatternRequestMatcher.withDefaults().matcher("/saml2/metadata/{registrationId}"), + PathPatternRequestMatcher.withDefaults().matcher("/saml2/metadata")); private String filename = DEFAULT_METADATA_FILENAME; diff --git a/saml2/saml2-service-provider/src/opensaml4Main/java/org/springframework/security/saml2/provider/service/web/OpenSamlAuthenticationTokenConverter.java b/saml2/saml2-service-provider/src/opensaml4Main/java/org/springframework/security/saml2/provider/service/web/OpenSamlAuthenticationTokenConverter.java index 852c6b7c27..16f8908fd9 100644 --- a/saml2/saml2-service-provider/src/opensaml4Main/java/org/springframework/security/saml2/provider/service/web/OpenSamlAuthenticationTokenConverter.java +++ b/saml2/saml2-service-provider/src/opensaml4Main/java/org/springframework/security/saml2/provider/service/web/OpenSamlAuthenticationTokenConverter.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2023 the original author or authors. + * 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. @@ -33,7 +33,7 @@ import org.springframework.security.saml2.provider.service.registration.RelyingP import org.springframework.security.saml2.provider.service.registration.RelyingPartyRegistrationRepository; import org.springframework.security.saml2.provider.service.web.RelyingPartyRegistrationPlaceholderResolvers.UriResolver; import org.springframework.security.web.authentication.AuthenticationConverter; -import org.springframework.security.web.util.matcher.AntPathRequestMatcher; +import org.springframework.security.web.servlet.util.matcher.PathPatternRequestMatcher; import org.springframework.security.web.util.matcher.OrRequestMatcher; import org.springframework.security.web.util.matcher.RequestMatcher; import org.springframework.util.Assert; @@ -60,8 +60,8 @@ public final class OpenSamlAuthenticationTokenConverter implements Authenticatio private final RelyingPartyRegistrationRepository registrations; private RequestMatcher requestMatcher = new OrRequestMatcher( - new AntPathRequestMatcher("/login/saml2/sso/{registrationId}"), - new AntPathRequestMatcher("/login/saml2/sso")); + PathPatternRequestMatcher.withDefaults().matcher("/login/saml2/sso/{registrationId}"), + PathPatternRequestMatcher.withDefaults().matcher("/login/saml2/sso")); private Function loader; diff --git a/saml2/saml2-service-provider/src/opensaml4Main/java/org/springframework/security/saml2/provider/service/web/authentication/logout/OpenSamlLogoutRequestValidatorParametersResolver.java b/saml2/saml2-service-provider/src/opensaml4Main/java/org/springframework/security/saml2/provider/service/web/authentication/logout/OpenSamlLogoutRequestValidatorParametersResolver.java index f520dad657..27a610a896 100644 --- a/saml2/saml2-service-provider/src/opensaml4Main/java/org/springframework/security/saml2/provider/service/web/authentication/logout/OpenSamlLogoutRequestValidatorParametersResolver.java +++ b/saml2/saml2-service-provider/src/opensaml4Main/java/org/springframework/security/saml2/provider/service/web/authentication/logout/OpenSamlLogoutRequestValidatorParametersResolver.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2023 the original author or authors. + * 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. @@ -37,7 +37,7 @@ import org.springframework.security.saml2.provider.service.registration.RelyingP import org.springframework.security.saml2.provider.service.registration.RelyingPartyRegistrationRepository; import org.springframework.security.saml2.provider.service.registration.Saml2MessageBinding; import org.springframework.security.saml2.provider.service.web.RelyingPartyRegistrationPlaceholderResolvers; -import org.springframework.security.web.util.matcher.AntPathRequestMatcher; +import org.springframework.security.web.servlet.util.matcher.PathPatternRequestMatcher; import org.springframework.security.web.util.matcher.OrRequestMatcher; import org.springframework.security.web.util.matcher.RequestMatcher; import org.springframework.util.Assert; @@ -59,8 +59,8 @@ public final class OpenSamlLogoutRequestValidatorParametersResolver } private RequestMatcher requestMatcher = new OrRequestMatcher( - new AntPathRequestMatcher("/logout/saml2/slo/{registrationId}"), - new AntPathRequestMatcher("/logout/saml2/slo")); + PathPatternRequestMatcher.withDefaults().matcher("/logout/saml2/slo/{registrationId}"), + PathPatternRequestMatcher.withDefaults().matcher("/logout/saml2/slo")); private final OpenSamlOperations saml = new OpenSaml4Template(); diff --git a/web/src/main/java/org/springframework/security/web/access/expression/ExpressionBasedFilterInvocationSecurityMetadataSource.java b/web/src/main/java/org/springframework/security/web/access/expression/ExpressionBasedFilterInvocationSecurityMetadataSource.java index f64c79242f..928c7d3101 100644 --- a/web/src/main/java/org/springframework/security/web/access/expression/ExpressionBasedFilterInvocationSecurityMetadataSource.java +++ b/web/src/main/java/org/springframework/security/web/access/expression/ExpressionBasedFilterInvocationSecurityMetadataSource.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * 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. @@ -35,7 +35,6 @@ import org.springframework.security.authorization.AuthorizationManager; import org.springframework.security.core.annotation.SecurityAnnotationScanner; import org.springframework.security.web.FilterInvocation; import org.springframework.security.web.access.intercept.DefaultFilterInvocationSecurityMetadataSource; -import org.springframework.security.web.util.matcher.AntPathRequestMatcher; import org.springframework.security.web.util.matcher.RequestMatcher; import org.springframework.util.Assert; @@ -99,21 +98,6 @@ public final class ExpressionBasedFilterInvocationSecurityMetadataSource return new RequestVariablesExtractorEvaluationContextPostProcessor(request); } - static class AntPathMatcherEvaluationContextPostProcessor extends AbstractVariableEvaluationContextPostProcessor { - - private final AntPathRequestMatcher matcher; - - AntPathMatcherEvaluationContextPostProcessor(AntPathRequestMatcher matcher) { - this.matcher = matcher; - } - - @Override - Map extractVariables(HttpServletRequest request) { - return this.matcher.matcher(request).getVariables(); - } - - } - static class RequestVariablesExtractorEvaluationContextPostProcessor extends AbstractVariableEvaluationContextPostProcessor { diff --git a/web/src/main/java/org/springframework/security/web/authentication/AbstractAuthenticationProcessingFilter.java b/web/src/main/java/org/springframework/security/web/authentication/AbstractAuthenticationProcessingFilter.java index 51776fb0b2..d96302acbd 100644 --- a/web/src/main/java/org/springframework/security/web/authentication/AbstractAuthenticationProcessingFilter.java +++ b/web/src/main/java/org/springframework/security/web/authentication/AbstractAuthenticationProcessingFilter.java @@ -46,7 +46,7 @@ import org.springframework.security.web.authentication.session.NullAuthenticated import org.springframework.security.web.authentication.session.SessionAuthenticationStrategy; import org.springframework.security.web.context.RequestAttributeSecurityContextRepository; import org.springframework.security.web.context.SecurityContextRepository; -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.util.Assert; import org.springframework.web.filter.GenericFilterBean; @@ -395,11 +395,11 @@ public abstract class AbstractAuthenticationProcessingFilter extends GenericFilt * @param filterProcessesUrl */ public void setFilterProcessesUrl(String filterProcessesUrl) { - setRequiresAuthenticationRequestMatcher(new AntPathRequestMatcher(filterProcessesUrl)); + setRequiresAuthenticationRequestMatcher(PathPatternRequestMatcher.withDefaults().matcher(filterProcessesUrl)); } public final void setRequiresAuthenticationRequestMatcher(RequestMatcher requestMatcher) { - Assert.notNull(requestMatcher, "requestMatcher cannot be null"); + Assert.notNull(requestMatcher, "requestMatcher cannot be null or empty"); this.requiresAuthenticationRequestMatcher = requestMatcher; } diff --git a/web/src/main/java/org/springframework/security/web/authentication/UsernamePasswordAuthenticationFilter.java b/web/src/main/java/org/springframework/security/web/authentication/UsernamePasswordAuthenticationFilter.java index a941cfeb59..9a9fd4a6dd 100644 --- a/web/src/main/java/org/springframework/security/web/authentication/UsernamePasswordAuthenticationFilter.java +++ b/web/src/main/java/org/springframework/security/web/authentication/UsernamePasswordAuthenticationFilter.java @@ -19,13 +19,15 @@ package org.springframework.security.web.authentication; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; +import org.springframework.http.HttpMethod; import org.springframework.lang.Nullable; import org.springframework.security.authentication.AuthenticationManager; import org.springframework.security.authentication.AuthenticationServiceException; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.security.core.Authentication; import org.springframework.security.core.AuthenticationException; -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.util.Assert; /** @@ -51,8 +53,8 @@ public class UsernamePasswordAuthenticationFilter extends AbstractAuthentication public static final String SPRING_SECURITY_FORM_PASSWORD_KEY = "password"; - private static final AntPathRequestMatcher DEFAULT_ANT_PATH_REQUEST_MATCHER = new AntPathRequestMatcher("/login", - "POST"); + private static final RequestMatcher DEFAULT_ANT_PATH_REQUEST_MATCHER = PathPatternRequestMatcher.withDefaults() + .matcher(HttpMethod.POST, "/login"); private String usernameParameter = SPRING_SECURITY_FORM_USERNAME_KEY; diff --git a/web/src/main/java/org/springframework/security/web/authentication/logout/LogoutFilter.java b/web/src/main/java/org/springframework/security/web/authentication/logout/LogoutFilter.java index b9053469d8..e8003ea4cf 100644 --- a/web/src/main/java/org/springframework/security/web/authentication/logout/LogoutFilter.java +++ b/web/src/main/java/org/springframework/security/web/authentication/logout/LogoutFilter.java @@ -29,8 +29,8 @@ import org.springframework.core.log.LogMessage; import org.springframework.security.core.Authentication; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.security.core.context.SecurityContextHolderStrategy; +import org.springframework.security.web.servlet.util.matcher.PathPatternRequestMatcher; import org.springframework.security.web.util.UrlUtils; -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; @@ -140,7 +140,7 @@ public class LogoutFilter extends GenericFilterBean { } public void setFilterProcessesUrl(String filterProcessesUrl) { - this.logoutRequestMatcher = new AntPathRequestMatcher(filterProcessesUrl); + this.logoutRequestMatcher = PathPatternRequestMatcher.withDefaults().matcher(filterProcessesUrl); } } diff --git a/web/src/main/java/org/springframework/security/web/authentication/ott/GenerateOneTimeTokenFilter.java b/web/src/main/java/org/springframework/security/web/authentication/ott/GenerateOneTimeTokenFilter.java index 381fdde75b..3b0f332ded 100644 --- a/web/src/main/java/org/springframework/security/web/authentication/ott/GenerateOneTimeTokenFilter.java +++ b/web/src/main/java/org/springframework/security/web/authentication/ott/GenerateOneTimeTokenFilter.java @@ -27,13 +27,12 @@ import org.springframework.http.HttpMethod; import org.springframework.security.authentication.ott.GenerateOneTimeTokenRequest; import org.springframework.security.authentication.ott.OneTimeToken; import org.springframework.security.authentication.ott.OneTimeTokenService; +import org.springframework.security.web.servlet.util.matcher.PathPatternRequestMatcher; import org.springframework.security.web.util.matcher.RequestMatcher; import org.springframework.util.Assert; import org.springframework.util.StringUtils; import org.springframework.web.filter.OncePerRequestFilter; -import static org.springframework.security.web.util.matcher.AntPathRequestMatcher.antMatcher; - /** * Filter that process a One-Time Token generation request. * @@ -49,7 +48,8 @@ public final class GenerateOneTimeTokenFilter extends OncePerRequestFilter { private final OneTimeTokenGenerationSuccessHandler tokenGenerationSuccessHandler; - private RequestMatcher requestMatcher = antMatcher(HttpMethod.POST, DEFAULT_GENERATE_URL); + private RequestMatcher requestMatcher = PathPatternRequestMatcher.withDefaults() + .matcher(HttpMethod.POST, DEFAULT_GENERATE_URL); private GenerateOneTimeTokenRequestResolver requestResolver = new DefaultGenerateOneTimeTokenRequestResolver(); diff --git a/web/src/main/java/org/springframework/security/web/authentication/ott/OneTimeTokenAuthenticationFilter.java b/web/src/main/java/org/springframework/security/web/authentication/ott/OneTimeTokenAuthenticationFilter.java index ab5f54d4d7..e520921257 100644 --- a/web/src/main/java/org/springframework/security/web/authentication/ott/OneTimeTokenAuthenticationFilter.java +++ b/web/src/main/java/org/springframework/security/web/authentication/ott/OneTimeTokenAuthenticationFilter.java @@ -16,8 +16,9 @@ package org.springframework.security.web.authentication.ott; +import org.springframework.http.HttpMethod; import org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter; -import org.springframework.security.web.util.matcher.AntPathRequestMatcher; +import org.springframework.security.web.servlet.util.matcher.PathPatternRequestMatcher; /** * Filter that processes a one-time token for log in. @@ -33,7 +34,7 @@ public final class OneTimeTokenAuthenticationFilter extends AbstractAuthenticati public static final String DEFAULT_LOGIN_PROCESSING_URL = "/login/ott"; public OneTimeTokenAuthenticationFilter() { - super(new AntPathRequestMatcher(DEFAULT_LOGIN_PROCESSING_URL, "POST")); + super(PathPatternRequestMatcher.withDefaults().matcher(HttpMethod.POST, DEFAULT_LOGIN_PROCESSING_URL)); setAuthenticationConverter(new OneTimeTokenAuthenticationConverter()); } diff --git a/web/src/main/java/org/springframework/security/web/authentication/ui/DefaultLogoutPageGeneratingFilter.java b/web/src/main/java/org/springframework/security/web/authentication/ui/DefaultLogoutPageGeneratingFilter.java index 401c7cb1d1..9e4999a7e2 100644 --- a/web/src/main/java/org/springframework/security/web/authentication/ui/DefaultLogoutPageGeneratingFilter.java +++ b/web/src/main/java/org/springframework/security/web/authentication/ui/DefaultLogoutPageGeneratingFilter.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2024 the original author or authors. + * 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. @@ -27,7 +27,8 @@ import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; import org.springframework.core.log.LogMessage; -import org.springframework.security.web.util.matcher.AntPathRequestMatcher; +import org.springframework.http.HttpMethod; +import org.springframework.security.web.servlet.util.matcher.PathPatternRequestMatcher; import org.springframework.security.web.util.matcher.RequestMatcher; import org.springframework.util.Assert; import org.springframework.web.filter.OncePerRequestFilter; @@ -40,7 +41,7 @@ import org.springframework.web.filter.OncePerRequestFilter; */ public class DefaultLogoutPageGeneratingFilter extends OncePerRequestFilter { - private RequestMatcher matcher = new AntPathRequestMatcher("/logout", "GET"); + private RequestMatcher matcher = PathPatternRequestMatcher.withDefaults().matcher(HttpMethod.GET, "/logout"); private Function> resolveHiddenInputs = (request) -> Collections.emptyMap(); diff --git a/web/src/main/java/org/springframework/security/web/authentication/ui/DefaultOneTimeTokenSubmitPageGeneratingFilter.java b/web/src/main/java/org/springframework/security/web/authentication/ui/DefaultOneTimeTokenSubmitPageGeneratingFilter.java index 47d087c9c7..f765dc6ddd 100644 --- a/web/src/main/java/org/springframework/security/web/authentication/ui/DefaultOneTimeTokenSubmitPageGeneratingFilter.java +++ b/web/src/main/java/org/springframework/security/web/authentication/ui/DefaultOneTimeTokenSubmitPageGeneratingFilter.java @@ -28,8 +28,9 @@ import jakarta.servlet.ServletException; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; +import org.springframework.http.HttpMethod; import org.springframework.security.web.authentication.ott.OneTimeTokenAuthenticationFilter; -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.util.Assert; import org.springframework.util.StringUtils; @@ -46,7 +47,8 @@ public final class DefaultOneTimeTokenSubmitPageGeneratingFilter extends OncePer public static final String DEFAULT_SUBMIT_PAGE_URL = "/login/ott"; - private RequestMatcher requestMatcher = new AntPathRequestMatcher(DEFAULT_SUBMIT_PAGE_URL, "GET"); + private RequestMatcher requestMatcher = PathPatternRequestMatcher.withDefaults() + .matcher(HttpMethod.GET, DEFAULT_SUBMIT_PAGE_URL); private Function> resolveHiddenInputs = (request) -> Collections.emptyMap(); diff --git a/web/src/main/java/org/springframework/security/web/authentication/ui/DefaultResourcesFilter.java b/web/src/main/java/org/springframework/security/web/authentication/ui/DefaultResourcesFilter.java index c2c80f19bd..ee52dc682b 100644 --- a/web/src/main/java/org/springframework/security/web/authentication/ui/DefaultResourcesFilter.java +++ b/web/src/main/java/org/springframework/security/web/authentication/ui/DefaultResourcesFilter.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2024 the original author or authors. + * 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. @@ -28,7 +28,7 @@ import jakarta.servlet.http.HttpServletRequest; import org.springframework.core.io.ClassPathResource; import org.springframework.http.HttpMethod; import org.springframework.http.MediaType; -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.util.Assert; import org.springframework.web.filter.GenericFilterBean; @@ -89,7 +89,8 @@ public final class DefaultResourcesFilter extends GenericFilterBean { * @return - */ public static DefaultResourcesFilter css() { - return new DefaultResourcesFilter(AntPathRequestMatcher.antMatcher(HttpMethod.GET, "/default-ui.css"), + return new DefaultResourcesFilter( + PathPatternRequestMatcher.withDefaults().matcher(HttpMethod.GET, "/default-ui.css"), new ClassPathResource("org/springframework/security/default-ui.css"), new MediaType("text", "css", StandardCharsets.UTF_8)); } @@ -106,7 +107,8 @@ public final class DefaultResourcesFilter extends GenericFilterBean { * @return - */ public static DefaultResourcesFilter webauthn() { - return new DefaultResourcesFilter(AntPathRequestMatcher.antMatcher(HttpMethod.GET, "/login/webauthn.js"), + return new DefaultResourcesFilter( + PathPatternRequestMatcher.withDefaults().matcher(HttpMethod.GET, "/login/webauthn.js"), new ClassPathResource("org/springframework/security/spring-security-webauthn.js"), new MediaType("text", "javascript", StandardCharsets.UTF_8)); } diff --git a/web/src/main/java/org/springframework/security/web/webauthn/authentication/PublicKeyCredentialRequestOptionsFilter.java b/web/src/main/java/org/springframework/security/web/webauthn/authentication/PublicKeyCredentialRequestOptionsFilter.java index 26abf556f2..6c7b64cfaa 100644 --- a/web/src/main/java/org/springframework/security/web/webauthn/authentication/PublicKeyCredentialRequestOptionsFilter.java +++ b/web/src/main/java/org/springframework/security/web/webauthn/authentication/PublicKeyCredentialRequestOptionsFilter.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2024 the original author or authors. + * 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. @@ -33,6 +33,7 @@ import org.springframework.http.server.ServletServerHttpResponse; import org.springframework.security.core.context.SecurityContext; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.security.core.context.SecurityContextHolderStrategy; +import org.springframework.security.web.servlet.util.matcher.PathPatternRequestMatcher; import org.springframework.security.web.util.matcher.RequestMatcher; import org.springframework.security.web.webauthn.api.PublicKeyCredentialRequestOptions; import org.springframework.security.web.webauthn.jackson.WebauthnJackson2Module; @@ -41,8 +42,6 @@ import org.springframework.security.web.webauthn.management.WebAuthnRelyingParty import org.springframework.util.Assert; import org.springframework.web.filter.OncePerRequestFilter; -import static org.springframework.security.web.util.matcher.AntPathRequestMatcher.antMatcher; - /** * A {@link jakarta.servlet.Filter} that renders the * {@link PublicKeyCredentialRequestOptions} in order to } that is * parsed from the body of the {@link HttpServletRequest} using the @@ -78,7 +77,7 @@ public class WebAuthnAuthenticationFilter extends AbstractAuthenticationProcessi private PublicKeyCredentialRequestOptionsRepository requestOptionsRepository = new HttpSessionPublicKeyCredentialRequestOptionsRepository(); public WebAuthnAuthenticationFilter() { - super(antMatcher(HttpMethod.POST, "/login/webauthn")); + super(PathPatternRequestMatcher.withDefaults().matcher(HttpMethod.POST, "/login/webauthn")); setSecurityContextRepository(new HttpSessionSecurityContextRepository()); setAuthenticationFailureHandler( new AuthenticationEntryPointFailureHandler(new HttpStatusEntryPoint(HttpStatus.UNAUTHORIZED))); diff --git a/web/src/main/java/org/springframework/security/web/webauthn/registration/DefaultWebAuthnRegistrationPageGeneratingFilter.java b/web/src/main/java/org/springframework/security/web/webauthn/registration/DefaultWebAuthnRegistrationPageGeneratingFilter.java index 2b8e0fb4df..6406f7af36 100644 --- a/web/src/main/java/org/springframework/security/web/webauthn/registration/DefaultWebAuthnRegistrationPageGeneratingFilter.java +++ b/web/src/main/java/org/springframework/security/web/webauthn/registration/DefaultWebAuthnRegistrationPageGeneratingFilter.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2024 the original author or authors. + * 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. @@ -34,7 +34,7 @@ import jakarta.servlet.http.HttpServletResponse; import org.springframework.http.HttpMethod; import org.springframework.http.MediaType; import org.springframework.security.web.csrf.CsrfToken; -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.security.web.webauthn.api.CredentialRecord; import org.springframework.security.web.webauthn.api.PublicKeyCredentialUserEntity; @@ -52,7 +52,8 @@ import org.springframework.web.filter.OncePerRequestFilter; */ public class DefaultWebAuthnRegistrationPageGeneratingFilter extends OncePerRequestFilter { - private RequestMatcher matcher = AntPathRequestMatcher.antMatcher(HttpMethod.GET, "/webauthn/register"); + private RequestMatcher matcher = PathPatternRequestMatcher.withDefaults() + .matcher(HttpMethod.GET, "/webauthn/register"); private final PublicKeyCredentialUserEntityRepository userEntities; diff --git a/web/src/main/java/org/springframework/security/web/webauthn/registration/PublicKeyCredentialCreationOptionsFilter.java b/web/src/main/java/org/springframework/security/web/webauthn/registration/PublicKeyCredentialCreationOptionsFilter.java index 6c9aa3b75e..1e93cb3502 100644 --- a/web/src/main/java/org/springframework/security/web/webauthn/registration/PublicKeyCredentialCreationOptionsFilter.java +++ b/web/src/main/java/org/springframework/security/web/webauthn/registration/PublicKeyCredentialCreationOptionsFilter.java @@ -38,6 +38,7 @@ import org.springframework.security.core.Authentication; import org.springframework.security.core.context.SecurityContext; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.security.core.context.SecurityContextHolderStrategy; +import org.springframework.security.web.servlet.util.matcher.PathPatternRequestMatcher; import org.springframework.security.web.util.matcher.RequestMatcher; import org.springframework.security.web.webauthn.api.PublicKeyCredentialCreationOptions; import org.springframework.security.web.webauthn.jackson.WebauthnJackson2Module; @@ -46,8 +47,6 @@ import org.springframework.security.web.webauthn.management.WebAuthnRelyingParty import org.springframework.util.Assert; import org.springframework.web.filter.OncePerRequestFilter; -import static org.springframework.security.web.util.matcher.AntPathRequestMatcher.antMatcher; - /** * A {@link jakarta.servlet.Filter} that renders the * {@link PublicKeyCredentialCreationOptions} for authorization = AuthenticatedAuthorizationManager.authenticated(); diff --git a/web/src/main/java/org/springframework/security/web/webauthn/registration/WebAuthnRegistrationFilter.java b/web/src/main/java/org/springframework/security/web/webauthn/registration/WebAuthnRegistrationFilter.java index 834531afc9..25ff74cc1a 100644 --- a/web/src/main/java/org/springframework/security/web/webauthn/registration/WebAuthnRegistrationFilter.java +++ b/web/src/main/java/org/springframework/security/web/webauthn/registration/WebAuthnRegistrationFilter.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2024 the original author or authors. + * 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. @@ -34,6 +34,7 @@ import org.springframework.http.converter.HttpMessageConverter; import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter; import org.springframework.http.server.ServletServerHttpRequest; import org.springframework.http.server.ServletServerHttpResponse; +import org.springframework.security.web.servlet.util.matcher.PathPatternRequestMatcher; import org.springframework.security.web.util.matcher.RequestMatcher; import org.springframework.security.web.webauthn.api.Bytes; import org.springframework.security.web.webauthn.api.CredentialRecord; @@ -46,8 +47,6 @@ import org.springframework.security.web.webauthn.management.WebAuthnRelyingParty import org.springframework.util.Assert; import org.springframework.web.filter.OncePerRequestFilter; -import static org.springframework.security.web.util.matcher.AntPathRequestMatcher.antMatcher; - /** * Authenticates {@code PublicKeyCredential} that is * parsed from the body of the {@link HttpServletRequest} using the @@ -93,9 +92,11 @@ public class WebAuthnRegistrationFilter extends OncePerRequestFilter { private PublicKeyCredentialCreationOptionsRepository creationOptionsRepository = new HttpSessionPublicKeyCredentialCreationOptionsRepository(); - private RequestMatcher registerCredentialMatcher = antMatcher(HttpMethod.POST, DEFAULT_REGISTER_CREDENTIAL_URL); + private RequestMatcher registerCredentialMatcher = PathPatternRequestMatcher.withDefaults() + .matcher(HttpMethod.POST, DEFAULT_REGISTER_CREDENTIAL_URL); - private RequestMatcher removeCredentialMatcher = antMatcher(HttpMethod.DELETE, "/webauthn/register/{id}"); + private RequestMatcher removeCredentialMatcher = PathPatternRequestMatcher.withDefaults() + .matcher(HttpMethod.DELETE, "/webauthn/register/{id}"); public WebAuthnRegistrationFilter(UserCredentialRepository userCredentials, WebAuthnRelyingPartyOperations rpOptions) { diff --git a/web/src/test/java/org/springframework/security/web/authentication/AbstractAuthenticationProcessingFilterTests.java b/web/src/test/java/org/springframework/security/web/authentication/AbstractAuthenticationProcessingFilterTests.java index 00e4de0614..4a9776ccb9 100644 --- a/web/src/test/java/org/springframework/security/web/authentication/AbstractAuthenticationProcessingFilterTests.java +++ b/web/src/test/java/org/springframework/security/web/authentication/AbstractAuthenticationProcessingFilterTests.java @@ -273,7 +273,7 @@ public class AbstractAuthenticationProcessingFilterTests { filter.setAuthenticationManager(mock(AuthenticationManager.class)); filter.setAuthenticationSuccessHandler(this.successHandler); assertThatIllegalArgumentException().isThrownBy(() -> filter.setFilterProcessesUrl(null)) - .withMessage("Pattern cannot be null or empty"); + .withMessage("pattern cannot be null"); } @Test diff --git a/web/src/test/java/org/springframework/security/web/authentication/ui/DefaultResourcesFilterTests.java b/web/src/test/java/org/springframework/security/web/authentication/ui/DefaultResourcesFilterTests.java index e7d0eb2b23..26b52f44b2 100644 --- a/web/src/test/java/org/springframework/security/web/authentication/ui/DefaultResourcesFilterTests.java +++ b/web/src/test/java/org/springframework/security/web/authentication/ui/DefaultResourcesFilterTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2024 the original author or authors. + * 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. @@ -59,7 +59,7 @@ public class DefaultResourcesFilterTests { @Test void toStringPrintsPathAndResource() { assertThat(this.cssFilter.toString()).isEqualTo( - "DefaultResourcesFilter [matcher=Ant [pattern='/default-ui.css', GET], resource=org/springframework/security/default-ui.css]"); + "DefaultResourcesFilter [matcher=PathPattern [GET /default-ui.css], resource=org/springframework/security/default-ui.css]"); } } @@ -89,7 +89,7 @@ public class DefaultResourcesFilterTests { @Test void toStringPrintsPathAndResource() { assertThat(this.webauthnFilter.toString()).isEqualTo( - "DefaultResourcesFilter [matcher=Ant [pattern='/login/webauthn.js', GET], resource=org/springframework/security/spring-security-webauthn.js]"); + "DefaultResourcesFilter [matcher=PathPattern [GET /login/webauthn.js], resource=org/springframework/security/spring-security-webauthn.js]"); } }