通过上面示例代码:
实现了以 /sys/ 开头的请求地址,与 admin 角色的绑定。即要访问以 /sys/ 开头的地址,必须拥有 admin 角色。
简单来说,权限管理就是将某个 url 地址(或者多个 url 地址)与特定的角色或菜单权限绑定。用户拥有了这些角色和菜单权限才能访问这些 url 地址。可以将上面代码转换为如下:
List<String> authList = new ArrayList<>(); // 用户权限列表 String url = "请求地址"; if(url.startWith("/sys/") && authList.container("admin")) { // 允许访问 } else { // 抛出异常,返回 403,禁止访问 }
这理解起来就简单了。
📢注意:
(1)在 Spring Security 6 中,http.authorizeHttpRequests() 也支持连缀写法,总体公式为:
url匹配规则.权限控制方法
例如:
.requestMatchers("/sys/*").hasRole("admin")
其中:requestMatchers() 用来匹配 url,hasRole() 实现权限控制。
通过上面的公式可以有很多 url 匹配规则和很多权限控制方法。这些内容进行各种组合就形成了 Spring Security 中的授权。
(2)在所有匹配规则中取所有规则的交集。配置顺序影响了之后授权效果,越是具体的应该放在前面,越是笼统的应该放到后面。例如:
.authorizeHttpRequests(authorize -> authorize.requestMatchers("/sys/get").hasRole("normal") // 普通用户也能访问 .requestMatchers("/sys/*").hasRole("admin") // 系统管理员才能访问 .anyRequest().authenticated() )
该方法是配置 HTTP 请求路径匹配规则的核心方法,用于精确控制哪些 URL 需要哪些权限才能访问。requestMatchers() 方法有四个重载方法:
requestMatchers(String... patterns)
requestMatchers(org.springframework.http.HttpMethod method)
requestMatchers(org.springframework.http.HttpMethod method, String... patterns)
requestMatchers(RequestMatcher... requestMatchers)
下面逐一详细介绍:
基于 Ant 风格路径表达式 匹配请求路径。
参数说明:
patterns:一个或多个 Ant 风格的路径表达式(如 /api/**、/user/*)。
使用示例:
http.authorizeHttpRequests(authorize -> authorize .requestMatchers("/public/**").permitAll() // 公开路径 .requestMatchers("/admin/**").hasRole("ADMIN") // 管理员路径 .anyRequest().authenticated() );
匹配规则如下:
符号 | 含义 | 示例 | 匹配路径 |
* | 匹配任意数量的任意字符 | /user/* | /user/123, /user/add |
** | 匹配多层路径 | /api/** | /api/users, /api/users/1 |
? | 匹配单个任意字符 | /user/?.html | /user/1.html, /user/a.html |
匹配指定 HTTP 方法的所有请求(不限制路径)。常用于开放特定 HTTP 方法的访问(如 CORS 预检请求的 OPTIONS 类型请求)。
参数说明:
method:HTTP 方法枚举值(如 GET、POST、PUT、DELETE)。
使用示例:
http.authorizeHttpRequests(authorize -> authorize .requestMatchers(HttpMethod.OPTIONS).permitAll() // 允许所有OPTIONS请求 .anyRequest().authenticated() );
匹配指定 HTTP 方法且符合路径表达式的请求,精确控制不同 HTTP 方法对同一资源的访问权限(如 RESTful API,GET/POST/DELETE 等)。
参数说明:
method:HTTP 方法枚举值(如 GET、POST、PUT、DELETE)。
patterns:Ant 风格路径表达式(如 /sys/*)。
使用示例:
http.authorizeHttpRequests(authorize -> authorize // 仅 GET 请求需要 normal 权限 .requestMatchers(HttpMethod.GET, "/sys/**").hasAuthority("normal") // 仅 POST 请求需要 admin 权限 .requestMatchers(HttpMethod.POST, "/sys/**").hasAuthority("admin") .anyRequest().authenticated() );
使用自定义请求匹配器(RequestMatcher)进行匹配,支持更复杂的匹配逻辑。
参数说明:
requestMatchers:一个或多个 RequestMatcher 接口的实现。
使用示例:
http.authorizeHttpRequests(authorize -> authorize // 自定义匹配器(示例) .requestMatchers(new RequestMatcher() { @Override public boolean matches(HttpServletRequest request) { return request.getServletPath().matches("/sys/get"); } }).hasRole("normal") );
RequestMatcher 接口的常见实现类:
AntPathRequestMatcher:Ant 风格路径匹配。
RegexRequestMatcher:正则表达式匹配。
AndRequestMatcher/OrRequestMatcher:组合多个匹配器。
在之前认证过程中我们就已经使用过 anyRequest(),用于定义所有未被前面规则匹配的请求的访问策略。它属于 AuthorizeHttpRequestsConfigurer 类,必须作为最后一个规则配置,用于设置默认的访问策略。
核心作用:
(1)为所有未明确配置的请求提供兜底策略(如要求认证、拒绝访问等)。
(2)确保安全配置的完整性,避免遗漏路径。
使用方式如下:
(1)要求所有请求必须认证
http.authorizeHttpRequests(authorize -> authorize .requestMatchers("/public/**").permitAll() // 公开路径 .anyRequest().authenticated() // 其他请求需认证 );
(2)拒绝所有未明确允许的请求
http.authorizeHttpRequests(authorize -> authorize .requestMatchers("/public/**").permitAll() // 公开路径 .anyRequest().denyAll() // 其他请求拒绝访问 );
(3)基于表达式的访问控制
http.authorizeHttpRequests(authorize -> authorize .requestMatchers("/public/**").permitAll() // 公开路径 // 需认证且有 admin 权限 .anyRequest().access(new WebExpressionAuthorizationManager("isAuthenticated() && hasAuthority('admin')")) );
该方法是一个用于匹配请求调度类型(Dispatcher Type)的配置方法。它允许你针对不同类型的请求调度(如 forward、include、error 等)应用特定的安全规则。
方法定义如下:
public C dispatcherTypeMatchers(DispatcherType... dispatcherTypes)
方法接收另个或多个 DispatcherType 类型的参数。
DispatcherType 表示请求调度类型,Servlet 规范定义了以下几种请求调度类型:
REQUEST:直接来自客户端的请求(默认类型)。
FORWARD:通过 RequestDispatcher.forward() 转发的请求。
INCLUDE:通过 RequestDispatcher.include() 包含的请求。
ERROR:由容器错误处理机制(如 error-page)处理的请求。
ASYNC:异步处理的请求(如 AsyncContext)。
Spring Security 中,默认只对 REQUEST 和 ASYNC 类型的请求应用安全规则。如果你需要对其他类型(如 FORWARD、INCLUDE)生效,必须显式配置。
注意:dispatcherTypeMatchers() 主要影响 Spring Security 过滤器链的执行范围。例如,设置 dispatcherTypeMatchers(DispatcherType.FORWARD) 会使过滤器链仅对转发请求生效。
某些安全规则可能只适用于特定类型的请求调度。例如:
(1)静态资源(如 CSS、JS)在被 forward 时可能需要不同的安全策略。
(2)错误页面的请求可能需要特殊的访问控制。
配置 DispatcherType.FORWARD 和 DispatcherType.ERROR 类型的请求允许访问,DispatcherType.REQUEST 类型的请求直接拒绝,如下:
http.authorizeHttpRequests(authorize -> authorize // 仅对 FORWARD 类型的请求允许访问 .dispatcherTypeMatchers(DispatcherType.FORWARD).permitAll() // 对 ERROR 类型的请求允许访问 .dispatcherTypeMatchers(DispatcherType.ERROR).permitAll() // 对 REQUEST 类型的请求直接拒绝 .dispatcherTypeMatchers(DispatcherType.REQUEST).denyAll() .requestMatchers("/sys/**").hasRole("admin") // 没有作用 .anyRequest().authenticated() );
到这里,Spring Security 中用于请求匹配的几个方法介绍完了,其中 requestMatchers() 和 anyRequest() 用得最多,anyRequest() 通常用来进行兜底。例如:
anyRequest().authenticated() 显示配置规则以外的所有请求地址需要鉴权,这可以用于后端管理系统配置,少部分页面可以没有登录也能访问。
anyRequest().permitAll() 显示配置规则以外的所有请求地址不需要鉴权,这可以用于网站配置,仅有后端管理系统需要鉴权,其他页面不需要鉴权。
更多知识参考官网文档。