Skip to content
Advertisement

Using ant patterns to match on path variable

I have several different controllers, configured with endpoints like below. Where {id} is a numeric @PathVariable.

@RequestMapping(value = "/noun1/noun2/{id}/verb1")
@RequestMapping(value = "/noun1/noun2/{id}/verb2")
@RequestMapping(value = "/noun1/noun2/{id}/verb3/verb4")
@RequestMapping(value = "/noun1/noun2/noun3/verb5")

Using HttpSecurity, I want to implement security around all endpoints that have {id} in them. So I created an ant pattern like this:

"/noun1/noun2/{id}/**"

The ant pattern is correctly matching on the endpoints with {id} in them. However, the ant pattern is also matching on the last endpoint, setting id = noun3. Is there a way with ant patterns to only match the endpoints containing {id}?

Advertisement

Answer

How your ant pattern should be depends on what {id} can be. The {id} in your ant matcher is not directly related to your {id} in your RequestMapping annotation.

Spring Security just checks, with the ant matcher, whether the path matches the provided pattern. In your case {id} matches any string and stores the matched value in a URI template variable named id for later use.

To specify the what is considered an {id} you can provide an regex. If your id consists of digits your matcher could be "/noun1/noun2/{regex:\d+}/**":

import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;

import org.junit.jupiter.api.Test;
import org.springframework.util.AntPathMatcher;

class AntMatcherTest {

  @Test
  void antMatcher() {
    AntPathMatcher antPathMatcher = new AntPathMatcher();
    String pattern = "/noun1/noun2/{id:\d+}/**";

    assertFalse(antPathMatcher.match(pattern, "/noun1/noun2/noun3/verb5"));
    assertTrue(antPathMatcher.match(pattern, "/noun1/noun2/1/verb1"));
    assertTrue(antPathMatcher.match(pattern, "/noun1/noun2/2/verb2"));
    assertTrue(antPathMatcher.match(pattern, "/noun1/noun2/3/verb3/verb4"));
  }
}

User contributions licensed under: CC BY-SA
4 People found this is helpful
Advertisement