spring-projects / spring-projects/spring-security
WebInvocationPrivilegeEvaluator throws UnsupportedOperationException when a dispatcherTypeMatcher is configured.
Nobody has claimed this yet.
- Dominant language
- Java
- Stars
- 9.6k
- Forks
- 6.3k
- Avg merge
- 2d 11h
- Merged PRs (30d)
- 52
Description
Describe the bug
We are using a WebInvocationPrivilegeEvaluator to evaluate if a user has access to some paths.
After upgrading Spring Security from 6.5.10 to 7.0.4, this now throws a java.lang.UnsupportedOperationException.
To Reproduce
Configure some dispatcherTypeMatcher in your HttpSecurity.
For instance:
httpSecurity.authorizeHttpRequests(authorizedRequests ->
authorizedRequests.dispatcherTypeMatchers(DispatcherType.ERROR, DispatcherType.FORWARD)
.permitAll());
Create a controller, and let Spring inject a WebInvocationPrivilegeEvaluator bean:
@RestController
@RequestMapping("/check-access")
public class MyController {
private final WebInvocationPrivilegeEvaluator privilegeEvaluator;
@Autowired
public MyController(WebInvocationPrivilegeEvaluator aPrivilegeEvaluator) {
privilegeEvaluator = aPrivilegeEvaluator;
}
@GetMapping("/anonymous")
public boolean checkAnonymousAccess() {
return privilegeEvaluator.isAllowed("/foo", new AnonymousAuthenticationToken("anonymous", "anonymous", List.of()));
}
}
Expected behavior
A working check that validates if the path is allowed according to the configured access rules in the HttpSecurity bean.
Actual behavior
java.lang.UnsupportedOperationException: public abstract jakarta.servlet.DispatcherType jakarta.servlet.ServletRequest.getDispatcherType() is not supported
at org.springframework.security.web.FilterInvocation$UnsupportedOperationExceptionInvocationHandler.invoke(FilterInvocation.java:332)
at jdk.proxy3/jdk.proxy3.$Proxy241.getDispatcherType(Unknown Source)
at jakarta.servlet.ServletRequestWrapper.getDispatcherType(ServletRequestWrapper.java:438)
at jakarta.servlet.ServletRequestWrapper.getDispatcherType(ServletRequestWrapper.java:438)
at org.springframework.security.web.util.matcher.DispatcherTypeRequestMatcher.matches(DispatcherTypeRequestMatcher.java:72)
at org.springframework.security.web.util.matcher.RequestMatcher.matcher(RequestMatcher.java:49)
at org.springframework.security.web.access.intercept.RequestMatcherDelegatingAuthorizationManager.authorize(RequestMatcherDelegatingAuthorizationManager.java:75)
at org.springframework.security.web.access.intercept.RequestMatcherDelegatingAuthorizationManager.authorize(RequestMatcherDelegatingAuthorizationManager.java:52)
at org.springframework.security.authorization.ObservationAuthorizationManager.authorize(ObservationAuthorizationManager.java:75)
at org.springframework.security.config.annotation.web.builders.WebSecurity.lambda$addAuthorizationManager$2(WebSecurity.java:384)
at org.springframework.security.web.access.intercept.RequestMatcherDelegatingAuthorizationManager.authorize(RequestMatcherDelegatingAuthorizationManager.java:82)
at org.springframework.security.web.access.intercept.RequestMatcherDelegatingAuthorizationManager.authorize(RequestMatcherDelegatingAuthorizationManager.java:52)
at org.springframework.security.web.access.AuthorizationManagerWebInvocationPrivilegeEvaluator.isAllowed(AuthorizationManagerWebInvocationPrivilegeEvaluator.java:62)
at org.springframework.security.web.access.AuthorizationManagerWebInvocationPrivilegeEvaluator.isAllowed(AuthorizationManagerWebInvocationPrivilegeEvaluator.java:54)
at org.springframework.security.web.access.RequestMatcherDelegatingWebInvocationPrivilegeEvaluator.isAllowed(RequestMatcherDelegatingWebInvocationPrivilegeEvaluator.java:82)
at com.test.MyController.checkAnonymousAccess(Unknown Source)
Evaluation
The reason this worked with Spring Security 6.5.10 is that in that version, the HandlerMappingIntrospectorRequestTransformer is used to transform the request. That transformer returns a CacheableRequestWrapper that always returns REQUEST as DispatcherType. In Spring Security 7.0.4, this class no longer exist and the DispatcherType is retrieved from the FilterInvocation.DummyRequest class, which throws an UnsupportedOperationException.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with AuthorizationManagerWebInvocationPrivilegeEvaluator, RequestMatcherDelegatingWebInvocationPrivilegeEvaluator, and FilterInvocation.DummyRequest, then reproduce the dispatcherTypeMatchers case from the issue. Trace how the request is transformed before DispatcherTypeRequestMatcher runs; done means WebInvocationPrivilegeEvaluator no longer throws and correctly evaluates the configured access rules.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- java, spring
- Domain
- security
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 55/100