diff --git a/docs/modules/ROOT/pages/migration/web.adoc b/docs/modules/ROOT/pages/migration/web.adoc index 7f5de0e194..1ea4ecbfc7 100644 --- a/docs/modules/ROOT/pages/migration/web.adoc +++ b/docs/modules/ROOT/pages/migration/web.adoc @@ -94,6 +94,61 @@ switchUser.setExitUserMatcher(PathPatternRequestMatcher.withDefaults().matcher(H ---- ====== +=== Migrate `filterProcessingUrl` Request Matcher in `AbstractAuthenticationProcessingFilter` Implementations + +Spring Security 6 converts any processing endpoint configured through `setFilterProcessingUrl` to an `AntPathRequestMatcher`. +In Spring Security 7, this will change to `PathPatternRequestMatcher`. + +If you are directly invoking `setFilterProcessingUrl` on a filter that extends `AbstractAuthenticationProcessingFilter`, like `UsernamePasswordAuthenticationFilter`, `OAuth2LoginAuthenticationFilter`, `Saml2WebSsoAuthenticationFilter`, `OneTimeTokenAuthenticationFilter`, or `WebAuthnAuthenticationFilter`, call `setRequiredAuthenticationRequestMatcher` instead to provide this `PathPatternRequestMatcher` in advance. + +That is, change this: +[tabs] +====== +Java:: ++ +[source,java,role="primary"] +---- +UsernamePasswordAuthenticationFilter usernamePassword = new UsernamePasswordAuthenticationFilter(authenticationManager); +usernamePassword.setFilterProcessingUrl("/my/processing/url"); +---- + +Kotlin:: ++ +[source,kotlin,role="secondary"] +---- +val usernamePassword = UsernamePasswordAuthenticationFilter(authenticationManager) +usernamePassword.setFilterProcessingUrl("/my/processing/url") +---- +====== + +to this: + +[tabs] +====== +Java:: ++ +[source,java,role="primary"] +---- +UsernamePasswordAuthenticationFilter usernamePassword = new UsernamePasswordAuthenticationFilter(authenticationManager); +RequestMatcher requestMatcher = PathPatternRequestMatcher.withDefaults().matcher("/my/processing/url"); +usernamePassword.setRequest(requestMatcher); +---- + +Kotlin:: ++ +[source,kotlin,role="secondary"] +---- +val usernamePassword = UsernamePasswordAuthenticationFilter(authenticationManager) +val requestMatcher = PathPatternRequestMatcher.withDefaults().matcher("/my/processing/url") +usernamePassword.setRequest(requestMatcher) +---- +====== + +[NOTE] +----- +Most applications use the DSL instead of setting the `filterProcessingUrl` directly on a filter instance. +----- + === Migrate CAS Proxy Receptor Request Matcher Spring Security 6 converts any configured `proxyReceptorUrl` to a request matcher that matches the end of the request, that is `/**/proxy/receptor`. diff --git a/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/web/OAuth2LoginAuthenticationFilter.java b/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/web/OAuth2LoginAuthenticationFilter.java index 6ac3a3d62a..cb51be66dc 100644 --- a/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/web/OAuth2LoginAuthenticationFilter.java +++ b/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/web/OAuth2LoginAuthenticationFilter.java @@ -39,7 +39,9 @@ import org.springframework.security.oauth2.core.endpoint.OAuth2AuthorizationResp import org.springframework.security.oauth2.core.endpoint.OAuth2ParameterNames; import org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter; import org.springframework.security.web.context.SecurityContextRepository; +import org.springframework.security.web.servlet.util.matcher.PathPatternRequestMatcher; import org.springframework.security.web.util.UrlUtils; +import org.springframework.security.web.util.matcher.RequestMatcher; import org.springframework.util.Assert; import org.springframework.util.MultiValueMap; import org.springframework.web.util.UriComponentsBuilder; @@ -123,6 +125,8 @@ public class OAuth2LoginAuthenticationFilter extends AbstractAuthenticationProce public OAuth2LoginAuthenticationFilter(ClientRegistrationRepository clientRegistrationRepository, OAuth2AuthorizedClientService authorizedClientService) { this(clientRegistrationRepository, authorizedClientService, DEFAULT_FILTER_PROCESSES_URI); + RequestMatcher processUri = PathPatternRequestMatcher.withDefaults().matcher(DEFAULT_FILTER_PROCESSES_URI); + setRequiresAuthenticationRequestMatcher(processUri); } /** 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 af2f42ad41..2e85ce082e 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 @@ -63,6 +63,8 @@ public class Saml2WebSsoAuthenticationFilter extends AbstractAuthenticationProce */ public Saml2WebSsoAuthenticationFilter(RelyingPartyRegistrationRepository relyingPartyRegistrationRepository) { this(relyingPartyRegistrationRepository, DEFAULT_FILTER_PROCESSES_URI); + RequestMatcher processUri = PathPatternRequestMatcher.withDefaults().matcher(DEFAULT_FILTER_PROCESSES_URI); + setRequiresAuthenticationRequestMatcher(processUri); } /** 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 d96302acbd..16a737a9f7 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.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.web.filter.GenericFilterBean; @@ -395,7 +395,7 @@ public abstract class AbstractAuthenticationProcessingFilter extends GenericFilt * @param filterProcessesUrl */ public void setFilterProcessesUrl(String filterProcessesUrl) { - setRequiresAuthenticationRequestMatcher(PathPatternRequestMatcher.withDefaults().matcher(filterProcessesUrl)); + setRequiresAuthenticationRequestMatcher(new AntPathRequestMatcher(filterProcessesUrl)); } public final void setRequiresAuthenticationRequestMatcher(RequestMatcher requestMatcher) { 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 4a9776ccb9..00e4de0614 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"); + .withMessage("Pattern cannot be null or empty"); } @Test