Skip to content
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

Upgrade from 2.5.7 to 2.6.x breaks use of RequestMappingHandlerMapping in Filters #28874

Closed
william00179 opened this issue Dec 1, 2021 · 12 comments
Assignees
Labels
status: invalid An issue that we don't feel is valid

Comments

@william00179
Copy link

Hi,

Working version: 2.5.7
Broken version: 2.6.x

I have a Filter that will check if the matched handler method has a particular annotation and wrap the servlet response if that is the case.

In 2.6.x requestMappingHandlerMapping.getHandler(httpServletRequest) throws

java.lang.IllegalArgumentException: Expected parsed RequestPath in request attribute "org.springframework.web.util.ServletRequestPathUtils.PATH".
	at org.springframework.util.Assert.notNull(Assert.java:201) ~[spring-core-5.3.13.jar!/:5.3.13]
	at org.springframework.web.util.ServletRequestPathUtils.getParsedRequestPath(ServletRequestPathUtils.java:77) ~[spring-web-5.3.13.jar!/:5.3.13]
	at org.springframework.web.servlet.handler.AbstractHandlerMapping.initLookupPath(AbstractHandlerMapping.java:574) ~[spring-webmvc-5.3.13.jar!/:5.3.13]
 	at org.springframework.web.servlet.handler.AbstractHandlerMethodMapping.getHandlerInternal(AbstractHandlerMethodMapping.java:380) ~[spring-webmvc-5.3.13.jar!/:5.3.13]
	at org.springframework.web.servlet.mvc.method.RequestMappingInfoHandlerMapping.getHandlerInternal(RequestMappingInfoHandlerMapping.java:125) ~[spring-webmvc-5.3.13.jar!/:5.3.13]
 	at org.springframework.web.servlet.mvc.method.RequestMappingInfoHandlerMapping.getHandlerInternal(RequestMappingInfoHandlerMapping.java:67) ~[spring-webmvc-5.3.13.jar!/:5.3.13]
	at org.springframework.web.servlet.handler.AbstractHandlerMapping.getHandler(AbstractHandlerMapping.java:498) ~[spring-webmvc-5.3.13.jar!/:5.3.13]

A minimal example of how we are using this code

@Component
@ConditionalOnWebApplication
public class DataFilter implements Filter {

 @Autowired
    private RequestMappingHandlerMapping requestMappingHandlerMapping;
    
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {

        HttpServletRequest httpServletRequest = (HttpServletRequest) request;
        HttpServletResponse httpServletResponse = (HttpServletResponse) response;
        try {
            Optional<HandlerExecutionChain> handlerExecutionChain = Optional.ofNullable(requestMappingHandlerMapping.getHandler(httpServletRequest));
            if (handlerExecutionChain.isPresent()) {
                HandlerMethod handlerMethod = (HandlerMethod) handlerExecutionChain.get().getHandler();
                if (handlerMethod.getMethod().isAnnotationPresent(MonitorData.class)) {
                    //wrap the response
                    chain.doFilter(request, wrappedResponse);
                    }
       ...
                   

I that the default matching strategy has been changed in #24805, but I've been unable to resolve this issue in my codebase.

@spring-projects-issues spring-projects-issues added the status: waiting-for-triage An issue we've not yet triaged label Dec 1, 2021
@william00179
Copy link
Author

Rolling back to the old behaviour by setting spring.mvc.pathmatch.matching-strategy=ANT_PATH_MATCHER works around this issue in the mean time.

@zifnab87
Copy link

zifnab87 commented Dec 1, 2021

Rolling back to the old behaviour by setting spring.mvc.pathmatch.matching-strategy=ANT_PATH_MATCHER works around this issue in the mean time.

This indeed is a workaround to the problem but using rest-assured with those endpoints that involve filters is still failing the tests even with this setting in my application-test.yaml .

The issue is replicated in this simple example

@Component
public class ChatBotAuthenticationFilter extends OncePerRequestFilter {

    private final RequestMappingHandlerMapping reqMap;

    public ChatBotAuthenticationFilter(RequestMappingHandlerMapping reqMap) {
        this.reqMap = reqMap;
    }

    @Override
    protected void doFilterInternal(HttpServletRequest req, HttpServletResponse res, FilterChain chain) throws IOException, ServletException {
        boolean isChatBotOnly = isEndpointChatBotOnly(req);
        //[...] custom logic
        chain.doFilter(req, res);
    }

    private boolean isEndpointChatBotOnly(HttpServletRequest req) {
        HandlerMethod method;
        try {
            // this call of reqMap.getHandler(req) throws the aforementioned exception
            method = (HandlerMethod) reqMap.getHandler(req).getHandler();
        } catch (Exception e) {
            return false;
        }

        return method.getMethod().isAnnotationPresent(ChatbotOnlyEndpoint.class);
    }
}

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface ChatbotOnlyEndpoint {
}

Here I am annotating some controller endpoints with @ChatbotOnlyEndpoint to enforce some kind of authorization filtering based on the headers that are being submitted (tokens/ids etc)

@bclozel
Copy link
Member

bclozel commented Dec 1, 2021

This path matching strategy has been available since Spring Framework 5.3 and Spring Boot 2.4 (as an option first, in #21694). This strategy will also become the new default in Spring Framework.

The problem here is that those custom Servlet filters are leveraging the RequestMappingHandlerMapping without adapting to the changes made in Spring Framework 5.3.

To avoid parsing the request path (for efficient matching) multiple times per request, this is done once and cached as a request attribute. At the time those filters process the request, this hasn't been done yet. This is usually done by the DispatcherServlet itself or by a ServletRequestPathFilter, as explained in AbsractHandlerMapping's javadoc.

I'd suggest to ways to fix the filter implementation:

  • check if the new path matching is configured with org.springframework.web.servlet.handler.AbstractHandlerMapping#getPatternParser and manually populate the cached request path with org.springframework.web.util.ServletRequestPathUtils#parseAndCache in your filter
  • or simply declare a ServletRequestPathFilter ahead of your filter

This issue is really about adapting custom code to the new path matching - changing the default in Spring Boot merely brought an existing problem to your attention. I'm closing this issue as a result. Thanks!

@bclozel bclozel closed this as completed Dec 1, 2021
@bclozel bclozel self-assigned this Dec 1, 2021
@bclozel bclozel added status: invalid An issue that we don't feel is valid and removed status: waiting-for-triage An issue we've not yet triaged labels Dec 1, 2021
@bclozel
Copy link
Member

bclozel commented Dec 1, 2021

As an additional comment, I'd like to add that RequestMappingHandlerMapping is really a strategy for the DispatcherServlet, so using it outside of that scope is not supported and considered as a bad practice. The solution I've provided in my previous comment is really a workaround and further changes should be considered in custom filters doing this.

Without knowing more about the use case, it's hard to point to alternatives. Maybe a org.springframework.web.servlet.HandlerInterceptor would be a better choice? In the interest of keeping questions outside of the Spring Boot issue tracker, feel free to ask questions on StackOverflow and report the link back here.

@zifnab87
Copy link

zifnab87 commented Dec 28, 2021

@bclozel Thanks for your suggestions! I tried the first suggestion and this is what I changed:

I added these lines

     if (!ServletRequestPathUtils.hasParsedRequestPath(req)) {
          ServletRequestPathUtils.parseAndCache(req);
     }

just before method = (HandlerMethod) reqMap.getHandler(req).getHandler();

and it fixed my problem - is this the correct way to fix the issue or this could introduce performance problems?

Do I really need to check ServletRequestPathUtils.hasParsedRequestPath(req) beforehand?

Thanks in advance!

@Component
public class CustomAuthenticationFilter extends OncePerRequestFilter {

    private final RequestMappingHandlerMapping reqMap;

    public ChatBotAuthenticationFilter(RequestMappingHandlerMapping reqMap) {
        this.reqMap = reqMap;
    }

    @Override
    protected void doFilterInternal(HttpServletRequest req, HttpServletResponse res, FilterChain chain) throws IOException, ServletException {
        boolean isChatBotOnly = isEndpointCustomAuthenticationOnly(req);
        //[...] custom logic
        chain.doFilter(req, res);
    }

    private boolean isEndpointCustomAuthenticationOnly(HttpServletRequest req) {
        HandlerMethod method;
        try {
             if (!ServletRequestPathUtils.hasParsedRequestPath(req)) {
                ServletRequestPathUtils.parseAndCache(req);
            }
            method = (HandlerMethod) reqMap.getHandler(req).getHandler();
        } catch (Exception e) {
            return false;
        }

        return method.getMethod().isAnnotationPresent(CustomAuthenticationEndpoint.class);
    }
}

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface CustomAuthenticationEndpoint {
}

@bclozel
Copy link
Member

bclozel commented Jan 18, 2022

Sorry for the late reply @zifnab87
This looks ok to me. The performance problem here is really about performing the matching process twice (once in this filter, and another time for the actual handling). Looking up/setting a request attribute is really cheap compared to that.

@orubel
Copy link

orubel commented May 20, 2023

@bclozel I still seem to be having this issue and it occurs when you use other supported Mappings like SimpleUrlHandlerMapping with CorsFilter. Even thopugh you can establish a corsConfiguration with SimpleUrlHandlerMapping, the CorsFilter will STILL USE RequestMappingHandlerMapping for routing requests

The mapping works fine and passes all tests (batching, chaining, different JWT ROLES, etc) but when used with CORS, it fails

I am integrating it like so:

@Bean(name='simpleUrlHandlerMapping')
public SimpleUrlHandlerMapping simpleUrlHandlerMapping() {

            ...

	SimpleUrlHandlerMapping mapping = new SimpleUrlHandlerMapping();
	mapping.registerHandlers(urlMap)
	mapping.setUrlMap(urlMap);
	mapping.setOrder(1);
	mapping.setInterceptors(new Object[]{
			new ApiInterceptor(throttleCacheService, exchangeService, batchService, chainService, traceExchangeService, apiProperties)
	})
	mapping.setApplicationContext(context);
	//resourceCache.putAllResources(urlSet);

	mapping.setCorsConfigurations(getCorsConfigurations());
	return mapping;
}

protected Map<String, CorsConfiguration> getCorsConfigurations() {
	CorsRegistry registry = new CorsRegistry()
	registry.addMapping("/**")
			.allowedOrigins("http://localhost","http://test.nosegrind.net")
			.allowedMethods("*")
			.allowedHeaders("*")
			.exposedHeaders("*")
			.allowCredentials(true);
	return registry.getCorsConfigurations();
}

@orubel
Copy link

orubel commented May 23, 2023

So a followup...
All my tests pass from a shell perspective (and have been for sometime) but when testing with CORS, I noticed that it is defaulting to ResourceHttpRequestHandler :

08:25:28.708 [http-nio-127.0.0.1-8080-exec-2] DEBUG o.s.w.s.h.SimpleUrlHandlerMapping - Mapped to ResourceHttpRequestHandler [classpath [META-INF/resources/], classpath [resources/], classpath [static/], classpath [public/], ServletContext [/]]
08:25:28.715 [http-nio-127.0.0.1-8080-exec-2] DEBUG o.s.web.servlet.DispatcherServlet - GET "/v1.0/hook/getServices?_=1684855528179", parameters={masked}
08:25:28.720 [http-nio-127.0.0.1-8080-exec-2] DEBUG o.s.w.s.h.SimpleUrlHandlerMapping - Mapped to ResourceHttpRequestHandler [classpath [META-INF/resources/], classpath [resources/], classpath [static/], classpath [public/], ServletContext [/]]
08:25:28.722 [http-nio-127.0.0.1-8080-exec-2] DEBUG o.s.w.s.r.ResourceHttpRequestHandler - Resource not found
08:25:28.723 [http-nio-127.0.0.1-8080-exec-2] DEBUG o.s.web.servlet.DispatcherServlet - Completed 404 NOT_FOUND
08:25:28.724 [http-nio-127.0.0.1-8080-exec-2] DEBUG o.s.web.servlet.DispatcherServlet - GET "/v1.0/hook/getServices?_=1684855528179", parameters={masked}
08:25:28.724 [http-nio-127.0.0.1-8080-exec-2] DEBUG o.s.w.s.h.SimpleUrlHandlerMapping - Mapped to ResourceHttpRequestHandler [classpath [META-INF/resources/], classpath [resources/], classpath [static/], classpath [public/], ServletContext [/]]
08:25:28.725 [http-nio-127.0.0.1-8080-exec-2] DEBUG o.s.w.s.r.ResourceHttpRequestHandler - Resource not found

This should not be occurring since I set the ORDER for SimpleUrlHandlerMapping to mapping.setOrder(Integer.MAX_VALUE - 2); to override that behaviour

And again, this ONLY happens when using CORS and is throwing the following error:

Caused by: java.lang.IllegalStateException: Cannot call sendError() after the response has been committed
	at org.apache.catalina.connector.ResponseFacade.sendError(ResponseFacade.java:472)
	at javax.servlet.http.HttpServletResponseWrapper.sendError(HttpServletResponseWrapper.java:129)
	at javax.servlet.http.HttpServletResponseWrapper.sendError(HttpServletResponseWrapper.java:129)
	at javax.servlet.http.HttpServletResponseWrapper.sendError(HttpServletResponseWrapper.java:129)
	at org.springframework.security.web.util.OnCommittedResponseWrapper.sendError(OnCommittedResponseWrapper.java:116)
	at org.springframework.web.servlet.resource.ResourceHttpRequestHandler.handleRequest(ResourceHttpRequestHandler.java:561)
	at org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter.handle(HttpRequestHandlerAdapter.java:52)
	at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1067)
	at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:963)
	at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006)

@orubel
Copy link

orubel commented May 23, 2023

Will gladly allow access to sourcecode upon request. Right now it is in a private dev build

I DEBUGGED and know these patterns exist as well:


09:54:20.510 [main] DEBUG o.s.w.s.h.SimpleUrlHandlerMapping - Patterns [/v1.0/connector/update/**, /v1.0/connector/update/, /v1.0-1/connector/update/**, /v1.0-1/connector/update/, /b1.0/connector/update/**, /b1.0/connector/update/, /b1.0-1/connector/update/**, /b1.0-1/connector/update/, /c1.0/connector/update/**, /c1.0/connector/update/, /c1.0-1/connector/update/**, /c1.0-1/connector/update/, /t1.0/connector/update/**, /t1.0/connector/update/, /t1.0-1/connector/update/**, /t1.0-1/connector/update/, /v1.0/apidoc/show/**, /v1.0/apidoc/show/, /v1.0-1/apidoc/show/**, /v1.0-1/apidoc/show/, /b1.0/apidoc/show/**, /b1.0/apidoc/show/, /b1.0-1/apidoc/show/**, /b1.0-1/apidoc/show/, /c1.0/apidoc/show/**, /c1.0/apidoc/show/, /c1.0-1/apidoc/show/**, /c1.0-1/apidoc/show/, /t1.0/apidoc/show/**, /t1.0/apidoc/show/, /t1.0-1/apidoc/show/**, /t1.0-1/apidoc/show/, /v1.0/branch/show/**, /v1.0/branch/show/, /v1.0-1/branch/show/**, /v1.0-1/branch/show/, /b1.0/branch/show/**, /b1.0/branch/show/, /b1.0-1/branch/show/**, /b1.0-1/branch/show/, /c1.0/branch/show/**, /c1.0/branch/show/, /c1.0-1/branch/show/**, /c1.0-1/branch/show/, /t1.0/branch/show/**, /t1.0/branch/show/, /t1.0-1/branch/show/**, /t1.0-1/branch/show/, /v1.0/branch/create/**, /v1.0/branch/create/, /v1.0-1/branch/create/**, /v1.0-1/branch/create/, /b1.0/branch/create/**, /b1.0/branch/create/, /b1.0-1/branch/create/**, /b1.0-1/branch/create/, /c1.0/branch/create/**, /c1.0/branch/create/, /c1.0-1/branch/create/**, /c1.0-1/branch/create/, /t1.0/branch/create/**, /t1.0/branch/create/, /t1.0-1/branch/create/**, /t1.0-1/branch/create/, /v1.0/branch/delete/**, /v1.0/branch/delete/, /v1.0-1/branch/delete/**, /v1.0-1/branch/delete/, /b1.0/branch/delete/**, /b1.0/branch/delete/, /b1.0-1/branch/delete/**, /b1.0-1/branch/delete/, /c1.0/branch/delete/**, /c1.0/branch/delete/, /c1.0-1/branch/delete/**, /c1.0-1/branch/delete/, /t1.0/branch/delete/**, /t1.0/branch/delete/, /t1.0-1/branch/delete/**, /t1.0-1/branch/delete/, /v1.0/company/show/**, /v1.0/company/show/, /v1.0-1/company/show/**, /v1.0-1/company/show/, /b1.0/company/show/**, /b1.0/company/show/, /b1.0-1/company/show/**, /b1.0-1/company/show/, /c1.0/company/show/**, /c1.0/company/show/, /c1.0-1/company/show/**, /c1.0-1/company/show/, /t1.0/company/show/**, /t1.0/company/show/, /t1.0-1/company/show/**, /t1.0-1/company/show/, /v1.0/company/create/**, /v1.0/company/create/, /v1.0-1/company/create/**, /v1.0-1/company/create/, /b1.0/company/create/**, /b1.0/company/create/, /b1.0-1/company/create/**, /b1.0-1/company/create/, /c1.0/company/create/**, /c1.0/company/create/, /c1.0-1/company/create/**, /c1.0-1/company/create/, /t1.0/company/create/**, /t1.0/company/create/, /t1.0-1/company/create/**, /t1.0-1/company/create/, /v1.0/company/update/**, /v1.0/company/update/, /v1.0-1/company/update/**, /v1.0-1/company/update/, /b1.0/company/update/**, /b1.0/company/update/, /b1.0-1/company/update/**, /b1.0-1/company/update/, /c1.0/company/update/**, /c1.0/company/update/, /c1.0-1/company/update/**, /c1.0-1/company/update/, /t1.0/company/update/**, /t1.0/company/update/, /t1.0-1/company/update/**, /t1.0-1/company/update/, /v1.0/company/delete/**, /v1.0/company/delete/, /v1.0-1/company/delete/**, /v1.0-1/company/delete/, /b1.0/company/delete/**, /b1.0/company/delete/, /b1.0-1/company/delete/**, /b1.0-1/company/delete/, /c1.0/company/delete/**, /c1.0/company/delete/, /c1.0-1/company/delete/**, /c1.0-1/company/delete/, /t1.0/company/delete/**, /t1.0/company/delete/, /t1.0-1/company/delete/**, /t1.0-1/company/delete/, /v1.0/user/show/**, /v1.0/user/show/, /v1.0-1/user/show/**, /v1.0-1/user/show/, /b1.0/user/show/**, /b1.0/user/show/, /b1.0-1/user/show/**, /b1.0-1/user/show/, /c1.0/user/show/**, /c1.0/user/show/, /c1.0-1/user/show/**, /c1.0-1/user/show/, /t1.0/user/show/**, /t1.0/user/show/, /t1.0-1/user/show/**, /t1.0-1/user/show/, /v1.0/user/getByUsername/**, /v1.0/user/getByUsername/, /v1.0-1/user/getByUsername/**, /v1.0-1/user/getByUsername/, /b1.0/user/getByUsername/**, /b1.0/user/getByUsername/, /b1.0-1/user/getByUsername/**, /b1.0-1/user/getByUsername/, /c1.0/user/getByUsername/**, /c1.0/user/getByUsername/, /c1.0-1/user/getByUsername/**, /c1.0-1/user/getByUsername/, /t1.0/user/getByUsername/**, /t1.0/user/getByUsername/, /t1.0-1/user/getByUsername/**, /t1.0-1/user/getByUsername/, /v1.0/user/updatePassword/**, /v1.0/user/updatePassword/, /v1.0-1/user/updatePassword/**, /v1.0-1/user/updatePassword/, /b1.0/user/updatePassword/**, /b1.0/user/updatePassword/, /b1.0-1/user/updatePassword/**, /b1.0-1/user/updatePassword/, /c1.0/user/updatePassword/**, /c1.0/user/updatePassword/, /c1.0-1/user/updatePassword/**, /c1.0-1/user/updatePassword/, /t1.0/user/updatePassword/**, /t1.0/user/updatePassword/, /t1.0-1/user/updatePassword/**, /t1.0-1/user/updatePassword/, /v1.0/user/create/**, /v1.0/user/create/, /v1.0-1/user/create/**, /v1.0-1/user/create/, /b1.0/user/create/**, /b1.0/user/create/, /b1.0-1/user/create/**, /b1.0-1/user/create/, /c1.0/user/create/**, /c1.0/user/create/, /c1.0-1/user/create/**, /c1.0-1/user/create/, /t1.0/user/create/**, /t1.0/user/create/, /t1.0-1/user/create/**, /t1.0-1/user/create/, /v1.0/user/list/**, /v1.0/user/list/, /v1.0-1/user/list/**, /v1.0-1/user/list/, /b1.0/user/list/**, /b1.0/user/list/, /b1.0-1/user/list/**, /b1.0-1/user/list/, /c1.0/user/list/**, /c1.0/user/list/, /c1.0-1/user/list/**, /c1.0-1/user/list/, /t1.0/user/list/**, /t1.0/user/list/, /t1.0-1/user/list/**, /t1.0-1/user/list/, /v1.0/authority/create/**, /v1.0/authority/create/, /v1.0-1/authority/create/**, /v1.0-1/authority/create/, /b1.0/authority/create/**, /b1.0/authority/create/, /b1.0-1/authority/create/**, /b1.0-1/authority/create/, /c1.0/authority/create/**, /c1.0/authority/create/, /c1.0-1/authority/create/**, /c1.0-1/authority/create/, /t1.0/authority/create/**, /t1.0/authority/create/, /t1.0-1/authority/create/**, /t1.0-1/authority/create/, /v1.0/authority/list/**, /v1.0/authority/list/, /v1.0-1/authority/list/**, /v1.0-1/authority/list/, /b1.0/authority/list/**, /b1.0/authority/list/, /b1.0-1/authority/list/**, /b1.0-1/authority/list/, /c1.0/authority/list/**, /c1.0/authority/list/, /c1.0-1/authority/list/**, /c1.0-1/authority/list/, /t1.0/authority/list/**, /t1.0/authority/list/, /t1.0-1/authority/list/**, /t1.0-1/authority/list/, /v1.0/dept/show/**, /v1.0/dept/show/, /v1.0-1/dept/show/**, /v1.0-1/dept/show/, /b1.0/dept/show/**, /b1.0/dept/show/, /b1.0-1/dept/show/**, /b1.0-1/dept/show/, /c1.0/dept/show/**, /c1.0/dept/show/, /c1.0-1/dept/show/**, /c1.0-1/dept/show/, /t1.0/dept/show/**, /t1.0/dept/show/, /t1.0-1/dept/show/**, /t1.0-1/dept/show/, /v1.0/dept/create/**, /v1.0/dept/create/, /v1.0-1/dept/create/**, /v1.0-1/dept/create/, /b1.0/dept/create/**, /b1.0/dept/create/, /b1.0-1/dept/create/**, /b1.0-1/dept/create/, /c1.0/dept/create/**, /c1.0/dept/create/, /c1.0-1/dept/create/**, /c1.0-1/dept/create/, /t1.0/dept/create/**, /t1.0/dept/create/, /t1.0-1/dept/create/**, /t1.0-1/dept/create/, /v1.0/dept/update/**, /v1.0/dept/update/, /v1.0-1/dept/update/**, /v1.0-1/dept/update/, /b1.0/dept/update/**, /b1.0/dept/update/, /b1.0-1/dept/update/**, /b1.0-1/dept/update/, /c1.0/dept/update/**, /c1.0/dept/update/, /c1.0-1/dept/update/**, /c1.0-1/dept/update/, /t1.0/dept/update/**, /t1.0/dept/update/, /t1.0-1/dept/update/**, /t1.0-1/dept/update/, /v1.0/dept/delete/**, /v1.0/dept/delete/, /v1.0-1/dept/delete/**, /v1.0-1/dept/delete/, /b1.0/dept/delete/**, /b1.0/dept/delete/, /b1.0-1/dept/delete/**, /b1.0-1/dept/delete/, /c1.0/dept/delete/**, /c1.0/dept/delete/, /c1.0-1/dept/delete/**, /c1.0-1/dept/delete/, /t1.0/dept/delete/**, /t1.0/dept/delete/, /t1.0-1/dept/delete/**, /t1.0-1/dept/delete/] in org.springframework.web.servlet.handler.SimpleUrlHandlerMapping
09:54:20.704 [main] DEBUG o.s.w.s.h.SimpleUrlHandlerMapping - Patterns [/webjars/**, /**] in 'resourceHandlerMapping'

The security config is fairly simple and straight forward:

    @Override
    protected void configure(HttpSecurity httpSecurity) throws Exception {
        httpSecurity.csrf().disable().cors();
        httpSecurity.authorizeRequests().antMatchers("/authenticate", "/register").permitAll().anyRequest().authenticated();
        httpSecurity.exceptionHandling().authenticationEntryPoint(jwtAuthenticationEntryPoint);
        //httpSecurity.addFilterAfter(requestInitializationFilter, CorsFilter.class);
        httpSecurity.addFilterAfter(jwtRequestFilter(), ExceptionTranslationFilter.class);
        //httpSecurity.addFilterAfter(requestInitializationFilter, JwtRequestFilter.class);
        httpSecurity.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
    }

@bclozel
Copy link
Member

bclozel commented May 23, 2023

The fact that the request is considered with the ResourceHttpRequestHandler indicates that this was not a match for the previous handlers. Maybe the request doesn't qualify as a CORS request and is ignored by the CORS support. Maybe debug through CorsUtils.isCorsRequest? In any case, a sample application showing the problem would be really helpful. If you believe this is a bug in Spring Framework, please raise an issue there.

@orubel
Copy link

orubel commented May 23, 2023

@bclozel Thanks a mill. Yeah that passed with flying colors. Just to be sure. This goes to HTTPSecurity??

@bclozel
Copy link
Member

bclozel commented May 23, 2023

@orubel, no CORS support is in Spring Framework, see CorsUtils and related classes.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
status: invalid An issue that we don't feel is valid
Projects
None yet
Development

No branches or pull requests

5 participants