摘要:例如,系统中某个用户辞职了,只需要将系统中该用户的角色授权撤销即可。
Q0.有哪些概念需要知道?
一些概念的具体定义如下
用户(user): 和计算机系统交互的人(在许多设计方案中,单个用户可能拥有多个登录标识(ID),这些标识可能同时处于活跃状态,但身份验证机制可以使多个标识匹配到某个具体的人,即用户对于计算机系统来说具有唯一性)
主体(subject): 一个代表用户行为的计算机进程(可以看成是用户的agent)
客体(object): 计算机系统中任意可访问的资源
操作(operation): 由客体触发的活动进程
权限(permission): 系统中授权可以执行的动作,即客体和操作的组合
角色: 不同权限或角色(职责)的集合
会话(session) : 用户和系统交互的实例
Q1.什么是RBAC?请自行参考百度百科和维基百科
核心概念:用户通过指派角色而获取相应的权限,而非直接把权限赋予用户
Q2.RBAC为什么通过角色来为用户分配权限,而不直接把权限赋予用户?通常用户和权限的关系变更频繁,而角色和权限的关系则相对稳定。例如,系统中某个用户辞职了,只需要将系统中该用户的角色授权撤销即可。
Q3.RBAC0,RBAC1,RBAC2,RBAC3有什么联系?RBAC0总结:
元素: 用户,角色,权限,组成权限的操作,操作对应的客体
映射: 用户-角色,角色-权限(角色与角色,角色与权限之间没有多层继承)
权限: 绑定在在计算机操作和资源客体上的抽象概念(操作 + 客体)
RBAC基础模型的动态组件包括: 角色激活和主体访问
主体: 能够访问处于控制下的角色、操作和客体的活动实体(主体代表用户完成其所有请求,主体到用户应是单一映射,而用户到主体则不一定),这个概念主要出现在动态模型中
RBAC1总结:
基于rbac0,与rbac0的区别是角色之间可以多层继承
使用多层角色的原因:单一角色通常出现功能重叠的现象(属于不同角色的用户都会被授予一些一般性权限)
连接器角色:通常不直接赋予用户;可以包含任意的权限集,作为抽象功能,抽象职责,抽象任务或抽象活动(便于重用);通常如果在角色中有80%或更多的权限重叠,那么就可以选择创建一个连接器角色;
RBAC2总结:
基于rbac0,与rbac0的区别是增加约束概念(主要是职责分离约束)
职责分离(SoD): 关键操作必须由两个或更多的人来完成,这样任何一个人都不可能多带带的破坏安全系统(所以在rbac中满足职责分离约束即有效角色A和有效角色B对应的用户集合不能有交集)
职责分离方法: 静态和动态方法
静态职责分离模型:在为用户指派角色时,就为角色施加约束(例如,如果为某用户授予角色A,就不能再为其授予角色B)
动态职责分离模型:用户以活动状态使用系统时其约束才会发挥作用(例如,它可以同时赋予某用户角色A和角色B,但不允许在一个会话中同时充当两个角色)
Q4.在编码实践中RBAC模块可能包含什么?用户管理:用户的增删改查
角色管理:角色的增删改查
权限管理:权限的增删改查
日志管理:日志的增删改查
授权与撤销授权操作
资源管理:资源的增删改查(注意:这里的资源指的是那些需要被rbac模块进行权限管理的资源)
权限判断操作:提供用于判断权限的接口(常见形式如:checkAccess(user,role,params))
会话管理:即对用户在当前交互中的活动角色进行管理
Q5.身份鉴别与rbac中权限授予的区别与联系?权限授予和身份鉴别是访问控制的基础
正确的权限授予事实上依赖于身份鉴别
身份鉴别是确定“你是谁“的过程;权限授予则是确定”你能干什么“的过程(即权限授予机制对用户是否可以访问系统资源做出”是“或”否“的决定)
Q6.在RBAC1中如何设计权限继承结构?以下仅为个人经验
分析系统,列出一些可能存在的角色
分析系统,列出所有需要被管理的资源
对每种资源列出所有需要被管理的操作
根据每种资源的每种操作,组合出所有的基本(操作,资源)(只分析需要进行权限管理的),形成"最底层permission"
对所有当前存在的permission构成的集合进行逐层划分(按照最小权限原则,并联系可能存在的角色)
根据上一步的划分,在每一个分界处提取出角色(其中可能包含连接器角色)
整理以上的工作,得到基本权限继承结构
对基本权限继承结构中的元素进行分析,确定是否需要附加rule(rule可以用于确保是在满足一些前置条件的情况下进行权限判定,rule不一定非要附加在permission或role上,也可以附加于assignment上,看实际编码时的考虑)
将带有rule的"permission"作为其"最底层permission"的上层权限,最后如果"最底层permission"没有上层角色,则可以考虑从结构中删除
整理并回顾,优化每个元素的命名
如果在第7步中不选择在permission或role上附加rule,则需要考虑如何在assignment上附加rule
Q7.在实际项目中会经常遇到角色是基于某种资源的情况,该如何处理?问题的具体描述:
在某一系统中,资源(客体)A需要进行权限管理。(A指的是一类资源,假设其中包括具体的该类资源a,b,c...)
存在用户u,u可以访问(access)A类资源中的a和b
用户u对于资源a被赋予角色r1,u对于资源b被赋予角色r2
需要如何实现rbac使得其满足以上需求?
Answer:
通常需要在rbac添加一个新的基本元素rule,rule的作用在于:当进行权限判定时,限定前置条件。
rule可以附加在permission,role或assignment(即某个用户赋予某种角色:(user,role))中,在判定权限过程中,需要执行rule
对应于上面的问题,可以添加一张表T,T中的每条记录包含(user,resourceA,role),执行rule的目的是判断(u,a,r1)或(u,b,r2)存在于表T中
个人偏向于在assignment中绑定rule,这样可以使权限继承结构更为清晰
Q8.在实现rbac时,进行权限判定的具体逻辑是怎样的?通常在实现的时候会用到递归,下面以YII2中提供的代码为例(源码在yii2中的位置为vendoryiisoftyii2 bacDbManager.php,这里的代码删减了一些无关的内容)
public function checkAccess($userId, $permissionName, $params = []) { $assignments = $this->getAssignments($userId);//先查找当前用户的已经授予的所有角色 if ($this->hasNoAssignments($assignments)) { return false;//如果没有任何授权的话,当然是判定失败 } //递归 return $this->checkAccessRecursive($userId, $permissionName, $params, $assignments); } protected function checkAccessRecursive($user, $itemName, $params, $assignments) { if (($item = $this->getItem($itemName)) === null) { return false;//如果所要判定的permission或role根本不存在,自然判定失败 } //需要判定的item存在,先执行当前Item的rule,rule可以用于执行一些业务逻辑 if (!$this->executeRule($user, $item, $params)) { return false; } //如果当前需要判定的role确实授予了该用户,那么就可以返回true,结束递归 if (isset($assignments[$itemName]) || in_array($itemName, $this->defaultRoles)) { return true; } //获取当前Item的上一层item,递归判定 $query = new Query; $parents = $query->select(["parent"]) ->from($this->itemChildTable) ->where(["child" => $itemName]) ->column($this->db); foreach ($parents as $parent) { if ($this->checkAccessRecursive($user, $parent, $params, $assignments)) { return true; } } return false; }
在上面的代码中可以看到,当中使用了rule,在yii2中可以在permission或role中绑定相应的rule(但在assignment中无法绑定rule),引入rule可以解决Q7中的问题
为了实现在assignment中绑定rule,以下是经过修改后的代码(除了checkAccessRecursive方法需要修改外,还有其他的相关方法需要修改,但此处就不列出了,具体可以查看github项目:https://github.com/Darkgel/tr...)
protected function checkAccessRecursive($user, $itemName, $params, $assignments) { if (($item = $this->getItem($itemName)) === null) { return false; } if (!$this->executeRule($user, $item, $params)) { return false; } if(in_array($itemName, $this->defaultRoles)){ return true; } //这里添加了对assignment中的rule进行判断 if (isset($assignments[$itemName])) { $assignment = $assignments[$itemName]; if($this->executeRule($user, $assignment, $params)){ return true; } } $query = new Query; $parents = $query->select(["parent"]) ->from($this->itemChildTable) ->where(["child" => $itemName]) ->column($this->db); foreach ($parents as $parent) { if ($this->checkAccessRecursive($user, $parent, $params, $assignments)) { return true; } } return false; }
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/30664.html
摘要:年初开始研究,至目前已发表近篇学习笔记。同时,他也是中国社区的活跃者,见证了中国社区的一路成长。经本人授权,从本周开始,中国将转载他的学习笔记,由浅入深地分享他在学习过程中的收获。节点包含的组件目前这三个组件需要部署在同一台机器上。 作者:宋净超 宋净超(Jimmy Song),TalkingData 容器技术负责人,微服务和云原生应用布道者。2017 年初开始研究 Kubernete...
摘要:数据库设计的三大范式确保每列的原子性如果每列都是不可再分的最小单元信息,则满足第一范式,比如下图中,地址是由国家和城市组成的,显然可以继续在拆分成两个列,国家和城市,是不满足第一范式的,需要将地址列差分成国家和城市两个列。 showImg(https://segmentfault.com/img/remote/1460000018997429?w=1100&h=546); 阅读原文 ...
摘要:近来部门接到一个外包项目,是基于现有的系统做一个知识文档库,类似于百度网盘一样的功能,只是在角色和权限上与网盘不同,这个项目我们部门称为,,难点就在于文件的权限管理。 近来部门接到一个外包项目,是基于现有的系统做一个知识文档库,类似于百度网盘一样的功能,只是在角色和权限上与网盘不同,这个项目我们部门称为KM,Knowledge Manager ,难点就在于文件的权限管理。 以下...
阅读 3735·2021-11-24 10:46
阅读 1705·2021-11-15 11:38
阅读 3759·2021-11-15 11:37
阅读 3479·2021-10-27 14:19
阅读 1938·2021-09-03 10:36
阅读 1990·2021-08-16 11:02
阅读 2997·2019-08-30 15:55
阅读 2247·2019-08-30 15:44