2
0
Эх сурвалжийг харах

Add RequestMatcher Migration Path for AbstractAuthenticationProcessingFilter

Issue gh-16417
Josh Cummings 5 сар өмнө
parent
commit
99345537d6

+ 55 - 0
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
 === 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`.
 Spring Security 6 converts any configured `proxyReceptorUrl` to a request matcher that matches the end of the request, that is `/**/proxy/receptor`.

+ 4 - 0
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.oauth2.core.endpoint.OAuth2ParameterNames;
 import org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter;
 import org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter;
 import org.springframework.security.web.context.SecurityContextRepository;
 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.UrlUtils;
+import org.springframework.security.web.util.matcher.RequestMatcher;
 import org.springframework.util.Assert;
 import org.springframework.util.Assert;
 import org.springframework.util.MultiValueMap;
 import org.springframework.util.MultiValueMap;
 import org.springframework.web.util.UriComponentsBuilder;
 import org.springframework.web.util.UriComponentsBuilder;
@@ -123,6 +125,8 @@ public class OAuth2LoginAuthenticationFilter extends AbstractAuthenticationProce
 	public OAuth2LoginAuthenticationFilter(ClientRegistrationRepository clientRegistrationRepository,
 	public OAuth2LoginAuthenticationFilter(ClientRegistrationRepository clientRegistrationRepository,
 			OAuth2AuthorizedClientService authorizedClientService) {
 			OAuth2AuthorizedClientService authorizedClientService) {
 		this(clientRegistrationRepository, authorizedClientService, DEFAULT_FILTER_PROCESSES_URI);
 		this(clientRegistrationRepository, authorizedClientService, DEFAULT_FILTER_PROCESSES_URI);
+		RequestMatcher processUri = PathPatternRequestMatcher.withDefaults().matcher(DEFAULT_FILTER_PROCESSES_URI);
+		setRequiresAuthenticationRequestMatcher(processUri);
 	}
 	}
 
 
 	/**
 	/**

+ 2 - 0
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) {
 	public Saml2WebSsoAuthenticationFilter(RelyingPartyRegistrationRepository relyingPartyRegistrationRepository) {
 		this(relyingPartyRegistrationRepository, DEFAULT_FILTER_PROCESSES_URI);
 		this(relyingPartyRegistrationRepository, DEFAULT_FILTER_PROCESSES_URI);
+		RequestMatcher processUri = PathPatternRequestMatcher.withDefaults().matcher(DEFAULT_FILTER_PROCESSES_URI);
+		setRequiresAuthenticationRequestMatcher(processUri);
 	}
 	}
 
 
 	/**
 	/**

+ 2 - 2
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.authentication.session.SessionAuthenticationStrategy;
 import org.springframework.security.web.context.RequestAttributeSecurityContextRepository;
 import org.springframework.security.web.context.RequestAttributeSecurityContextRepository;
 import org.springframework.security.web.context.SecurityContextRepository;
 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.security.web.util.matcher.RequestMatcher;
 import org.springframework.util.Assert;
 import org.springframework.util.Assert;
 import org.springframework.web.filter.GenericFilterBean;
 import org.springframework.web.filter.GenericFilterBean;
@@ -395,7 +395,7 @@ public abstract class AbstractAuthenticationProcessingFilter extends GenericFilt
 	 * @param filterProcessesUrl
 	 * @param filterProcessesUrl
 	 */
 	 */
 	public void setFilterProcessesUrl(String filterProcessesUrl) {
 	public void setFilterProcessesUrl(String filterProcessesUrl) {
-		setRequiresAuthenticationRequestMatcher(PathPatternRequestMatcher.withDefaults().matcher(filterProcessesUrl));
+		setRequiresAuthenticationRequestMatcher(new AntPathRequestMatcher(filterProcessesUrl));
 	}
 	}
 
 
 	public final void setRequiresAuthenticationRequestMatcher(RequestMatcher requestMatcher) {
 	public final void setRequiresAuthenticationRequestMatcher(RequestMatcher requestMatcher) {

+ 1 - 1
web/src/test/java/org/springframework/security/web/authentication/AbstractAuthenticationProcessingFilterTests.java

@@ -273,7 +273,7 @@ public class AbstractAuthenticationProcessingFilterTests {
 		filter.setAuthenticationManager(mock(AuthenticationManager.class));
 		filter.setAuthenticationManager(mock(AuthenticationManager.class));
 		filter.setAuthenticationSuccessHandler(this.successHandler);
 		filter.setAuthenticationSuccessHandler(this.successHandler);
 		assertThatIllegalArgumentException().isThrownBy(() -> filter.setFilterProcessesUrl(null))
 		assertThatIllegalArgumentException().isThrownBy(() -> filter.setFilterProcessesUrl(null))
-			.withMessage("pattern cannot be null");
+			.withMessage("Pattern cannot be null or empty");
 	}
 	}
 
 
 	@Test
 	@Test