antMatchers
Spring Security
Java
authentication
access control

What does 'antMatchers' mean?

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

In Spring Security, antMatchers referred to URL rules based on Ant-style path patterns such as "/admin/**". It was a convenient way to say which requests should be permitted, authenticated, or restricted to specific roles. The important modern detail is that antMatchers belongs to the older API shape; current Spring Security code usually uses requestMatchers instead.

What the ant Part Means

The word ant comes from Ant-style path matching. These patterns are simple wildcards for paths:

  • '? matches one character inside a path segment'
  • '* matches zero or more characters inside one segment'
  • '** matches across path segments'

So a pattern like "/css/**" matches files under /css/, while "/admin/*" matches one segment directly under /admin/.

That is the core idea behind antMatchers: use human-readable patterns instead of writing custom matching logic for every endpoint.

How antMatchers Was Used

In older Spring Security configurations, you often saw code like this:

java
1http
2    .authorizeRequests()
3    .antMatchers("/css/**", "/js/**").permitAll()
4    .antMatchers("/admin/**").hasRole("ADMIN")
5    .antMatchers("/profile/**").authenticated()
6    .anyRequest().denyAll();

This means:

  • static assets are public
  • '/admin/ paths require the ADMIN role'
  • '/profile/ paths require a logged-in user'
  • everything else is denied

The rule order matters. Spring Security evaluates request matchers in order, so a broad rule placed too early can swallow a narrower rule that appears later.

What You Should Write in Current Spring Security

In modern Spring Security, the common API is requestMatchers under authorizeHttpRequests.

java
1import static org.springframework.security.config.Customizer.withDefaults;
2
3@Bean
4SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
5    http
6        .authorizeHttpRequests(authorize -> authorize
7            .requestMatchers("/css/**", "/js/**").permitAll()
8            .requestMatchers("/admin/**").hasRole("ADMIN")
9            .requestMatchers("/profile/**").authenticated()
10            .anyRequest().denyAll()
11        )
12        .formLogin(withDefaults());
13
14    return http.build();
15}

For simple path patterns, this reads almost the same. The difference is that the framework moved toward a more general request-matcher model instead of centering the configuration API on the older antMatchers method name.

In other words, antMatchers did not mean “special security logic.” It meant “apply authorization rules to requests matched with Ant-style path syntax.”

When Ant-Style Matching Is Enough

Ant-style patterns work well for common URL layouts:

  • public static files under a directory
  • admin or internal routes under a prefix
  • method-specific endpoint rules combined with HTTP methods

Example with a specific HTTP method:

java
1@Bean
2SecurityFilterChain apiSecurity(HttpSecurity http) throws Exception {
3    http
4        .authorizeHttpRequests(authorize -> authorize
5            .requestMatchers(HttpMethod.GET, "/api/public/**").permitAll()
6            .requestMatchers(HttpMethod.POST, "/api/admin/**").hasRole("ADMIN")
7            .anyRequest().authenticated()
8        );
9
10    return http.build();
11}

That gives you clear intent without introducing a custom matcher class.

When You Need Something More Specific

Sometimes Ant patterns are too broad. If a rule depends on a strict format such as alphanumeric usernames or a more complex path shape, use a regex matcher or another RequestMatcher implementation.

java
1import org.springframework.security.web.util.matcher.RegexRequestMatcher;
2
3@Bean
4SecurityFilterChain regexSecurity(HttpSecurity http) throws Exception {
5    http
6        .authorizeHttpRequests(authorize -> authorize
7            .requestMatchers(
8                RegexRequestMatcher.regexMatcher("/reports/[A-Za-z0-9]+")
9            ).hasAuthority("REPORT_VIEW")
10            .anyRequest().denyAll()
11        );
12
13    return http.build();
14}

That is one reason the newer requestMatchers API is useful: it can accept more than one matching strategy.

Common Pitfalls

The most common mistake is assuming * and ** mean the same thing. They do not. * stays within one path segment, while ** can cross multiple segments.

Another mistake is putting a broad matcher before a narrow one. A rule like "/**".authenticated() placed too early can prevent later admin-specific rules from ever being reached.

A third issue is treating antMatchers as current terminology in brand-new projects. If you are using recent Spring Security versions, write requestMatchers and think in terms of request matcher types rather than memorizing an old method name.

Summary

  • 'antMatchers was the older Spring Security API for applying rules to Ant-style path patterns'
  • Ant-style patterns use ?, *, and ** to match request paths
  • In current Spring Security, requestMatchers is the usual replacement
  • Rule order matters because matchers are evaluated in sequence
  • Use regex or custom matchers when Ant-style patterns are too broad for the route shape you need

Course illustration
Course illustration

All Rights Reserved.