-
Notifications
You must be signed in to change notification settings - Fork 41.1k
Upgrade from 2.5.7 to 2.6.x breaks use of RequestMappingHandlerMapping in Filters #28874
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
Rolling back to the old behaviour by setting |
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 |
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 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 I'd suggest to ways to fix the filter implementation:
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! |
As an additional comment, I'd like to add that Without knowing more about the use case, it's hard to point to alternatives. Maybe a |
@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 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 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 {
} |
Sorry for the late reply @zifnab87 |
@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:
|
So a followup...
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:
|
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:
The security config is fairly simple and straight forward:
|
The fact that the request is considered with the |
@bclozel Thanks a mill. Yeah that passed with flying colors. Just to be sure. This goes to HTTPSecurity?? |
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)
throwsA minimal example of how we are using this code
I that the default matching strategy has been changed in #24805, but I've been unable to resolve this issue in my codebase.
The text was updated successfully, but these errors were encountered: