Przeglądaj źródła

Add RequestMatcher Migration Path for CAS

Issue gh-16417
Josh Cummings 4 miesięcy temu
rodzic
commit
91ee5e7f2b

+ 15 - 0
cas/src/main/java/org/springframework/security/cas/web/CasAuthenticationFilter.java

@@ -51,6 +51,7 @@ import org.springframework.security.web.context.SecurityContextRepository;
 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;
@@ -215,6 +216,8 @@ public class CasAuthenticationFilter extends AbstractAuthenticationProcessingFil
 
 	public CasAuthenticationFilter() {
 		super("/login/cas");
+		RequestMatcher processUri = PathPatternRequestMatcher.withDefaults().matcher("/login/cas");
+		setRequiresAuthenticationRequestMatcher(processUri);
 		setAuthenticationFailureHandler(new SimpleUrlAuthenticationFailureHandler());
 		setSecurityContextRepository(this.securityContextRepository);
 	}
@@ -319,6 +322,18 @@ public class CasAuthenticationFilter extends AbstractAuthenticationProcessingFil
 		super.setAuthenticationFailureHandler(new CasAuthenticationFailureHandler(failureHandler));
 	}
 
+	/**
+	 * Use this {@code RequestMatcher} to match proxy receptor requests. Without setting
+	 * this matcher, {@link CasAuthenticationFilter} will not capture any proxy receptor
+	 * requets.
+	 * @param proxyReceptorMatcher the {@link RequestMatcher} to use
+	 * @since 6.5
+	 */
+	public final void setProxyReceptorMatcher(RequestMatcher proxyReceptorMatcher) {
+		Assert.notNull(proxyReceptorMatcher, "proxyReceptorMatcher cannot be null");
+		this.proxyReceptorMatcher = proxyReceptorMatcher;
+	}
+
 	public final void setProxyReceptorUrl(final String proxyReceptorUrl) {
 		this.proxyReceptorMatcher = new AntPathRequestMatcher("/**" + proxyReceptorUrl);
 	}

+ 17 - 0
cas/src/test/java/org/springframework/security/cas/web/CasAuthenticationFilterTests.java

@@ -43,6 +43,7 @@ import org.springframework.security.core.context.SecurityContextImpl;
 import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
 import org.springframework.security.web.context.SecurityContextRepository;
 import org.springframework.security.web.savedrequest.HttpSessionRequestCache;
+import org.springframework.security.web.servlet.util.matcher.PathPatternRequestMatcher;
 import org.springframework.test.util.ReflectionTestUtils;
 
 import static org.assertj.core.api.Assertions.assertThat;
@@ -267,4 +268,20 @@ public class CasAuthenticationFilterTests {
 		verify(securityContextRepository).setContext(any(SecurityContext.class));
 	}
 
+	@Test
+	public void requiresAuthenticationWhenProxyRequestMatcherThenMatches() {
+		CasAuthenticationFilter filter = new CasAuthenticationFilter();
+		MockHttpServletRequest request = new MockHttpServletRequest("GET", "/pgtCallback");
+		MockHttpServletResponse response = new MockHttpServletResponse();
+		request.setServletPath("/pgtCallback");
+		assertThat(filter.requiresAuthentication(request, response)).isFalse();
+		filter.setProxyReceptorMatcher(PathPatternRequestMatcher.withDefaults().matcher(request.getServletPath()));
+		assertThat(filter.requiresAuthentication(request, response)).isFalse();
+		filter.setProxyGrantingTicketStorage(mock(ProxyGrantingTicketStorage.class));
+		assertThat(filter.requiresAuthentication(request, response)).isTrue();
+		request.setRequestURI("/other");
+		request.setServletPath("/other");
+		assertThat(filter.requiresAuthentication(request, response)).isFalse();
+	}
+
 }

+ 45 - 0
docs/modules/ROOT/pages/migration/web.adoc

@@ -94,6 +94,51 @@ switchUser.setExitUserMatcher(PathPatternRequestMatcher.withDefaults().matcher(H
 ----
 ======
 
+=== 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`.
+In Spring Security 7, this pattern is not allowed and will change to using `PathPatternRequestMatcher`.
+Also in Spring Security 7m the URL should by absolute, excluding any context path, like so: `/proxy/receptor`.
+
+So to prepare for these change, you can use `setProxyReceptorRequestMatcher` instead of `setProxyReceptorUrl`.
+
+That is, change this:
+[tabs]
+======
+Java::
++
+[source,java,role="primary"]
+----
+casAuthentication.setProxyReceptorUrl("/proxy/receptor");
+----
+
+Kotlin::
++
+[source,kotlin,role="secondary"]
+----
+casAuthentication.setProxyReceptorUrl("/proxy/receptor")
+----
+======
+
+to this:
+
+[tabs]
+======
+Java::
++
+[source,java,role="primary"]
+----
+casAuthentication.setProxyReceptorUrl(PathPatternRequestMatcher.withDefaults().matcher("/proxy/receptor"));
+----
+
+Kotlin::
++
+[source,kotlin,role="secondary"]
+----
+casAuthentication.setProxyReceptorUrl(PathPatternRequestMatcher.withDefaults().matcher("/proxy/receptor"))
+----
+======
+
 == Include the Servlet Path Prefix in Authorization Rules
 
 For many applications <<use-path-pattern, the above>> will make no difference since most commonly all URIs listed are matched by the default servlet.