Skip to content

RequestMatcherDelegatingWebInvocationPrivilegeEvaluator fails with PathPatternRequestMatcher #16771

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

Closed
rwinch opened this issue Mar 19, 2025 · 1 comment
Assignees
Labels
in: web An issue in web modules (web, webmvc) type: bug A general bug
Milestone

Comments

@rwinch
Copy link
Member

rwinch commented Mar 19, 2025

When using WebInvocationPrivilegeEvaluator(e.g. Theymeleaf Security or JSP Taglibs) with PathPatternRequestMatcher it fails with the following exception:

IllegalArgumentException: Expected parsed RequestPath in request attribute "org.springframework.web.util.ServletRequestPathUtils.PATH".
	at org.springframework.util.Assert.notNull(Assert.java:200) ~[spring-core-6.2.5-SNAPSHOT.jar:6.2.5-SNAPSHOT]
	at org.springframework.web.util.ServletRequestPathUtils.getParsedRequestPath(ServletRequestPathUtils.java:78) ~[spring-web-6.2.5-SNAPSHOT.jar:6.2.5-SNAPSHOT]
	at org.springframework.security.web.servlet.util.matcher.PathPatternRequestMatcher.getRequestPath(PathPatternRequestMatcher.java:130) ~[spring-security-web-6.5.0-M3.jar:6.5.0-M3]
	at org.springframework.security.web.servlet.util.matcher.PathPatternRequestMatcher.matcher(PathPatternRequestMatcher.java:116) ~[spring-security-web-6.5.0-M3.jar:6.5.0-M3]
	at org.springframework.security.web.access.intercept.RequestMatcherDelegatingAuthorizationManager.check(RequestMatcherDelegatingAuthorizationManager.java:83) ~[spring-security-web-6.5.0-M3.jar:6.5.0-M3]
	at org.springframework.security.web.access.intercept.RequestMatcherDelegatingAuthorizationManager.check(RequestMatcherDelegatingAuthorizationManager.java:50) ~[spring-security-web-6.5.0-M3.jar:6.5.0-M3]
	at org.springframework.security.authorization.AuthorizationManager.authorize(AuthorizationManager.java:69) ~[spring-security-core-6.5.0-M3.jar:6.5.0-M3]
	at org.springframework.security.web.access.AuthorizationManagerWebInvocationPrivilegeEvaluator.isAllowed(AuthorizationManagerWebInvocationPrivilegeEvaluator.java:60) ~[spring-security-web-6.5.0-M3.jar:6.5.0-M3]
	at org.springframework.security.web.access.RequestMatcherDelegatingWebInvocationPrivilegeEvaluator.isAllowed(RequestMatcherDelegatingWebInvocationPrivilegeEvaluator.java:109) ~[spring-security-web-6.5.0-M3.jar:6.5.0-M3]
	at org.thymeleaf.extras.springsecurity6.auth.AuthUtils$MvcAuthUtils.authorizeUsingUrlCheckMvc(AuthUtils.java:362) ~[thymeleaf-extras-springsecurity6-3.1.3.RELEASE.jar:3.1.3.RELEASE]
	at org.thymeleaf.extras.springsecurity6.auth.AuthUtils$MvcAuthUtils.access$300(AuthUtils.java:304) ~[thymeleaf-extras-springsecurity6-3.1.3.RELEASE.jar:3.1.3.RELEASE]
	at org.thymeleaf.extras.springsecurity6.auth.AuthUtils.authorizeUsingUrlCheck(AuthUtils.java:236) ~[thymeleaf-extras-springsecurity6-3.1.3.RELEASE.jar:3.1.3.RELEASE]
	at org.thymeleaf.extras.springsecurity6.dialect.processor.AuthorizeUrlAttrProcessor.isVisible(AuthorizeUrlAttrProcessor.java:74) ~[thymeleaf-extras-springsecurity6-3.1.3.RELEASE.jar:3.1.3.RELEASE]
	at org.thymeleaf.standard.processor.AbstractStandardConditionalVisibilityTagProcessor.doProcess(AbstractStandardConditionalVisibilityTagProcessor.java:61) ~[thymeleaf-3.1.3.RELEASE.jar:3.1.3.RELEASE]
	at org.thymeleaf.processor.element.AbstractAttributeTagProcessor.doProcess(AbstractAttributeTagProcessor.java:74) ~[thymeleaf-3.1.3.RELEASE.jar:3.1.3.RELEASE]
	at org.thymeleaf.processor.element.AbstractElementTagProcessor.process(AbstractElementTagProcessor.java:95) ~[thymeleaf-3.1.3.RELEASE.jar:3.1.3.RELEASE]
	at org.thymeleaf.util.ProcessorConfigurationUtils$ElementTagProcessorWrapper.process(ProcessorConfigurationUtils.java:633) ~[thymeleaf-3.1.3.RELEASE.jar:3.1.3.RELEASE]
	at org.thymeleaf.engine.ProcessorTemplateHandler.handleOpenElement(ProcessorTemplateHandler.java:1314) ~[thymeleaf-3.1.3.RELEASE.jar:3.1.3.RELEASE]
	at org.thymeleaf.engine.OpenElementTag.beHandled(OpenElementTag.java:205) ~[thymeleaf-3.1.3.RELEASE.jar:3.1.3.RELEASE]
	at org.thymeleaf.engine.TemplateModel.process(TemplateModel.java:136) ~[thymeleaf-3.1.3.RELEASE.jar:3.1.3.RELEASE]
	at org.thymeleaf.engine.TemplateManager.parseAndProcess(TemplateManager.java:661) ~[thymeleaf-3.1.3.RELEASE.jar:3.1.3.RELEASE]
	at org.thymeleaf.TemplateEngine.process(TemplateEngine.java:1103) ~[thymeleaf-3.1.3.RELEASE.jar:3.1.3.RELEASE]
	at org.thymeleaf.TemplateEngine.process(TemplateEngine.java:1077) ~[thymeleaf-3.1.3.RELEASE.jar:3.1.3.RELEASE]
	at org.thymeleaf.spring6.view.ThymeleafView.renderFragment(ThymeleafView.java:372) ~[thymeleaf-spring6-3.1.3.RELEASE.jar:3.1.3.RELEASE]
	at org.thymeleaf.spring6.view.ThymeleafView.render(ThymeleafView.java:192) ~[thymeleaf-spring6-3.1.3.RELEASE.jar:3.1.3.RELEASE]
	at org.springframework.web.servlet.DispatcherServlet.render(DispatcherServlet.java:1437) ~[spring-webmvc-6.2.5-SNAPSHOT.jar:6.2.5-SNAPSHOT]
	at org.springframework.web.servlet.DispatcherServlet.processDispatchResult(DispatcherServlet.java:1168) ~[spring-webmvc-6.2.5-SNAPSHOT.jar:6.2.5-SNAPSHOT]
	at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1106) ~[spring-webmvc-6.2.5-SNAPSHOT.jar:6.2.5-SNAPSHOT]
	at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:979) ~[spring-webmvc-6.2.5-SNAPSHOT.jar:6.2.5-SNAPSHOT]
	at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1014) ~[spring-webmvc-6.2.5-SNAPSHOT.jar:6.2.5-SNAPSHOT]
	at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:903) ~[spring-webmvc-6.2.5-SNAPSHOT.jar:6.2.5-SNAPSHOT]
	at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:564) ~[tomcat-embed-core-10.1.39.jar:6.0]
	at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:885) ~[spring-webmvc-6.2.5-SNAPSHOT.jar:6.2.5-SNAPSHOT]
	at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:658) ~[tomcat-embed-core-10.1.39.jar:6.0]
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:195) ~[tomcat-embed-core-10.1.39.jar:10.1.39]
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:140) ~[tomcat-embed-core-10.1.39.jar:10.1.39]
	at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:51) ~[tomcat-embed-websocket-10.1.39.jar:10.1.39]
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:164) ~[tomcat-embed-core-10.1.39.jar:10.1.39]
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:140) ~[tomcat-embed-core-10.1.39.jar:10.1.39]
	at org.springframework.web.filter.CompositeFilter$VirtualFilterChain.doFilter(CompositeFilter.java:108) ~[spring-web-6.2.5-SNAPSHOT.jar:6.2.5-SNAPSHOT]
	at org.springframework.security.web.FilterChainProxy.lambda$doFilterInternal$3(FilterChainProxy.java:235) ~[spring-security-web-6.5.0-M3.jar:6.5.0-M3]
	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:370) ~[spring-security-web-6.5.0-M3.jar:6.5.0-M3]
	at org.springframework.security.web.access.intercept.AuthorizationFilter.doFilter(AuthorizationFilter.java:101) ~[spring-security-web-6.5.0-M3.jar:6.5.0-M3]
	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:379) ~[spring-security-web-6.5.0-M3.jar:6.5.0-M3]
	at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:126) ~[spring-security-web-6.5.0-M3.jar:6.5.0-M3]
	at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:120) ~[spring-security-web-6.5.0-M3.jar:6.5.0-M3]
	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:379) ~[spring-security-web-6.5.0-M3.jar:6.5.0-M3]
	at org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:100) ~[spring-security-web-6.5.0-M3.jar:6.5.0-M3]
	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:379) ~[spring-security-web-6.5.0-M3.jar:6.5.0-M3]
	at org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:179) ~[spring-security-web-6.5.0-M3.jar:6.5.0-M3]
	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:379) ~[spring-security-web-6.5.0-M3.jar:6.5.0-M3]
	at org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:63) ~[spring-security-web-6.5.0-M3.jar:6.5.0-M3]
	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:379) ~[spring-security-web-6.5.0-M3.jar:6.5.0-M3]
	at org.springframework.security.web.authentication.www.BasicAuthenticationFilter.doFilterInternal(BasicAuthenticationFilter.java:181) ~[spring-security-web-6.5.0-M3.jar:6.5.0-M3]
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) ~[spring-web-6.2.5-SNAPSHOT.jar:6.2.5-SNAPSHOT]
	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:379) ~[spring-security-web-6.5.0-M3.jar:6.5.0-M3]
	at org.springframework.security.web.authentication.ui.DefaultLogoutPageGeneratingFilter.doFilterInternal(DefaultLogoutPageGeneratingFilter.java:58) ~[spring-security-web-6.5.0-M3.jar:6.5.0-M3]
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) ~[spring-web-6.2.5-SNAPSHOT.jar:6.2.5-SNAPSHOT]
	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:379) ~[spring-security-web-6.5.0-M3.jar:6.5.0-M3]
	at org.springframework.security.web.authentication.ui.DefaultLoginPageGeneratingFilter.doFilter(DefaultLoginPageGeneratingFilter.java:216) ~[spring-security-web-6.5.0-M3.jar:6.5.0-M3]
	at org.springframework.security.web.authentication.ui.DefaultLoginPageGeneratingFilter.doFilter(DefaultLoginPageGeneratingFilter.java:202) ~[spring-security-web-6.5.0-M3.jar:6.5.0-M3]
	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:379) ~[spring-security-web-6.5.0-M3.jar:6.5.0-M3]
	at org.springframework.security.web.authentication.ui.DefaultResourcesFilter.doFilter(DefaultResourcesFilter.java:72) ~[spring-security-web-6.5.0-M3.jar:6.5.0-M3]
	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:379) ~[spring-security-web-6.5.0-M3.jar:6.5.0-M3]
	at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:227) ~[spring-security-web-6.5.0-M3.jar:6.5.0-M3]
	at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:221) ~[spring-security-web-6.5.0-M3.jar:6.5.0-M3]
	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:379) ~[spring-security-web-6.5.0-M3.jar:6.5.0-M3]
	at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:107) ~[spring-security-web-6.5.0-M3.jar:6.5.0-M3]
	at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:93) ~[spring-security-web-6.5.0-M3.jar:6.5.0-M3]
	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:379) ~[spring-security-web-6.5.0-M3.jar:6.5.0-M3]
	at org.springframework.security.web.csrf.CsrfFilter.doFilterInternal(CsrfFilter.java:117) ~[spring-security-web-6.5.0-M3.jar:6.5.0-M3]
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) ~[spring-web-6.2.5-SNAPSHOT.jar:6.2.5-SNAPSHOT]
	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:379) ~[spring-security-web-6.5.0-M3.jar:6.5.0-M3]
	at org.springframework.security.web.header.HeaderWriterFilter.doHeadersAfter(HeaderWriterFilter.java:90) ~[spring-security-web-6.5.0-M3.jar:6.5.0-M3]
	at org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:75) ~[spring-security-web-6.5.0-M3.jar:6.5.0-M3]
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) ~[spring-web-6.2.5-SNAPSHOT.jar:6.2.5-SNAPSHOT]
	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:379) ~[spring-security-web-6.5.0-M3.jar:6.5.0-M3]
	at org.springframework.security.web.context.SecurityContextHolderFilter.doFilter(SecurityContextHolderFilter.java:82) ~[spring-security-web-6.5.0-M3.jar:6.5.0-M3]
	at org.springframework.security.web.context.SecurityContextHolderFilter.doFilter(SecurityContextHolderFilter.java:69) ~[spring-security-web-6.5.0-M3.jar:6.5.0-M3]
	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:379) ~[spring-security-web-6.5.0-M3.jar:6.5.0-M3]
	at org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:62) ~[spring-security-web-6.5.0-M3.jar:6.5.0-M3]
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) ~[spring-web-6.2.5-SNAPSHOT.jar:6.2.5-SNAPSHOT]
	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:379) ~[spring-security-web-6.5.0-M3.jar:6.5.0-M3]
	at org.springframework.security.web.session.DisableEncodeUrlFilter.doFilterInternal(DisableEncodeUrlFilter.java:42) ~[spring-security-web-6.5.0-M3.jar:6.5.0-M3]
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) ~[spring-web-6.2.5-SNAPSHOT.jar:6.2.5-SNAPSHOT]
	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:379) ~[spring-security-web-6.5.0-M3.jar:6.5.0-M3]
	at org.springframework.security.web.FilterChainProxy.lambda$doFilterInternal$4(FilterChainProxy.java:237) ~[spring-security-web-6.5.0-M3.jar:6.5.0-M3]
	at org.springframework.web.filter.ServletRequestPathFilter.doFilter(ServletRequestPathFilter.java:52) ~[spring-web-6.2.5-SNAPSHOT.jar:6.2.5-SNAPSHOT]
	at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:216) ~[spring-security-web-6.5.0-M3.jar:6.5.0-M3]
	at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:194) ~[spring-security-web-6.5.0-M3.jar:6.5.0-M3]
	at org.springframework.web.filter.CompositeFilter$VirtualFilterChain.doFilter(CompositeFilter.java:113) ~[spring-web-6.2.5-SNAPSHOT.jar:6.2.5-SNAPSHOT]
	at org.springframework.web.servlet.handler.HandlerMappingIntrospector.lambda$createCacheFilter$3(HandlerMappingIntrospector.java:243) ~[spring-webmvc-6.2.5-SNAPSHOT.jar:6.2.5-SNAPSHOT]
	at org.springframework.web.filter.CompositeFilter$VirtualFilterChain.doFilter(CompositeFilter.java:113) ~[spring-web-6.2.5-SNAPSHOT.jar:6.2.5-SNAPSHOT]
	at org.springframework.web.filter.CompositeFilter.doFilter(CompositeFilter.java:74) ~[spring-web-6.2.5-SNAPSHOT.jar:6.2.5-SNAPSHOT]
	at org.springframework.security.config.annotation.web.configuration.WebMvcSecurityConfiguration$CompositeFilterChainProxy.doFilter(WebMvcSecurityConfiguration.java:238) ~[spring-security-config-6.5.0-M3.jar:6.5.0-M3]
	at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:362) ~[spring-web-6.2.5-SNAPSHOT.jar:6.2.5-SNAPSHOT]
	at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:278) ~[spring-web-6.2.5-SNAPSHOT.jar:6.2.5-SNAPSHOT]
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:164) ~[tomcat-embed-core-10.1.39.jar:10.1.39]
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:140) ~[tomcat-embed-core-10.1.39.jar:10.1.39]
	at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100) ~[spring-web-6.2.5-SNAPSHOT.jar:6.2.5-SNAPSHOT]
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) ~[spring-web-6.2.5-SNAPSHOT.jar:6.2.5-SNAPSHOT]
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:164) ~[tomcat-embed-core-10.1.39.jar:10.1.39]
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:140) ~[tomcat-embed-core-10.1.39.jar:10.1.39]
	at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93) ~[spring-web-6.2.5-SNAPSHOT.jar:6.2.5-SNAPSHOT]
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) ~[spring-web-6.2.5-SNAPSHOT.jar:6.2.5-SNAPSHOT]
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:164) ~[tomcat-embed-core-10.1.39.jar:10.1.39]
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:140) ~[tomcat-embed-core-10.1.39.jar:10.1.39]
	at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201) ~[spring-web-6.2.5-SNAPSHOT.jar:6.2.5-SNAPSHOT]
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) ~[spring-web-6.2.5-SNAPSHOT.jar:6.2.5-SNAPSHOT]
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:164) ~[tomcat-embed-core-10.1.39.jar:10.1.39]
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:140) ~[tomcat-embed-core-10.1.39.jar:10.1.39]
	at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:167) ~[tomcat-embed-core-10.1.39.jar:10.1.39]
	at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:90) ~[tomcat-embed-core-10.1.39.jar:10.1.39]
	at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:483) ~[tomcat-embed-core-10.1.39.jar:10.1.39]
	at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:115) ~[tomcat-embed-core-10.1.39.jar:10.1.39]
	at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:93) ~[tomcat-embed-core-10.1.39.jar:10.1.39]
	at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74) ~[tomcat-embed-core-10.1.39.jar:10.1.39]
	at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:344) ~[tomcat-embed-core-10.1.39.jar:10.1.39]
	at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:397) ~[tomcat-embed-core-10.1.39.jar:10.1.39]
	at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:63) ~[tomcat-embed-core-10.1.39.jar:10.1.39]
	at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:905) ~[tomcat-embed-core-10.1.39.jar:10.1.39]
	at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1743) ~[tomcat-embed-core-10.1.39.jar:10.1.39]
	at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:52) ~[tomcat-embed-core-10.1.39.jar:10.1.39]
	at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1190) ~[tomcat-embed-core-10.1.39.jar:10.1.39]
	at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659) ~[tomcat-embed-core-10.1.39.jar:10.1.39]
	at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:63) ~[tomcat-embed-core-10.1.39.jar:10.1.39]
	at java.base/java.lang.Thread.run(Thread.java:840) ~[na:na]

@rwinch rwinch added status: waiting-for-triage An issue we've not yet triaged type: bug A general bug in: web An issue in web modules (web, webmvc) and removed status: waiting-for-triage An issue we've not yet triaged labels Mar 19, 2025
@rwinch rwinch added this to the 6.5.0-RC1 milestone Mar 19, 2025
@rwinch rwinch self-assigned this Mar 19, 2025
jzheaux added a commit that referenced this issue Mar 21, 2025
In this way PathPatternRequestMatcher won't need to reparse for each
request matcher.

Issue gh-16771
jzheaux added a commit that referenced this issue Mar 21, 2025
@mcollovati
Copy link

mcollovati commented Jun 9, 2025

Maybe not exactly the same issue, but I still get a failure in 6.5.0 when using RequestMatcherDelegatingWebInvocationPrivilegeEvaluator together with PathPatternRequestMatcher.isAllowed(String uri, Authentication authentication); when the method is invoked a UnsupportedOperationException is thrown by FilterInvokation.DummyRequest.setAttribute class, called by ServletRequestPathUtils.parseAndCache.
The issue originates from AuthorizationManagerWebInvocationPrivilegeEvaluator that creates the FilterInvocation instance that in turn returns the DummyRequest passed to the AuthorizationManager

StackTrace
java.lang.UnsupportedOperationException: public abstract void jakarta.servlet.ServletRequest.setAttribute(java.lang.String,java.lang.Object) is not supported

  at org.springframework.security.web.FilterInvocation$UnsupportedOperationExceptionInvocationHandler.invoke(FilterInvocation.java:331)
  at jdk.proxy2/jdk.proxy2.$Proxy78.setAttribute(Unknown Source)
  at jakarta.servlet.ServletRequestWrapper.setAttribute(ServletRequestWrapper.java:238)
  at org.springframework.web.util.ServletRequestPathUtils.parseAndCache(ServletRequestPathUtils.java:68)
  at org.springframework.security.web.servlet.util.matcher.PathPatternRequestMatcher.getPathContainer(PathPatternRequestMatcher.java:126)
  at org.springframework.security.web.servlet.util.matcher.PathPatternRequestMatcher.matcher(PathPatternRequestMatcher.java:111)
  at org.springframework.security.web.access.intercept.RequestMatcherDelegatingAuthorizationManager.check(RequestMatcherDelegatingAuthorizationManager.java:83)
  at org.springframework.security.web.access.intercept.RequestMatcherDelegatingAuthorizationManager.check(RequestMatcherDelegatingAuthorizationManager.java:50)
  at org.springframework.security.authorization.AuthorizationManager.authorize(AuthorizationManager.java:69)
  at org.springframework.security.config.annotation.web.builders.WebSecurity.lambda$addAuthorizationManager$3(WebSecurity.java:389)
  at org.springframework.security.web.access.intercept.RequestMatcherDelegatingAuthorizationManager.check(RequestMatcherDelegatingAuthorizationManager.java:90)
  at org.springframework.security.web.access.intercept.RequestMatcherDelegatingAuthorizationManager.check(RequestMatcherDelegatingAuthorizationManager.java:50)
  at org.springframework.security.authorization.AuthorizationManager.authorize(AuthorizationManager.java:69)
  at org.springframework.security.web.access.AuthorizationManagerWebInvocationPrivilegeEvaluator.isAllowed(AuthorizationManagerWebInvocationPrivilegeEvaluator.java:60)
  at org.springframework.security.web.access.AuthorizationManagerWebInvocationPrivilegeEvaluator.isAllowed(AuthorizationManagerWebInvocationPrivilegeEvaluator.java:53)
  at org.springframework.security.web.access.RequestMatcherDelegatingWebInvocationPrivilegeEvaluator.isAllowed(RequestMatcherDelegatingWebInvocationPrivilegeEvaluator.java:81)
  at com.vaadin.flow.spring.security.MyTest.testWebInvocationPrivilegeEvaluator(MyTest.java:44)
  at java.base/java.lang.reflect.Method.invoke(Method.java:569)
  at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
  at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)

A simple test case that reproduces the problem

@SpringJUnitWebConfig
@ContextConfiguration(classes = MyTest.TestConfig.class)
public class MyTest {

    @Autowired
    WebInvocationPrivilegeEvaluator evaluator;

    @Test
    void testWebInvocationPrivilegeEvaluator() {
        evaluator.isAllowed("/admin", new UsernamePasswordAuthenticationToken(
                "user", "password", List.of()));
    }

    @Configuration
    @EnableWebSecurity
    public static class TestConfig {

        @Bean
        public SecurityFilterChain testingFilterChain(HttpSecurity http)
                throws Exception {
            var matcherBuilder = PathPatternRequestMatcher.withDefaults();
            http.authorizeHttpRequests(cfg -> cfg
                    .requestMatchers(matcherBuilder.matcher("/admin/**"))
                    .hasRole("ADMIN")
                    .requestMatchers(matcherBuilder.matcher("/public/**"))
                    .permitAll());
            return http.build();
        }
    }
}

EDIT: perhaps is just an issue in the test setup; exposing PathPatternRequestTransformer as a bean fixes the problem.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
in: web An issue in web modules (web, webmvc) type: bug A general bug
Projects
None yet
Development

No branches or pull requests

2 participants