AccessDecisionManager

      ConfigAttribute负责表述规则,AccessDecisionVoter负责为规则表决,但最终的访问授权是否通过是由AccessDecisionManager进行决策的。

      AccessDecisionManager为当前的访问规则进行决策,是否给予访问的权限。无论是decide方法还是supports方法,AccessDecisionManager本身并不完成相关的逻辑,全部交由其管理的AccessDecisionVoter依次去判断与执行。而根据decide的逻辑规则不同,Spring Security中分别存在三种不同decide决策规则的AccessDecisionManager,它们分别是:

  • AffirmativeBased
  • UnanimousBased
  • ConsensusBased

  在Spring Security默认设置中,使用的是AffirmativeBased。在框架设计中AccessDecisionManagerAccessDecisionVoter的集合类,管理着对于不同规则进行判断与表决的AccessDecisionVoter们。 但不同的是,AccessDecisionVoter分别都只会对自己支持的规则进行表决,如一个资源的访问规则存在多个并行时,便不能以某一个AccessDecisionVoter的表决作为最终的访问授权结果。AccessDecisionManager的职责便是在这种场景下,汇总所有AccessDecisionVoter的表决结果后给出一个最终的决策。从而导致框架中预设了三种不同决策规则的AccessDecisionManager的实现类。

  

 

   AffirmativeBased的逻辑就是一票通过——当前只要存在任何一个投了赞同表的AccessDecisionVoter便会最终给予相关授权。UnanimousBased所代表的一票否则制,所有人都没有反对意见。调整Java Config配置代码将使用的AccessDecisionManager实现变更为UnanimousBased

@EnableGlobalMethodSecurity(prePostEnabled = true,securedEnabled = true)
@Configuration
public class MethodSecurityConfiguration extends GlobalMethodSecurityConfiguration {
    @Override
    protected AccessDecisionManager accessDecisionManager() {
        List<AccessDecisionVoter<? extends Object>> decisionVoters = new ArrayList();
        ExpressionBasedPreInvocationAdvice expressionAdvice = new ExpressionBasedPreInvocationAdvice();
        expressionAdvice.setExpressionHandler(this.getExpressionHandler());
        decisionVoters.add(new RoleVoter());
        decisionVoters.add(new AuthenticatedVoter());
        decisionVoters.add(new MinuteBasedVoter());
        return new UnanimousBased(decisionVoters);
    }
}

  ConsensusBased可能是三个规则里最“民主”,即少数服从多数制。

posted on 2022-07-31 10:39  溪水静幽  阅读(592)  评论(0)    收藏  举报