Add RequestMatcher Migration Path for CAS

Issue gh-16417
This commit is contained in:
Josh Cummings 2025-03-26 15:33:45 -06:00
parent 15d9c13984
commit 91ee5e7f2b
No known key found for this signature in database
GPG Key ID: 869B37A20E876129
3 changed files with 77 additions and 0 deletions

View File

@ -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);
}

View File

@ -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();
}
}

View File

@ -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.