In Spring Framework 5.3 snapshots Spring MVC has support for parsed PathPatterns, see https://github.com/spring-projects/spring-framework/issues/24945.

After the changes if a HandlerMappingIntrospector returns a MatchableHandlerMapping with a PathPatternParser, the existing match method raises an IllegalArgumentException. To support this, Spring Security would need have its own patterns parsed on startup and at runtime it would use either the PathPattern or its String representation available via PathPattern#getPatternString based on MatchableHandlerMapping.usesPathPatterns().

PathPattern expects a parsed PathContainer path to match to. There is ServletRequestPathUtils to help parse and cache the path in a request attribute, and that is done once in the DispatcherServlet but there is also a ServletRequestPathFilter that can be used to do the same earlier. That will probably be of interest to Spring Security.

As an aside, there are a number of components in Spring MVC including MappedInterceptor, WebContentInterceptor, and UrlBasedCorsConfigurationSource that operate in similar fashion. They hold parsed patterns and using them either as PathPattern or as String patterns with PathMatcher. However in their case they simply check whether a parsed RequestPath is present or not, while Spring Security can check more directly against through the MatchableHandlerMapping.

Comment From: rwinch

Thanks for the detailed writeup. I've started work on this in a branch, but I have a few questions.

The first is that Spring Security uses some default logic if no MatchableHandlerMapping is found. Now that there is another code path (using PathPatternParser), I'm not sure if this is a good default. What are your thoughts?

The second is that you stated:

To support this, Spring Security would need have its own patterns parsed on startup

What do you mean it's own patterns parsed at startup? As far as I'm aware I cannot do this because parsing is done via MatchableHandlerMapping which I need the HttpServletRequest to look up. This means I cannot parse the patterns until runtime. Does this sound correct?

Comment From: rstoyanchev

The null means that no matching handler is found and that Spring MVC would return a 404 or a 4xx like 405 for the request. Whether that was determined with PathPattern's or a PathMatcher shouldn't matter and for this case any default matching that Spring Security wants to default to should be okay as far as I can see.

For the parsing of Spring Security patterns, yes that is a bit of a challenge. PathPatternParser has two settings that can vary. One for case sensitivity and another for trailing slashes. Does it make sense for Spring Security to have those pinned to some default, e.g. caseSensitive=false and matchOptionalTrailingSeparator=true so that Spring Security always matches a superset of Spring MVC might? If the answer is no then Spring Security might have to to maintain a different set of patterns parsed for the required combination. For this we might have HandlerMapingIntrpospector expose a method to return a list of all HandlerMapping instances that Spring MVC knows about so that Spring Security can check their PathPatternParser instances determine upfront what sets of patterns it needs.

Comment From: rwinch

Does it make sense for Spring Security to have those pinned to some default, e.g. caseSensitive=false and matchOptionalTrailingSeparator=true so that Spring Security always matches a superset of Spring MVC might?

This won't work because depending on the rule the user is setting it might be more or less restrictive. For example, the matching might be to denyAll which we would want the pattern to match more things or it might be permitAll in which case we'd want it to match fewer items.

I wonder if there would be a way to expose single PathPatternParser so Spring Security could use that vs exposing it on every HandlerMapingIntrpospector?

Comment From: rstoyanchev

Challenge is, each HandlerMapping can have its own PathPatternParser.

Comment From: rwinch

I don't think we can parse up front if there is more than one PathPatternParser instances. Spring Security may have a rule specified that matches multiple HandlerMapping instances. Consider a rule of /admin/** for security. Spring MVC may have one HandlerMapingIntrpospector match /admin/foo and another HandlerMappingIntrospector match /admin/bar.

Comment From: rstoyanchev

The changes for https://github.com/spring-projects/spring-framework/issues/25312 have been made. The PathPattern support should be transparent for Spring Security but if you could you take and confirm all is good, that would be great. In any case this can be closed now. We can discuss further under the Spring Framework issue if needed.

Comment From: rwinch

Thanks @rstoyanchev The changes look good to me. Closing as the changes are no longer necessary in Spring Security