AuthorizationManager
和 AccessDecisionManager
都是 Spring Security 中用于处理授权的组件,但它们来自不同的版本和授权机制。在 Spring Security 5.5 之前,授权主要是通过 AccessDecisionManager
实现的。而在 Spring Security 5.5 之后,引入了新的授权机制,即 AuthorizationManager
,作为一种替代或补充。
主要区别和关系
1. AccessDecisionManager
(旧机制)
- 版本:引入于 Spring Security 早期版本,一直沿用到 Spring Security 5.x。
- 作用:通过多个
AccessDecisionVoter
对用户访问资源的权限进行投票,最后做出授权决策。 - 结构:
AccessDecisionManager
接收Authentication
对象、目标对象(如FilterInvocation
)、和配置的权限信息,然后通过AccessDecisionVoter
来投票决定是否允许用户访问。 - 工作流程:
- 请求到达
FilterSecurityInterceptor
。 FilterSecurityInterceptor
调用AccessDecisionManager
来决定是否允许访问。AccessDecisionManager
收集多个AccessDecisionVoter
的投票结果,做出最终授权决策。
- 请求到达
public interface AccessDecisionManager {
void decide(Authentication authentication, Object object, Collection<ConfigAttribute> configAttributes)
throws AccessDeniedException, InsufficientAuthenticationException;
}
2. AuthorizationManager
(新机制)
- 版本:引入于 Spring Security 5.5,作为一种更现代、更灵活的授权机制。
- 作用:通过直接检查
Authentication
对象来做出授权决策,简化了授权流程,不再依赖投票机制。 - 结构:
AuthorizationManager
接受Authentication
对象以及请求的上下文信息(如RequestAuthorizationContext
),直接返回一个AuthorizationDecision
(授权结果)。 - 工作流程:
- 请求到达时,
AuthorizationManager
会接收到Authentication
对象。 AuthorizationManager
根据提供的授权规则,直接做出true
或false
的授权决策。
- 请求到达时,
public interface AuthorizationManager<T> {
AuthorizationDecision check(Supplier<Authentication> authentication, T object);
}
关系
-
历史演变:
AccessDecisionManager
是 Spring Security 的旧授权机制,而AuthorizationManager
是新引入的授权机制。AuthorizationManager
提供了更简洁、更灵活的授权方式,可以看作对AccessDecisionManager
的一种替代或简化。 -
授权决策方式:
AccessDecisionManager
:依赖多个AccessDecisionVoter
进行投票,最后根据投票结果(比如AffirmativeBased
、ConsensusBased
等投票策略)做出决策。AuthorizationManager
:直接返回一个AuthorizationDecision
,简化了整个流程,不需要多个投票器。
-
功能重叠:在 Spring Security 5.5 之后,
AuthorizationManager
逐渐成为推荐的授权机制,而AccessDecisionManager
仍然存在于老的应用中,但一般来说,它们不会同时使用。如果你在项目中使用AuthorizationManager
,则不需要再配置AccessDecisionManager
和AccessDecisionVoter
。
具体示例对比
使用 AccessDecisionManager
import org.springframework.security.access.AccessDecisionManager;
import org.springframework.security.access.AccessDecisionVoter;
import org.springframework.security.access.vote.AffirmativeBased;
import org.springframework.security.access.vote.RoleVoter;
import org.springframework.security.access.vote.AuthenticatedVoter;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.web.access.intercept.FilterSecurityInterceptor;
import java.util.Arrays;
public class SecurityConfig {
public AccessDecisionManager accessDecisionManager() {
// 定义投票器
AccessDecisionVoter<?> roleVoter = new RoleVoter();
AccessDecisionVoter<?> authenticatedVoter = new AuthenticatedVoter();
return new AffirmativeBased(Arrays.asList(roleVoter, authenticatedVoter)); // Affirmative 策略
}
public void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/admin").hasRole("ADMIN")
.anyRequest().permitAll()
.and()
.addFilter(new FilterSecurityInterceptor()); // 使用 AccessDecisionManager
}
}
在这里,AccessDecisionManager
使用了 RoleVoter
和 AuthenticatedVoter
来投票,最后通过 AffirmativeBased
策略做出决策。
使用 AuthorizationManager
import org.springframework.security.authorization.AuthorityAuthorizationManager;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class SecurityConfig {
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http
.authorizeHttpRequests(authz -> authz
.requestMatchers("/admin").access(AuthorityAuthorizationManager.hasRole("ADMIN")) // 使用 AuthorizationManager
.anyRequest().permitAll()
)
.formLogin(); // 表单登录
return http.build();
}
}
在这个示例中,AuthorizationManager
直接通过 AuthorityAuthorizationManager.hasRole("ADMIN")
来做出授权决策,代码更为简洁。
总结
AccessDecisionManager
:基于多个AccessDecisionVoter
进行投票,然后由AccessDecisionManager
根据投票结果做出最终决策。这是旧的授权机制,常用于较为复杂的投票场景。AuthorizationManager
:这是 Spring Security 5.5 引入的更灵活、更简洁的授权机制,推荐用于新的项目或应用。它可以直接根据Authentication
和资源上下文进行授权决策,无需依赖投票机制。
如果你是从老项目迁移或者新项目开发,建议使用 AuthorizationManager
来实现授权逻辑,因为它简化了授权流程,并提供了更现代化的授权模型。