Skip to content

Commit 15d9c13

Browse files
committed
Add RequestMatcher MigrationPath for SwitchUserFilter
To simplify migration, the filter's setter methods still use AntPathRequestMatcher. Users can call the equivalent RequestMatcher setter methods to opt-in to the change early. Issue gh-16417
1 parent 1eec51a commit 15d9c13

File tree

2 files changed

+53
-12
lines changed

2 files changed

+53
-12
lines changed

docs/modules/ROOT/pages/migration/web.adoc

Lines changed: 43 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -42,21 +42,57 @@ This will tell the Spring Security DSL to use `PathPatternRequestMatcher` for al
4242

4343
In the event that you are directly constructing an object (as opposed to having the DSL construct it) that has a `setRequestMatcher` method. you should also proactively specify a `PathPatternRequestMatcher` there as well.
4444

45-
For example, in the case of `LogoutFilter`, it constructs an `AntPathRequestMatcher` in Spring Security 6:
45+
=== Migrate `exitUserUrl` and `switchUserUrl` Request Matchers in `SwitchUserFilter`
4646

47-
[method,java]
47+
`SwitchUserFilter`, constructs an `AntPathRequestMatcher` in its `setExitUserUrl` and `setSwitchUserUrl` methods.
48+
This will change to use `PathPatternRequestMatcher` in Spring Security 7.
49+
50+
To prepare for this change, call `setExitUserMatcher` and `setSwithcUserMatcher` to provide this `PathPatternRequestMatcher` in advance.
51+
That is, change this:
52+
53+
[tabs]
54+
======
55+
Java::
56+
+
57+
[source,java,role="primary"]
4858
----
49-
private RequestMatcher logoutUrl = new AntPathRequestMatcher("/logout");
59+
SwitchUserFilter switchUser = new SwitchUserFilter();
60+
// ... other configuration
61+
switchUser.setExitUserUrl("/exit/impersonate");
5062
----
5163
52-
and will change this to a `PathPatternRequestMatcher` in 7:
64+
Kotlin::
65+
+
66+
[source,kotlin,role="secondary"]
67+
----
68+
val switchUser = SwitchUserFilter()
69+
// ... other configuration
70+
switchUser.setExitUserUrl("/exit/impersonate")
71+
----
72+
======
5373

54-
[method,java]
74+
to this:
75+
76+
[tabs]
77+
======
78+
Java::
79+
+
80+
[source,java,role="primary"]
5581
----
56-
private RequestMatcher logoutUrl = PathPatternRequestMatcher.path().matcher("/logout");
82+
SwitchUserFilter switchUser = new SwitchUserFilter();
83+
// ... other configuration
84+
switchUser.setExitUserMatcher(PathPatternRequestMatcher.withDefaults().matcher(HttpMethod.POST, "/exit/impersonate"));
5785
----
5886
59-
If you are constructing your own `LogoutFilter`, consider calling `setLogoutRequestMatcher` to provide this `PathPatternRequestMatcher` in advance.
87+
Kotlin::
88+
+
89+
[source,kotlin,role="secondary"]
90+
----
91+
val switchUser = SwitchUserFilter()
92+
// ... other configuration
93+
switchUser.setExitUserMatcher(PathPatternRequestMatcher.withDefaults().matcher(HttpMethod.POST, "/exit/impersonate"))
94+
----
95+
======
6096

6197
== Include the Servlet Path Prefix in Authorization Rules
6298

web/src/main/java/org/springframework/security/web/authentication/switchuser/SwitchUserFilter.java

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
import org.springframework.context.MessageSourceAware;
3636
import org.springframework.context.support.MessageSourceAccessor;
3737
import org.springframework.core.log.LogMessage;
38+
import org.springframework.http.HttpMethod;
3839
import org.springframework.security.authentication.AccountExpiredException;
3940
import org.springframework.security.authentication.AccountStatusUserDetailsChecker;
4041
import org.springframework.security.authentication.AuthenticationCredentialsNotFoundException;
@@ -62,6 +63,7 @@
6263
import org.springframework.security.web.context.HttpSessionSecurityContextRepository;
6364
import org.springframework.security.web.context.RequestAttributeSecurityContextRepository;
6465
import org.springframework.security.web.context.SecurityContextRepository;
66+
import org.springframework.security.web.servlet.util.matcher.PathPatternRequestMatcher;
6567
import org.springframework.security.web.util.UrlUtils;
6668
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
6769
import org.springframework.security.web.util.matcher.RequestMatcher;
@@ -127,9 +129,9 @@ public class SwitchUserFilter extends GenericFilterBean implements ApplicationEv
127129

128130
protected MessageSourceAccessor messages = SpringSecurityMessageSource.getAccessor();
129131

130-
private RequestMatcher exitUserMatcher = createMatcher("/logout/impersonate");
132+
private RequestMatcher exitUserMatcher = createMatcher("/logout/impersonate", true);
131133

132-
private RequestMatcher switchUserMatcher = createMatcher("/login/impersonate");
134+
private RequestMatcher switchUserMatcher = createMatcher("/login/impersonate", true);
133135

134136
private String targetUrl;
135137

@@ -406,7 +408,7 @@ public void setUserDetailsService(UserDetailsService userDetailsService) {
406408
public void setExitUserUrl(String exitUserUrl) {
407409
Assert.isTrue(UrlUtils.isValidRedirectUrl(exitUserUrl),
408410
"exitUserUrl cannot be empty and must be a valid redirect URL");
409-
this.exitUserMatcher = createMatcher(exitUserUrl);
411+
this.exitUserMatcher = createMatcher(exitUserUrl, false);
410412
}
411413

412414
/**
@@ -426,7 +428,7 @@ public void setExitUserMatcher(RequestMatcher exitUserMatcher) {
426428
public void setSwitchUserUrl(String switchUserUrl) {
427429
Assert.isTrue(UrlUtils.isValidRedirectUrl(switchUserUrl),
428430
"switchUserUrl cannot be empty and must be a valid redirect URL");
429-
this.switchUserMatcher = createMatcher(switchUserUrl);
431+
this.switchUserMatcher = createMatcher(switchUserUrl, false);
430432
}
431433

432434
/**
@@ -545,7 +547,10 @@ public void setSecurityContextRepository(SecurityContextRepository securityConte
545547
this.securityContextRepository = securityContextRepository;
546548
}
547549

548-
private static RequestMatcher createMatcher(String pattern) {
550+
private static RequestMatcher createMatcher(String pattern, boolean usePathPatterns) {
551+
if (usePathPatterns) {
552+
return PathPatternRequestMatcher.withDefaults().matcher(HttpMethod.POST, pattern);
553+
}
549554
return new AntPathRequestMatcher(pattern, "POST", true, new UrlPathHelper());
550555
}
551556

0 commit comments

Comments
 (0)