1. 引言
Spring Security 作为 Spring Framework 的扩展,能帮我们轻松在应用中实现常见安全实践,包括用户认证、授权、API 保护等。本文聚焦其中的核心组件:AuthorizationManager。我们将深入探讨它在 Spring Security 生态中的定位,以及如何用它来加固应用安全。
2. 什么是 Spring Security AuthorizationManager
AuthorizationManager 是一个接口,用于判断已认证实体是否有权访问受保护资源。Spring Security 通过该接口对基于请求、方法和消息的组件做出最终访问控制决策。
理解 AuthorizationManager 前,需先掌握几个关键概念:
- 实体:任何能发起系统请求的对象(如用户或远程服务)
- 认证:验证实体身份的过程(如用户名/密码、令牌等)
- 授权:验证实体是否有权访问资源的过程
- 资源:系统中可访问的信息(如 URL 或文档)
- 权限:常称为角色(Role),表示实体权限的逻辑名称
2.1. 如何使用 AuthorizationManager
AuthorizationManager 接口仅包含两个方法:
AuthorizationDecision check(Supplier<Authentication> authentication, T object);
void verify(Supplier<Authentication> authentication, T object);
两个方法参数相同:
authentication
:提供发起请求实体的Authentication
对象object
:被请求的安全对象(根据请求类型变化)
但功能不同:
check()
返回AuthorizationDecision
(布尔值包装器),表示是否允许访问verify()
无返回值,直接执行授权检查,未授权时抛出AccessDeniedException
2.2. 旧版 Spring Security 中的实现
⚠️ 踩坑提醒:AuthorizationManager 是 Spring Security 5.0 引入的。此前主要使用 AccessDecisionManager
接口。虽然新版仍保留该接口,但已标记为废弃,应优先使用 AuthorizationManager。
3. AuthorizationManager 的实现类
Spring 提供了多种 AuthorizationManager 实现,以下是常用实现:
3.1. AuthenticatedAuthorizationManager
仅根据实体是否已认证返回授权决策,支持三种认证级别:
anonymous
:未认证remember me
:通过记住我认证fully authenticated
:完全认证(非记住我)
✅ 这是 Spring Boot Web 应用的默认实现,默认所有接口只要认证通过即可访问。
3.2. AuthoritiesAuthorizationManager
基于多个权限做授权决策,适合复杂场景。例如博客系统:
- 创建文章:
AUTHOR
和EDITOR
角色均可 - 发布文章:仅
EDITOR
角色可操作
3.3. AuthorityAuthorizationManager
根据实体是否拥有特定角色做决策,适合简单场景。例如:
.requestMatchers("/admin/**").hasRole("ADMIN")
✅ 实际内部委托给 AuthoritiesAuthorizationManager
,是调用 hasRole()
/hasAuthority()
时的默认实现。
3.4. RequestMatcherDelegatingAuthorizationManager
根据 URL 模式委托给其他实现。例如:
- 公开 URL → 委托给总是允许的空实现
- 受保护 URL → 委托给
AuthoritiesAuthorizationManager
✅ 这正是 Spring 在 SecurityFilterChain
中添加请求匹配器时的底层机制。
3.5. ObservationAuthorizationManager
包装其他实现,**额外记录授权决策的监控指标**。当应用中存在有效的 ObservationRegistry
时,Spring 会自动启用。
3.6. 其他实现类
Spring Security 还提供与注解对应的实现:
SecuredAuthorizationManager
→@Secured
PreAuthorizeAuthorizationManager
→@PreAuthorize
PostAuthorizeAuthorizationManager
→@PostAuthorize
所有安全注解都有对应的 AuthorizationManager 实现。
3.7. 组合使用多个 AuthorizationManager
实际开发中常组合使用多个实现。看这个 SecurityFilterChain
示例:
@Bean
SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http.authorizeHttpRequests((authorize) -> authorize
.requestMatchers("/posts/publish/**").hasRole("EDITOR")
.requestMatchers("/posts/create/**").hasAnyRole("EDITOR", "AUTHOR")
.anyRequest().permitAll());
return http.build();
}
这里实际使用了五个 AuthorizationManager:
hasRole("EDITOR")
→ 创建AuthorityAuthorizationManager
→ 委托给新的AuthoritiesAuthorizationManager
hasAnyRole("EDITOR", "AUTHOR")
→ 同上机制permitAll()
→ 使用 Spring 提供的静态空实现(总是允许访问)
4. 自定义 AuthorizationManager
当内置实现不满足需求时,可自定义实现:
AuthorizationManager<RequestAuthorizationContext> customAuthManager() {
return new AuthorizationManager<RequestAuthorizationContext>() {
@Override
public AuthorizationDecision check(Supplier<Authentication> authentication, RequestAuthorizationContext object) {
// 自定义授权逻辑
}
};
}
然后在 SecurityFilterChain
中使用:
SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http.authorizeHttpRequests((authorize) ->
authorize.requestMatchers("/custom/**").access(customAuthManager())
return http.build();
}
✅ 通过 RequestAuthorizationContext
可访问 HTTP 请求,能基于 Cookie、Header 等做决策,甚至委托给第三方服务或数据库实现复杂授权逻辑。
5. 总结
本文深入剖析了 Spring Security 的授权机制:
- 介绍了
AuthorizationManager
接口及其核心方法 - 探讨了多种内置实现及其适用场景
- 演示了如何自定义实现满足特殊需求
所有示例代码可在 GitHub 获取。