-
Notifications
You must be signed in to change notification settings - Fork 6k
FilterInvocation should support getDispatcherType() #15042
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
just ran into this myself! Using 5.8.12 with latest Spring Boot 2.7 |
Thanks for the report @chrylis, do you have a minimal, reproducible sample that we can try it out? I'd like to see how exactly the |
If you would like us to look at this issue, please provide the requested information. If the information is not provided within the next 7 days this issue will be closed. |
Closing due to lack of requested feedback. If you would like us to look at this issue, please provide the requested information and we will re-open the issue. |
Hi @marcusdacoregio. I ran into the same issue while following the migration steps for Spring Security 5.x to 6.x. Minimal reproducible sample: Steps to reproduce:
Expected Behavior:
Actual Behavior:
|
Thanks for the sample @teddy-materio. This problem is happening because the Spring Boot's @teddy-materio, to fix the error in your sample we can move the @Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
.authorizeHttpRequests()
.shouldFilterAllDispatcherTypes(true)
.requestMatchers("/demo", "/error").permitAll()
.dispatcherTypeMatchers(DispatcherType.FORWARD, DispatcherType.ERROR).permitAll()
.anyRequest().authenticated();
return http.build();
} This will make sure that we don't use the |
That worked, thank you!! Really appreciate the quick response and solution 🙏 . |
Hi @marcusdacoregio ! Here's another way to reproduce this issue: through the Here's a sample call stack which triggers the exception: Call stackinvoke:331, FilterInvocation$UnsupportedOperationExceptionInvocationHandler (org.springframework.security.web) getDispatcherType:-1, $Proxy563 (jdk.proxy3) getDispatcherType:438, ServletRequestWrapper (jakarta.servlet) matches:72, DispatcherTypeRequestMatcher (org.springframework.security.web.util.matcher) matcher:48, RequestMatcher (org.springframework.security.web.util.matcher) check:80, RequestMatcherDelegatingAuthorizationManager (org.springframework.security.web.access.intercept) check:49, RequestMatcherDelegatingAuthorizationManager (org.springframework.security.web.access.intercept) isAllowed:60, AuthorizationManagerWebInvocationPrivilegeEvaluator (org.springframework.security.web.access) isAllowed:109, RequestMatcherDelegatingWebInvocationPrivilegeEvaluator (org.springframework.security.web.access) authorizeUsingUrlCheck:148, AbstractAuthorizeTag (org.springframework.security.taglibs.authz) authorize:102, AbstractAuthorizeTag (org.springframework.security.taglibs.authz) doStartTag:70, JspAuthorizeTag (org.springframework.security.taglibs.authz) Security configuration: @Bean
public SecurityFilterChain filterChain(HttpSecurity http...) {
...
http.authorizeHttpRequests((auth) -> auth.dispatcherTypeMatchers(DispatcherType.FORWARD, DispatcherType.ERROR).permitAll();
(more request matchers)
...
} Referring back to the stack trace, a new instance of a FilterInvocation is created in @Override
public boolean isAllowed(String contextPath, String uri, String method, Authentication authentication) {
FilterInvocation filterInvocation = new FilterInvocation(contextPath, uri, method, this.servletContext);
HttpServletRequest httpRequest = this.requestTransformer.transform(filterInvocation.getHttpRequest());
AuthorizationDecision decision = this.authorizationManager.check(() -> authentication, httpRequest);
return decision == null || decision.isGranted();
} When @Override
public boolean matches(HttpServletRequest request) {
if (this.httpMethod != null && StringUtils.hasText(request.getMethod())
&& this.httpMethod != HttpMethod.valueOf(request.getMethod())) {
return false;
}
return this.dispatcherType == request.getDispatcherType();
} @Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
if (method.isDefault()) {
return invokeDefaultMethod(proxy, method, args);
}
throw new UnsupportedOperationException(method + " is not supported");
} Is it possible that there was an oversight in the design of Interestingly, though, it's only using the JspAuthorizeTag's url attribute, not its access attribute, that triggers this problem. If we use: public boolean authorize() throws IOException {
if (StringUtils.hasText(getAccess())) {
return authorizeUsingAccessExpression();
}
if (StringUtils.hasText(getUrl())) {
return authorizeUsingUrlCheck();
}
return false;
} It's |
Describe the bug
The core
HttpSecurity
builder supportsdispatcherTypeMatchers
, butFilterInvocation
throwsUnsupportedOperationException
if they are invoked.During an upgrade of an older Boot Servlet project, I ran into the problem where the Spring Boot
/error
mapping is no longer allowed by default, at least for 403 errors. I tried the suggested resolution of addingdispatcherTypeMatchers(ERROR).permitAll()
to mySecurityFilterChain
bean. This throws an exception in 5.7.11 (the default with the last Boot 2.7) and 5.8.12.The problem appears to be that
DefaultWebInvocationPrivilegeEvaluator
uses aDummyRequest
instead of the real request but does not implement core API methods; many/most other methods were supported as part of #8566.To Reproduce
dispatcherTypeMatchers(ERROR).permitAll()
in aSecurityFilterChain
.AnonymousAuthenticationToken
)Expected behavior
The matcher permits the error page to proceed.
Actual behavior
The text was updated successfully, but these errors were encountered: