javaspring-mvcspring-security

Spring Security 4: How to ignore trailing slashes


I have a Spring Boot application and I'm using Spring Security (4.0.4).

Current security configuration (in Java) for the endpoints allows a call to /some/endpoint but not to /some/endpoint/.

I have searched here, and the documentation but I don't see anything like a switch to ignore the trailing whitespaces. For example, with Spring MVC I can do the following:

@Configuration
public class ServletConfig extends WebMvcConfigurerAdapter {
  @Override
  public void configurePathMatch(final PathMatchConfigurer configurer) {
    configurer.setUseTrailingSlashMatch(false);
  }
}

Of course, the above code changes the behaviour opposite of what I want, but it just serves as a demonstration of what I'd like to do with Spring Security.

My (reduced) security configuration:

@Bean
public ResourceServerConfigurer resourceServerConfigurer(final ScopesProperties oauthProperties) {
    return new ResourceServerConfigurerAdapter() {
        @Override
        public void configure(final HttpSecurity http) throws Exception {
            http.sessionManagement().sessionCreationPolicy(NEVER).and()
                    .authorizeRequests()
                    .antMatchers(GET, "/foo")
                    .access(oauthProperties.getFooRead())
                    .antMatchers(GET, "/bar/*")
                    .access(oauthProperties.getBarRead())
                    .antMatchers(PUT, "/bar/*")
                    .access(oauthProperties.getBarWrite())
                    // everything else
                    .anyRequest().denyAll();
        }

I know that I can use regex matchers, which I'd like to avoid, mostly for the same reason as I'd like to avoid having one extra rule for every endpoint just to approve the same endpoint with a trailing slash. I would have to do it for every endpoint, which is error prone. I also know that I can use ant matchers and set the path to /foo/**. Problem with this is when I want to control sub-resources with different scopes.

So the question is: How to tell Spring Security to globally ignore trailing slashes?


Solution

  • Just in case someone has the same problem, there is a solution for it. It's called MvcRequestMatcher and you can read all about it in the Spring Documentation

    Here is the main part:

    The problem is that our security rule is only protecting /admin. We could add additional rules for all the permutations of Spring MVC, but this would be quite verbose and tedious.

    Instead, we can leverage Spring Security’s MvcRequestMatcher. The following configuration will protect the same URLs that Spring MVC will match on by using Spring MVC to match on the URL.

    Here is how the configuration is looking right now:

    @Bean
    public ResourceServerConfigurer resourceServerConfigurer(final ScopesProperties oauthProperties) {
        return new ResourceServerConfigurerAdapter() {
            @Override
            public void configure(final HttpSecurity http) throws Exception {
                http.sessionManagement().sessionCreationPolicy(NEVER).and()
                    .authorizeRequests()
                    .mvcMatchers(GET, "/foo")
                    .access(oauthProperties.getFooRead())
                    .mvcMatchers(GET, "/bar")
                    .access(oauthProperties.getBarRead())
                    .mvcMatchers(PUT, "/bar")
                    .access(oauthProperties.getBarWrite())
                    // everything else
                    .anyRequest().denyAll();
        }