spring-projects/spring-framework

ServerWebExchangeMatchers does not honor setUseTrailingSlashMatch

kdebski85 opened this issue · 1 comments

Affects: 6.0.3

Probably caused by: #28552


According to https://github.com/spring-projects/spring-boot/wiki/Spring-Boot-3.0-Migration-Guide#spring-mvc-and-webflux-url-matching-changes training slash match can be enabled with:

@Configuration
public class WebConfiguration implements WebFluxConfigurer {

    @Override
    public void configurePathMatching(PathMatchConfigurer configurer) {
      configurer.setUseTrailingSlashMatch(true);
    }

}

However, it does not work when org.springframework.security.web.server.util.matcher.ServerWebExchangeMatchers is used because it creates a new instance of PathPatternParserServerWebExchangeMatcher which always uses DEFAULT_PATTERN_PARSER with default settings.

For example, if we use SpringFlux with the following security setup, it will match /api/test, but not /api/test/.

@Configuration
class SecurityConfiguration {

    @Bean
    public SecurityWebFilterChain securityWebFilterChain(ServerHttpSecurity http) {
        return http.authorizeExchange(exchangeSpec -> exchangeSpec.pathMatchers(GET, "/api/test").authenticated()).build();
    }

}

If I understand correctly, this means that Spring Security doesn't currently document a way to register ServerWebExchangeMatcher instances that are based on a custom PathPatternParser. I'm not sure that a new variant should be surfaced in the DSL, given that this strategy is deprecated altogether.

I've crafted the following:

@Configuration
class SecurityConfiguration {

	private final PathPatternParser pathPatternParser;

	public SecurityConfiguration() {
		this.pathPatternParser = new PathPatternParser();
		this.pathPatternParser.setMatchOptionalTrailingSeparator(true);
	}

	@Bean
	public SecurityWebFilterChain securityWebFilterChain(ServerHttpSecurity http) {
		return http.authorizeExchange(exchangeSpec -> exchangeSpec.matchers(pathMatch("/api/test", GET)).authenticated()).build();
	}

	PathPatternParserServerWebExchangeMatcher pathMatch(String pathPattern, HttpMethod method) {
		PathPattern pattern = this.pathPatternParser.parse(pathPattern);
		return new PathPatternParserServerWebExchangeMatcher(pattern, method);
	}

}

I'm not sure there's anything we can do at the Framework level, could you reach out to the Spring Security team to discuss this matter? Thanks!