当前位置: 首页 > 后端技术 > PHP

RBAC笔记

时间:2023-03-29 18:13:32 PHP

Q0。你需要了解哪些概念?一些概念的具体定义如下:用户:与计算机系统交互的人(在很多设计中,单个用户可能有多个登录身份(ID),可能同时处于活动状态,但身份验证机制可以make多个标识符匹配到一个特定的人,即用户在计算机系统中是唯一的)subject:代表用户行为的计算机进程(可以看作是用户的代理)object(客体):计算机系统Any可访问的资源操作(operation):对象触发的活动过程权限(permission):系统中授权可以执行的动作,即对象和操作的组合作用:不同权限或权限的集合roles(responsibility)session(session):用户-系统交互的例子Q1.什么是RBAC?请参考百度百科和维基百科的核心概念:用户通过分配角色获得相应的权限,而不是直接给用户授予权限Q2。为什么RBAC是通过角色给用户分配权限,而不是直接给用户授予权限?通常,用户和权限之间的关系经常变化,而角色和权限之间的关系相对稳定。例如系统中某个用户辞职,只需要撤销该用户在系统中的角色授权即可。Q3.RBAC0、RBAC1、RBAC2、RBAC3之间有什么联系?RBAC0总结:元素:用户、角色、权限、构成权限的操作、操作对应的对象映射:用户-角色、角色-权限(角色与角色、角色与权限之间不存在多层继承关系)权限:boundinAbstractconceptsoncomputeroperationsandresourceobjects(operation+object)RBAC基础模型的动态组件包括:ofusers)Request,subjecttouser应该是单一的映射,但usertosubject不一定),这个概念主要出现在动态模型RBAC1总结:基于rbac0,与rbac0的区别在于角色可以在多个继承layersusingmulti-layerroles原因:单个角色通常有重叠的功能(属于不同角色的用户会被授予一些通用权限)Connector角色:u最终不直接分配给用户;它可以包含任何一组权限,如抽象功能、抽象职责、抽象任务或抽象活动(以便于重用);通常如果角色中有80%或更多的权限重叠,那么你可以选择创建连接器角色;RBAC2总结:在rbac0的基础上,与rbac0的区别在于增加了约束的概念(主要是SeparationofDutiesConstraints)SeparationofDuties(SoD):关键操作必须由两人或多人共同完成,这样就没有人可以破坏securitysystem单独(所以在rbac中满足职责分离约束,即有效角色A和有效角色B对应的用户集合不能有交集)职责分离方法:静态和动态方法静态职责分离model:当一个用户被赋予一个角色时,对角色施加约束(例如,如果一个用户被授予角色A,它不能授予角色B)动态职责分离模型:当用户正在积极使用系统(例如,可以同时授予用户角色A和角色B,但不允许在一个会话中同时充当两个角色)Q4.在编码实践中,RBAC模块可能包含什么?用户管理:用户的增删改查角色管理:角色的增删改查权限管理:权限的增删改查日志管理:日志的增删改查资源参考对那些需要rbac模块管理的资源)权限判断操作:提供判断权限的接口(常见形式如:checkAccess(user,role,params))session管理:即针对当前用户互动Q5.rbac中身份认证和权限授予有什么区别和联系?授权和认证是访问控制的基础。正确的授权实际上取决于身份验证。这是确定“你是谁”的过程;权限授予是确定“你可以做什么”的过程(即权限授予机制对用户是否可以访问系统资源做出“是”或“否”的决定)Q6.RBAC1中权限继承结构如何设计?下面只是个人经验分析系统,列出一些可能的角色分析系统,列出所有需要管理的资源,列出每个资源需要管理的所有操作。根据每个资源的每个操作,组合所有的基础(操作,资源)(只分析那些需要权限管理的),形成“最低级权限”并将当前存在的所有权限的集合逐层划分(根据最小权限原则,并联系可能的角色)根据上一步的划分,在各个边界提取角色(可能包括连接器角色)对上述工作进行梳理,得到基本的权限继承结构。分析基本权限继承结构中的元素,判断是否需要附加规则(rulescanbe用于保证在满足某些前置条件的情况下进行权限判断。规则不一定要附加到permissionorrole,也可以附加到assignment中。看实际编码注意事项)将具有规则“作为其“最低级别权限”的上级权限的“权限”,最后如果“lowest-levelpermission”没有上层角色,可以考虑将其从结构中删除并重新审视,优化各元素的命名。如果在第7步中没有选择权限或者给角色附加规则,则需要考虑如何给一个assignment附加一个ruleQ7.在实际项目中,经常遇到一个role是基于某个resource的,怎么处理?具体问题描述:在某个系统中,一个resource(object)A需要进行权限管理(A指的是一类资源,假设它包含了具体的这一类资源a,b,c...)有一个用户u,u可以访问(access)A类资源中的a和b。用户u被分配了资源a的角色r1,并且u被分配了资源b的角色r2。如何实现rbac使其满足上述要求呢?答:通常需要在rbac中添加一个新的基本元素规则。规则的作用是在进行权限判断时限制前置条件。规则可以附加到权限、角色或分配(即一个用户分配某个角色:(用户,角色))。在确定权限的过程中,需要执行规则来对应上述问题。可以添加一个表T,T中的每条记录包含(user,resourceA,role),执行规则的目的是判断表中是否存在(u,a,r1)或(u,b,r2)T.个人倾向于在作业中遵守规则。这样可以让权限继承结构更加清晰Q8.rbac实现时权限判断的具体逻辑是什么?通常,递归用于实现。我们以YII2中提供的代码为例(yii2中源码位置为vendor\yiisoft\yii2\rbac\DbManager.php,此处代码删除了一些不相关的内容)publicfunctioncheckAccess($userId,$permissionName,$params=[]){$assignments=$this->getAssignments($userId);//先找到所有已经授予当前用户的角色if($this->hasNoAssignments($assignments)){returnfalse;//如果没有授权,当然判断失败}//递归返回$this->checkAccessRecursive($userId,$permissionName,$params,$assignments);}protectedfunctioncheckAccessRecursive($user,$itemName,$params,$assignments){if(($item=$this->getItem($itemName))===null){returnfalse;//如果要判断的权限或角色根本不存在,自然判断failed}//需要判断的item是否存在,先执行当前Item的规则,规则可以用来执行一些业务逻辑if(!$this->executeRule($us呃,$item,$params)){返回false;}//如果当前需要判断的角色确实授予了用户,那么就可以返回true,结束递归if(isset($assignments[$itemName])||in_array($itemName,$this->defaultRoles)){返回真;}//获取当前Item的前一项,递归判断$query=newQuery;$parents=$query->select(['parent'])->from($this->itemChildTable)->where(['child'=>$itemName])->column($this->db);foreach($parentsas$parent){if($this->checkAccessRecursive($user,$parent,$params,$assignments)){返回真;}}返回假;}上面代码可以看到,使用了rule,在yii2中可以绑定对应的rule到permission或者role(但是赋值中不能绑定rule),引入rule可以解决问题在Q7。为了实现规则在赋值中的绑定,下面是修改后的代码(除了checkAccessRecursive方法需要修改外,还有其他相关方法需要修改,这里就不一一列举了,可以查看github项目详情:https://github.com/Darkgel/tr...)protectedfunctioncheckAccessRecursive($user,$itemName,$params,$assignments){if(($item=$this->getItem($项目名称))===空){返回假;}if(!$this->executeRule($user,$item,$params)){返回false;}if(in_array($itemName,$this->defaultRoles)){返回真;}//这里添加了对assignment中的规则进行判断if(isset($assignments[$itemName])){$assignment=$assignments[$itemName];如果($this->executeRule($user,$assignment,$params)){返回真;}}$查询=新查询;$parents=$query->select(['parent'])->from($this->itemChildTable)->where(['child'=>$itemName])->column($this->db);foreach($parentsas$parent){if($this->checkAccessRecursive($user,$parent,$params,$assignments)){返回真;}}返回假;}