Spring Security6 请求地址映射,实现权限管理

通过上面示例代码:

Spring Security6 请求地址映射,实现权限管理

实现了以 /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()
)

requestMatchers()

该方法是配置 HTTP 请求路径匹配规则的核心方法,用于精确控制哪些 URL 需要哪些权限才能访问。requestMatchers() 方法有四个重载方法:

  • requestMatchers(String... patterns)

  • requestMatchers(org.springframework.http.HttpMethod method)

  • requestMatchers(org.springframework.http.HttpMethod method, String... patterns)

  • requestMatchers(RequestMatcher... requestMatchers)

下面逐一详细介绍:

requestMatchers(String... patterns)

基于 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

requestMatchers(HttpMethod method)

匹配指定 HTTP 方法的所有请求(不限制路径)。常用于开放特定 HTTP 方法的访问(如 CORS 预检请求的 OPTIONS 类型请求)。

参数说明:

  • method:HTTP 方法枚举值(如 GET、POST、PUT、DELETE)。

使用示例:

http.authorizeHttpRequests(authorize -> 
    authorize
        .requestMatchers(HttpMethod.OPTIONS).permitAll()  // 允许所有OPTIONS请求
        .anyRequest().authenticated()
);

requestMatchers(HttpMethod method, String... patterns)

匹配指定 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()
);

requestMatchers(RequestMatcher... requestMatchers)

使用自定义请求匹配器(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()

在之前认证过程中我们就已经使用过 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')"))
);

dispatcherTypeMatchers()

该方法是一个用于匹配请求调度类型(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()  显示配置规则以外的所有请求地址不需要鉴权,这可以用于网站配置,仅有后端管理系统需要鉴权,其他页面不需要鉴权。

更多知识参考官网文档。

说说我的看法
全部评论(
没有评论
关于
本网站专注于 Java、数据库(MySQL、Oracle)、Linux、软件架构及大数据等多领域技术知识分享。涵盖丰富的原创与精选技术文章,助力技术传播与交流。无论是技术新手渴望入门,还是资深开发者寻求进阶,这里都能为您提供深度见解与实用经验,让复杂编码变得轻松易懂,携手共赴技术提升新高度。如有侵权,请来信告知:hxstrive@outlook.com
其他应用
公众号