第九期 AccessDecisionManager组件介绍

作为访问控制的最后一期,但确实整个章节部分里最简单的一部分。ConfigAttribute负责表述规则,AccessDecisionVoter负责为规则表决,但最终的访问授权是否通过是由AccessDecisionManager进行决策的。 这一期我们将主要介绍Spring Security中提供的三种主要决策模型。

一、AccessDecisionManager接口说明

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

  • AffirmativeBased
  • UnanimousBased
  • ConsensusBased 在Spring Security默认设置中,使用的是AffirmativeBased

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

二、一票通过AffirmativeBased

第一个我们来介绍,Spring Security中默认提供的访问决策模型AffirmativeBased。一句话来说AffirmativeBased的逻辑就是一票通过——当前只要存在任何一个投了赞同表的AccessDecisionVoter便会最终给予相关授权。

affirmative adj. 肯定的;积极的 n. 肯定语;赞成的一方

假设存在资源A,在RoleVoter中要求有Admin的角色,而在MinutedOddVoter中缺只要是奇数分钟则可以访问。那么在AffirmativeBased模型下,即时用于没有Admin的角色,只要满足奇数分钟的条件一样可以访问目标资源。

    @Secured({"IS_AUTHENTICATED_FULLY","ROLE_USER","MINUTE_ODD"})@RequestMapping("/")public String root(@Autowired Authentication authentication) {return "index";}
复制代码

当我们奇数分钟数访问对应资源的时候:

Voter: org.springframework.security.access.vote.RoleVoter@508280a4, returned: -1
Voter: org.springframework.security.access.vote.AuthenticatedVoter@2846f995, returned: -1
Voter: com.newnil.demo.security.MinuteBasedVoter@1ec9ec13, returned: 1
Authorization successful
复制代码

即使RoleVoterAuthenticatedVoter存在明确的反对,但是因为MinuteBasedVoter满足了时间的要求,一样会得到一个肯定的结果。 这边有一个经验,在默认的AffirmativeBased的模型下客制化AccessDecisionVoter如果不是很决定性的规则,诸如一些辅助性的访问限制避免投出明确的赞同表,而是换个角度,投出明确的反对票,如不满足反对的情况可以投出弃权票。我们在上一期客制化的MinuteBasedVoter便是一个不好的反面教材^_^。

三、一票否决UnanimousBased

第二个,我们再来介绍一个备选的决策规则,即UnanimousBased所代表的一票否则制,所有人都没有反对意见。

unanimous adj. 全体一致的;意见一致的;无异议的

其规则也十分容易懂,只要任意一个AccessDecisionVoter投出了反对票,则无论有多少个赞同票都无法授权访问权限。UnanimousBased代表了与AffirmativeBased完全对立的规则,有点类似五常表决的一票否则制,比如前几年著名的新闻“土耳其要求取消俄罗斯的一票否决票,这个提案被俄罗斯一票否决了”。 同样回到代码上来,我们通过调整Java Config配置代码将使用的AccessDecisionManager实现变更为UnanimousBased

@EnableGlobalMethodSecurity(prePostEnabled = true,securedEnabled = true)
@Configuration
public class MethodSecurityConfiguration extends GlobalMethodSecurityConfiguration {@Overrideprotected 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);}
}
复制代码

对于同样的场景下,如用户已经登录并拥有了对应的权限而因为当前时间不是偶数分钟,那么最终的决策结果因为有一票否决变为了不可访问

 Voter: org.springframework.security.access.vote.RoleVoter@ddc490, returned: 0Voter: org.springframework.security.access.vote.AuthenticatedVoter@27f66035, returned: 1Voter: com.newnil.demo.security.MinuteBasedVoter@4f6b68aa, returned: -1
Access is denied (user is not anonymous);
复制代码

四、少数服从多数ConsensusBased

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

consensus n. 一致;舆论;合意 ConsensusBased对所有投票的AccessDecisionVoter的意见进行汇总,以数量多那一方的结果为准。 但是存在一种特殊情况——平票:如果产生平票则根据配置allowIfEqualGrantedDeniedDecisions来判断是否通过,在默认情况下allowIfEqualGrantedDeniedDecisions值是true。

同样的我们修改Java Config来测试下ConsensusBased的行为:

@EnableGlobalMethodSecurity(prePostEnabled = true,securedEnabled = true)
@Configuration
public class MethodSecurityConfiguration extends GlobalMethodSecurityConfiguration {@Overrideprotected 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());ConsensusBased consensusBased = new ConsensusBased(decisionVoters);consensusBased.setAllowIfEqualGrantedDeniedDecisions(false);//可以调整平票逻辑return consensusBased;}
}
复制代码

我们同样在偶数分钟访问,在登录后访问受限制的资源:

Voter: org.springframework.security.access.vote.RoleVoter@2c1ae72c, returned: 1
Voter: org.springframework.security.access.vote.AuthenticatedVoter@60d5234, returned: 1
Voter: com.newnil.demo.security.MinuteBasedVoter@6a34393c, returned: -1
Authorization successful
复制代码

与之前UnanimousBased的表现不同,因为赞同票大于否对票所以我们最终还是获取了访问的权限。

结尾

作为访问控制的最后一个组件,由于有了之前的铺垫和了解,三种决策规则相比之下会显得简单很多。并且在通常的情况下,对于AccessDecisionManager我们也不太会存在任何客制化的可能性。我们只需要了解如何选择合适的AccessDecisionManager与如何编写相关的Java配置代码即可。 从下一期开始,我们将进入新的主题开始介绍Spring Security中的config包下关于配置的一些内容。 我们下期再见。

转载于:https://juejin.im/post/5cbe69b06fb9a031fb2cd27a

Spring Security教程 Vol 9. AccessDecisionManager组件介绍相关推荐

  1. Spring Security教程

    Spring Security教程 Web系统中登录认证(Authentication)的核心就是凭证机制,无论是Session还是JWT,都是在用户成功登录时返回给用户一个凭证,后续用户访问接口需携 ...

  2. 史上最简单的Spring Security教程(十九):AccessDecisionVoter简介及自定义访问权限投票器

    为了后续对 AccessDecisionManager 的介绍,我们先来提前对 AccessDecisionVoter 做个简单的了解,然后,在捎带手自定义一个 AccessDecisionVoter ...

  3. Spring Security 教程

    Spring Security 教程 在这篇文章中,我们将讨论Spring框架 "安全性"模块基础知识.我们将在即将发布的帖子中开发一些简单而先进的示例. 现在,开发安全应用程序是 ...

  4. Spring Security小教程 Vol 2. Authentication核心组件介绍

    前言 上一期我们介绍了如何最简单的为一个SpringBoot应用添加Spring Security框架,并使其为应用完成用户鉴权和访问控制的授权服务. 这一期我们将聚焦在用户鉴权部分,用户鉴权又可以从 ...

  5. 史上最简单的Spring Security教程(二十八):CA登录与默认用户名密码登录共存详细实现及配置

    ​在前面的文章中,我们自定义了一些CA登录相关的类,如 CertificateAuthorityAuthenticationToken.CertificateAuthorityAuthenticati ...

  6. Spring Security教程 第一弹 初识spring security

    写在前面的话 更多Spring与微服务相关的教程请戳这里 Spring与微服务教程合集 1.概述 核心概念: 认证 授权:Spring Security不仅支持基于URL对Web的请求授权,还支持方法 ...

  7. Spring Security:身份验证令牌Authentication介绍与Debug分析

    在Spring Security中,通过Authentication来封装用户的验证请求信息,Authentication可以是需要验证和已验证的用户请求信息封装.接下来,博主介绍Authentica ...

  8. Spring Security:身份验证入口AuthenticationEntryPoint介绍与Debug分析

    ExceptionTranslationFilter ExceptionTranslationFilter(Security Filter)允许将AccessDeniedException和Authe ...

  9. microsoftsql新建登录用户登录失败_史上最简单的Spring Security教程(九):自定义用户登录失败页面...

    生活中肯定存在这样的场景,在登录某个网站时,难免会忘记密码,或是验证码输入错误,造成多次尝试.所以,有必要适度的提醒用户,到底是什么原因造成了登录失败,如用户名密码不正确.验证码错误等等.由于 Spr ...

最新文章

  1. base64编码 vba_VB VBA ASP 可通用的基于Base64进行加密和解密的函数
  2. java 同步中的线程出现异常会放弃锁吗
  3. ZooKeeper入门(一)
  4. 创建一个对象时,在一个类当中 静态代码块 和普通代码块构造方法 的顺序?
  5. JavaFX技巧1:可调整大小的Canvas
  6. 前端学习(3174):react-hello-react之脚手架的配置
  7. 在maven pom.xml中加载不同的properties ,如localhost 和 dev master等jdbc.properties 中的链接不一样...
  8. 301缓存重定向?301 Moved Permanently (from disk cache)
  9. 社交电商带直播电商功能,可以DIY前端,可以H5和小程序一般商城常用功能齐全
  10. servlet-api-2.5.jar - jar not loaded
  11. jquery ajax 调用webservice以及跨域问题
  12. 设计模式---外观模式(C++实现)
  13. Spring学习笔记(三十六)——SpringBoot 实现大文件分片上传、断点续传及秒传
  14. android直播录像,安卓手机怎么录制直播视频
  15. 效率之王!这些令人惊叹的开发工具不可不知!
  16. cloudera manager报错解决方案
  17. echarts简单日历
  18. 一个JAVA程序员成长之路分享
  19. cocos2dx 安卓环境播放mid音乐
  20. 机器学习应用——无监督学习(实例:31省市居民家庭消费调查学生上网时间分布聚类鸢尾花数据人脸数据特征提取)

热门文章

  1. Android stadio 电脑连上手机可以识别,但是连不上Android stadio
  2. 【剑指offer-Java版】30最小的K个数
  3. 【JavaWeb】Access restriction The type is not accessible due to restriction on required library
  4. StringBuffer、StringBuilder区别以及Synchronized原理
  5. linux vim 字体大小,Linux学习—vim大全
  6. python 模板引擎 对比_Python Web开发模板引擎优缺点总结
  7. (012) java后台开发之Apache与Tomcat有什么关系和区别
  8. WPF MVVM从入门到精通1:MVVM模式简介
  9. python网络编程及高并发问题
  10. Linux 下 的 cc 和 gcc