AuthorizationManager和AccessDecisionManager

AuthorizationManagerAccessDecisionManager 都是 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 来投票决定是否允许用户访问。
  • 工作流程
    1. 请求到达 FilterSecurityInterceptor
    2. FilterSecurityInterceptor 调用 AccessDecisionManager 来决定是否允许访问。
    3. 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(授权结果)。
  • 工作流程
    1. 请求到达时,AuthorizationManager 会接收到 Authentication 对象。
    2. AuthorizationManager 根据提供的授权规则,直接做出 truefalse 的授权决策。
public interface AuthorizationManager<T> {
    AuthorizationDecision check(Supplier<Authentication> authentication, T object);
}

关系

  1. 历史演变AccessDecisionManager 是 Spring Security 的旧授权机制,而 AuthorizationManager 是新引入的授权机制。AuthorizationManager 提供了更简洁、更灵活的授权方式,可以看作对 AccessDecisionManager 的一种替代或简化。

  2. 授权决策方式

    • AccessDecisionManager:依赖多个 AccessDecisionVoter 进行投票,最后根据投票结果(比如 AffirmativeBasedConsensusBased 等投票策略)做出决策。
    • AuthorizationManager:直接返回一个 AuthorizationDecision,简化了整个流程,不需要多个投票器。
  3. 功能重叠:在 Spring Security 5.5 之后,AuthorizationManager 逐渐成为推荐的授权机制,而 AccessDecisionManager 仍然存在于老的应用中,但一般来说,它们不会同时使用。如果你在项目中使用 AuthorizationManager,则不需要再配置 AccessDecisionManagerAccessDecisionVoter


具体示例对比

使用 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 使用了 RoleVoterAuthenticatedVoter 来投票,最后通过 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") 来做出授权决策,代码更为简洁。


总结

  1. AccessDecisionManager:基于多个 AccessDecisionVoter 进行投票,然后由 AccessDecisionManager 根据投票结果做出最终决策。这是旧的授权机制,常用于较为复杂的投票场景。
  2. AuthorizationManager:这是 Spring Security 5.5 引入的更灵活、更简洁的授权机制,推荐用于新的项目或应用。它可以直接根据 Authentication 和资源上下文进行授权决策,无需依赖投票机制。

如果你是从老项目迁移或者新项目开发,建议使用 AuthorizationManager 来实现授权逻辑,因为它简化了授权流程,并提供了更现代化的授权模型。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值