Skip to content

Thymeleaf sec: Tags causes UnsupportedOperationException when WebSecurity is configured with EndpointRequestMatcher #27728

@tvahrst

Description

@tvahrst

If a WebSecurityConfiguration contains EndpointRequestMatchers, for example like this

public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
                .requestMatchers(EndpointRequest.to(HealthEndpoint.class)).permitAll()
                .anyRequest().permitAll();
    }
}

and the application uses thymeleaf templates with sec: tags - like this:

<div sec:authorize-url="/admin"> /admin is accessable</div>

any http-invocation adressing this template throws:

java.lang.UnsupportedOperationException: public abstract javax.servlet.ServletContext javax.servlet.ServletRequest.getServletContext() is not supported
	at org.springframework.security.web.FilterInvocation$UnsupportedOperationExceptionInvocationHandler.invoke(FilterInvocation.java:304) ~[spring-security-web-5.5.1.jar:5.5.1]
	at com.sun.proxy.$Proxy93.getServletContext(Unknown Source) ~[na:na]
	at javax.servlet.ServletRequestWrapper.getServletContext(ServletRequestWrapper.java:369) ~[tomcat-embed-core-9.0.50.jar:4.0.FR]
	at org.springframework.boot.security.servlet.ApplicationContextRequestMatcher.matches(ApplicationContextRequestMatcher.java:58) ~[spring-boot-2.5.3.jar:2.5.3]
	at org.springframework.security.web.access.intercept.DefaultFilterInvocationSecurityMetadataSource.getAttributes(DefaultFilterInvocationSecurityMetadataSource.java:84) ~[spring-security-web-5.5.1.jar:5.5.1]
	at org.springframework.security.web.access.DefaultWebInvocationPrivilegeEvaluator.isAllowed(DefaultWebInvocationPrivilegeEvaluator.java:87) ~[spring-security-web-5.5.1.jar:5.5.1]
	at org.thymeleaf.extras.springsecurity5.auth.AuthUtils$MvcAuthUtils.authorizeUsingUrlCheckMvc(AuthUtils.java:362) ~[thymeleaf-extras-springsecurity5-3.0.4.RELEASE.jar:3.0.4.RELEASE]
	at org.thymeleaf.extras.springsecurity5.auth.AuthUtils$MvcAuthUtils.access$300(AuthUtils.java:304) ~[thymeleaf-extras-springsecurity5-3.0.4.RELEASE.jar:3.0.4.RELEASE]
	at org.thymeleaf.extras.springsecurity5.auth.AuthUtils.authorizeUsingUrlCheck(AuthUtils.java:236) ~[thymeleaf-extras-springsecurity5-3.0.4.RELEASE.jar:3.0.4.RELEASE]
	at org.thymeleaf.extras.springsecurity5.dialect.processor.AuthorizeUrlAttrProcessor.isVisible(AuthorizeUrlAttrProcessor.java:74) ~[thymeleaf-extras-springsecurity5-3.0.4.RELEASE.jar:3.0.4.RELEASE]
	at org.thymeleaf.standard.processor.AbstractStandardConditionalVisibilityTagProcessor.doProcess(AbstractStandardConditionalVisibilityTagProcessor.java:61) ~[thymeleaf-3.0.12.RELEASE.jar:3.0.12.RELEASE]
	at org.thymeleaf.processor.element.AbstractAttributeTagProcessor.doProcess(AbstractAttributeTagProcessor.java:74) ~[thymeleaf-3.0.12.RELEASE.jar:3.0.12.RELEASE]
	at org.thymeleaf.processor.element.AbstractElementTagProcessor.process(AbstractElementTagProcessor.java:95) ~[thymeleaf-3.0.12.RELEASE.jar:3.0.12.RELEASE]
	at org.thymeleaf.util.ProcessorConfigurationUtils$ElementTagProcessorWrapper.process(ProcessorConfigurationUtils.java:633) ~[thymeleaf-3.0.12.RELEASE.jar:3.0.12.RELEASE]
	at org.thymeleaf.engine.ProcessorTemplateHandler.handleOpenElement(ProcessorTemplateHandler.java:1314) ~[thymeleaf-3.0.12.RELEASE.jar:3.0.12.RELEASE]
	at org.thymeleaf.engine.OpenElementTag.beHandled(OpenElementTag.java:205) ~[thymeleaf-3.0.12.RELEASE.jar:3.0.12.RELEASE]
	at org.thymeleaf.engine.TemplateModel.process(TemplateModel.java:136) ~[thymeleaf-3.0.12.RELEASE.jar:3.0.12.RELEASE]
	at org.thymeleaf.engine.TemplateManager.parseAndProcess(TemplateManager.java:661) ~[thymeleaf-3.0.12.RELEASE.jar:3.0.12.RELEASE]
	at org.thymeleaf.TemplateEngine.process(TemplateEngine.java:1098) ~[thymeleaf-3.0.12.RELEASE.jar:3.0.12.RELEASE]
	at org.thymeleaf.TemplateEngine.process(TemplateEngine.java:1072) ~[thymeleaf-3.0.12.RELEASE.jar:3.0.12.RELEASE]
	at org.thymeleaf.spring5.view.ThymeleafView.renderFragment(ThymeleafView.java:366) ~[thymeleaf-spring5-3.0.12.RELEASE.jar:3.0.12.RELEASE]
	at org.thymeleaf.spring5.view.ThymeleafView.render(ThymeleafView.java:190) ~[thymeleaf-spring5-3.0.12.RELEASE.jar:3.0.12.RELEASE]
	at org.springframework.web.servlet.DispatcherServlet.render(DispatcherServlet.java:1397) ~[spring-webmvc-5.3.9.jar:5.3.9]
	at org.springframework.web.servlet.DispatcherServlet.processDispatchResult(DispatcherServlet.java:1142) ~[spring-webmvc-5.3.9.jar:5.3.9]
	at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1081) ~[spring-webmvc-5.3.9.jar:5.3.9]
	at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:963) ~[spring-webmvc-5.3.9.jar:5.3.9]
	at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006) ~[spring-webmvc-5.3.9.jar:5.3.9]
	at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:898) ~[spring-webmvc-5.3.9.jar:5.3.9]
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:655) ~[tomcat-embed-core-9.0.50.jar:4.0.FR]
	at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883) ~[spring-webmvc-5.3.9.jar:5.3.9]
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:764) ~[tomcat-embed-core-9.0.50.jar:4.0.FR]
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:228) ~[tomcat-embed-core-9.0.50.jar:9.0.50]
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:163) ~[tomcat-embed-core-9.0.50.jar:9.0.50]
	at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53) ~[tomcat-embed-websocket-9.0.50.jar:9.0.50]
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:190) ~[tomcat-embed-core-9.0.50.jar:9.0.50]
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:163) ~[tomcat-embed-core-9.0.50.jar:9.0.50]

The reason: EndpointRequestMatcher is a subclass of ApplicationContextRequestMatcher and the matches Method requires a HttpServletRequest with a valid servletContext (to obtain the applicationcontext). But the concrete HttpServletRequest is an instance of FilterInvocation.DummyRequest which doesn't support 'getServletContext()'.

This is a small SpringBoot Application (web, actuator, spring-security and thymleaf) to demonstrate the problem: https://github.com/tvahrst/springboot-security-thymeleaf

URL: localhost:8080/main

Metadata

Metadata

Assignees

No one assigned

    Labels

    for: external-projectFor an external project and not something we can fixstatus: invalidAn issue that we don't feel is valid

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions