@[toc] Spring Security is a powerful and highly customizable security framework that provides a complete solution for protecting Spring-based applications. In Spring Security, path matching is a core part of permission control, which determines which requests can access specific resources. This article will introduce the path matching strategy in Spring Security in detail and provide corresponding code examples.
In the old version of Spring Security, there were many path matching methods, but the new version of Spring Security uniformly encapsulates these methods and calls the requestMatchers method for processing:
public C requestMatchers(RequestMatcher... requestMatchers) {
Assert.state(!this.anyRequestConfigured, "Can't configure requestMatchers after anyRequest");
return chainRequestMatchers(Arrays.asList(requestMatchers));
}
The requestMatchers method receives a parameter of type RequestMatcher. RequestMatcher is an interface. This interface is a tool used to determine whether an HTTP request matches a given pattern. This interface provides a flexible way to define request matching rules, so that different security policies can be implemented for different requests.
So in the new version of Spring Security, different path matching sub-schemes are actually different implementation classes of RequestMatcher.
1. AntPathRequestMatcher
AntPathRequestMatcher
Is one of the most commonly used request matchers in Spring, which uses Ant-style path patterns to match request URIs.
1.1 What is Ant-style path pattern
Ant-style path matching (Ant Path Matching) is a pattern matching rule for resource location, which originates from the Java build tool Apache Ant. In Ant, this mode is used to specify files and directories in the file system. Due to its simplicity and flexibility, Ant-style path patterns are also adopted by many other frameworks and applications, including Spring Security.
Ant-style path patterns use some special characters to represent different levels of path matching:
-
?
: Matches any single character (except path separators). -
*
: Matches a sequence of any characters (except path separators), excluding the empty string. -
**
: Matches any sequence of characters, including the empty string. Matches a sequence of at least one character and can span path separators. -
{}
: Indicates a wildcard selection that can match multiple comma-separated patterns. For example,{,春夏秋冬}
any string starting with spring, summer, autumn, or winter can be matched. -
[]
: In some implementations, can be used to match a single character within parentheses. -
()
: In some implementations, can be used for group matching.
In Spring Security, Ant-style path patterns are often used to define the mapping between URL paths and security configurations. For example, you can use Ant-style path patterns to specify which URL paths require specific permissions or roles.
Here are some examples of Ant-style path patterns:
-
/users/*
: Matches/users/
any path starting with , such as/users/123
or/users/profile
. -
/users/**
: Matches/users/
any path starting with , including subpaths such as/users/123
or/users/profile/picture
. -
/users/123
: Exact match/users/123
. -
/users/{id}
: Although this is not an Ant-style pattern, it demonstrates path parameter matching, which can match/users/123
,/users/456
etc. -
/files/**.{jpg,png}
: Matches/files/
all file paths ending with.jpg
or , such as or ..png
/files/image1.jpg
/files/folder/image.png
By using Ant-style path patterns, you can flexibly define complex URL matching rules to adapt to different security requirements.
1.2 Basic usage
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
// 创建 AntPathRequestMatcher 实例
RequestMatcher antMatcher = new AntPathRequestMatcher("/users/**", "GET");
// 使用 matcher 进行匹配
boolean isMatch = antMatcher.matches(request);
1.3 Wildcards
?
Matches any single character.*
Matches any sequence of characters (but not directory separators).**
Matches any sequence of characters, including directory separators.
// 匹配 /admin 下的任何资源,包括子目录
RequestMatcher adminMatcher = new AntPathRequestMatcher("/admin/**");
// 匹配 /files 目录下的任何 HTML 文件
RequestMatcher fileMatcher = new AntPathRequestMatcher("/files/*.{html,htm}", "GET");
2. RegexRequestMatcher
RegexRequestMatcher
Use regular expressions to match the requested URI and HTTP method.
2.1 Basic usage
import org.springframework.security.web.util.matcher.RegexRequestMatcher;
// 创建 RegexRequestMatcher 实例
RequestMatcher regexMatcher = new RegexRequestMatcher("^/api/.*", "GET");
// 使用 matcher 进行匹配
boolean isMatch = regexMatcher.matches(request);
2.2 Using regular expressions
// 匹配任何以 /api 开头的 URI
RequestMatcher apiMatcher = new RegexRequestMatcher("^/api/.*");
// 匹配任何 HTTP 方法
RequestMatcher anyMethodMatcher = new RegexRequestMatcher("^/.*", "GET|POST|PUT|DELETE");
2.3 Combined with Spring Security
The following code intercepts all requests ending with html, css and js. These requests can be accessed directly:
@Configuration
public class SecurityConfig {
@Bean
SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http.authorizeHttpRequests(a -> a.requestMatchers(new RegexRequestMatcher("^.*\\.(htm|css|js)$","GET")).permitAll())
.formLogin(Customizer.withDefaults())
.csrf(c -> c.disable());
return http.build();
}
}
3. RequestHeaderRequestMatcher
RequestHeaderRequestMatcher
Used to match keys and values in request headers.
import org.springframework.security.web.util.matcher.RequestHeaderRequestMatcher;
// 创建 RequestHeaderRequestMatcher 实例
RequestMatcher headerMatcher = new RequestHeaderRequestMatcher("User-Agent", "Mozilla.*");
// 使用 matcher 进行匹配
boolean isMatch = headerMatcher.matches(request);
Specifically in Spring Security, the usage is as follows:
@Configuration
public class SecurityConfig {
@Bean
SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http.authorizeHttpRequests(a -> a.requestMatchers(new RequestHeaderRequestMatcher("User-Agent","Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0 Safari/537.36")).permitAll())
.formLogin(Customizer.withDefaults())
.csrf(c -> c.disable());
return http.build();
}
}
4. NegatedRequestMatcher
NegatedRequestMatcher
Allows you to negate an existing RequestMatcher
match.
import org.springframework.security.web.util.matcher.NegatedRequestMatcher;
// 创建一个 matcher,然后否定它的匹配结果
RequestMatcher notAdminMatcher = new NegatedRequestMatcher(adminMatcher);
// 使用 negated matcher 进行匹配
boolean isNotMatch = notAdminMatcher.matches(request);
For example, the following code indicates that /hello
all addresses except , can be accessed directly:
@Configuration
public class SecurityConfig {
@Bean
SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http.authorizeHttpRequests(a -> a.requestMatchers(new NegatedRequestMatcher(new AntPathRequestMatcher("/hello"))).permitAll())
.formLogin(Customizer.withDefaults())
.csrf(c -> c.disable());
return http.build();
}
}
5. AndRequestMatcher 和 OrRequestMatcher
AndRequestMatcher
and OrRequestMatcher
are respectively used to combine multiple RequestMatcher
instances to perform logical matching of "AND" or "OR".
5.1 AndRequestMatcher
import org.springframework.security.web.util.matcher.AndRequestMatcher;
// 组合多个 matcher 进行“与”匹配
RequestMatcher andMatcher = new AndRequestMatcher(apiMatcher, headerMatcher);
// 使用 andMatcher 进行匹配
boolean isMatch = andMatcher.matches(request);
5.2 OrRequestMatcher
import org.springframework.security.web.util.matcher.OrRequestMatcher;
// 组合多个 matcher 进行“或”匹配
RequestMatcher orMatcher = new OrRequestMatcher(adminMatcher, fileMatcher);
// 使用 orMatcher 进行匹配
boolean isMatch = orMatcher.matches(request);
6. Summary
Spring provides a variety of RequestMatcher
implementation classes to meet different request matching needs. By using these matchers appropriately, security policies can be flexibly defined and implemented. In actual applications, you may need to select an appropriate matcher based on business requirements and combine it with Spring Security configuration to implement fine-grained access control.