文档章节

权限设计的杂谈

cross___
 cross___
发布于 08/01 11:27
字数 3653
阅读 8009
收藏 205

权限设计的杂谈

这篇文章的定位,不是宣传某个框架,仅仅之是梳理一下有关权限方面的一些想法和最近项目中的一些探索过程。 我们主要想解决一下问题。

  1. 什么是权限,程序员理解的权限和客户所理解的权限是不是一致的。
  2. 权限的划分原则,权限到底是根据什么原则进行组合的。
  3. 角色是用户与权限之间的必要的关系吗?角色到底承接了什么作用。
  4. 如何进行合理的表设计。
  5. 安全框架。

1.什么是权限

在很多与开发者也好,与客户也好,沟通的过程中我们很多次提到了权限,但是权限具体的含义每个人理解的含义都不明确,这样很容易造成双方信息不对称,有的人就只是把权限理解成某个页面的是否可访问,但是有的人却理解成其他的东西。所以我们要彻底的定义一下权限是什么。

权限到底是名词属性还是动词属性,还是名词、动词属性均包含,这对于权限的含义很重要。如果是名词属性的话,那么它应该是有具体的指代物;如果是动词,则应该具有行为表示。

  • 权限的名词属性:api接口、页面、功能点。
  • 权限的动词属性:可操作、不可操作。

那么我们现在来看,其实权限是名词、动词属性,它一定是表达了两层含义。即控制的对象操作

  1. 例如:权限A表示页面A的可访问。
  2. 例如:权限B表示页面B可访问且页面内的功能b不可使用
  3. 例如:权限C表示接口C不可调用。
  4. 例如:权限D表示页面D可访问,且接口D可访问。

那么进一步的说明,权限可以表示单个控制的对象的操作集合,也可以表示多个控制的对象的操作集合。而这两者的取舍则是有设计人员决定的。

权限的内容

一句话总结权限的含义:what(若干元素)进行how(若干操作)

2.权限的划分原则

我们了解了权限的具体含义之后,接下来就是用的问题,我们该如何去使用权限,如何将系统中的操作元素进行一个组合,这个我借鉴网上的一篇文章来解释。划分原则可以按照“最小特权原则”和“数据抽象原则”。

  • 最小特权原则
  1. 我先举一个反例,我把系统中所有的元素和操作都组合成一个权限。一个用户拥有这个权限就相当拥有了系统所有的功能,实际上这肯定是不行的,用户在一套系统中一定有他不允许操作的内容,哪怕是超级管理员也可能会有不能操作的元素,那么最大化权限则是行不通,因为不符合常理。
  2. 据此,我们就把权限再进行一个拆分,按照业务模块进行拆分,但是这实际上也是不行的。就比如系统中的财务模块,假定模块中含有报销页面和申报页面,如果按照模块进行拆分,那么肯定有用户同时包含了两个互斥功能。
  3. 根据1和2,我们需要按照最小化进行权限划分。但是这个也是值得商榷的,因为不同系统,最小的权限划分对于提供的功能来说,划分的角度也是不同的。
  • 数据抽象原则
  1. “最小特权划分”从某个程度上来说决定了控制的对象 ,而数据抽象原则是是决定了操作
  2. 数据抽象从字面的意思来看,其实很难理解到底是什么意思。通常我们口头上说最多的是CRUD增删查改,这实际上就是数据抽象的一种,我们可以理解成元素操作许可权的意思。
  3. 但是CRUD并不是数据抽象的全部,增删查改用于单实体,基本是没问题的,但是在构建关系上,其实是不够用的,例如任免某个经理管辖某个部门,从业务表面而言它修改了经理的管辖范围。但是从代码底层构建上来说,它属于在经理和部门间新增了一道关系,所以根据需求我们需要再额外的增加一类许可权“任免许可”,这一类型的扩展则需要根据系统实际的业务情况进行划分。

“最小特权”和“数据抽象”分别决定了权限中控制的对象操作,但是这里面还差了一个角度,则是现阶段非常普遍的前后端分离的权限划分的问题。

  • 服务端的权限
  1. 前后端分离下的服务端,本质而言只是提供接口的或者rpc服务等其他资源服务的服务提供方。
  2. 服务端能提供的权限的鉴权机制的对象:接口服务(api或者其他形式的服务)不包含前端的页面或页面中的功能点
  3. 前端或移动端的页面元素的控制和鉴权实质上不由服务端控制
  4. 服务端可以单独的控制服务的权限。
  5. 服务端的服务对象是前端、移动端、第三方客户端,提供的服务是接口服务。

在前后端已经分离的情况下,服务端对于前端而言只是接口的提供者,但无权干涉前端页面的展示,服务端对于前端而言,能提供的是仅鉴权服务的接口而已,但是页面的构成,页面的栏目菜单或页面内的功能点的构成均由前端单独完成的。

  • 前端或移动端的权限
  1. 前端的鉴权包含页面的可访问,和页面上的某项功能按钮是否可以操作。
  2. 前端和移动端的服务对象是用户,提供的服务是可视化的页面。

前后端分离的权限对象

前后端的服务对象的责任划分清晰之后,我们就不会混杂权限的归属的问题,在过去前后端没分离的情况下,页面本身就是服务端的一体,就没有这方面的问题。虽然分清楚了各端本质提供的服务的情况,但是前后端分离的权限划分中仍有新的问题。

  1. 因为服务端和前端的鉴权对象不一致,服务端只能鉴权到api接口,那么是否将api接口和前端的页面乃至页面功能点进行数据库表与表层面的绑定关系。
  2. 如果进行了进行了表与表之间的绑定关系,那么整个权限系统的维护量,是否能在能承受范围之内。
  3. 如果不进行表与表之间的绑定关系,前端页面在操作功能的时候,服务端如何鉴权页面调用的api接口是否在用户可操作的权限之内?

其实上面的问题则需要一个取舍,要么增加运维成本严格控制前端调用api接口的关系,偏重服务端的接口服务鉴权。要么是给api接口和前端页面及功能点再提供一个通性的逻辑判断处理,如:页面及调用的功能点属于某个业务模块的操作许可,而页面触发的接口也刚好是这个业务模块的操作许可,那么鉴权通过,否则鉴权失败。这种就是属于侧重前端对于用户的控制,弱化了接口级的控制。

3.角色与权限的关系

通过1,2的描述,基本确定了权限的定义和划分一个权限的通用法则。用户在系统中最终是通过权限来使用各种功能点,是否有必要在用户和权限中间再额外的附加一个关系。在我们现在的权限设计中,是增加了这样一层关系的,就是角色。

  1. 减少操作层面的重复性。角色其实就是一组权限的集合,是权限集合的更高级抽象,为了便于运维和实际管理,通过角色的赋予,替代了权限赋予用户的繁琐性,在一套系统中,普遍情况都是权限的数量多于角色的数量。
  2. 权限是控制对象操作集合,它本身不存在任何状态,但是在赋予在用户身上则拥有了状态,比如权限A中允许用户访问页面A,权限B允许用户访问页面B,权限D运行用户访问B页面,但是不允许访问A页面。那么这层关系的维护在角色层面的话,会更加清晰,也就是说本身角色具有权限集合组装的策略问题,对于互斥的权限有不同的方案处理。(权限中没有某个操作和权限中禁止某个操作,是两个不同的角度,不能混为一谈)
  3. 因为权限的可能存在互斥性,在实际业务中也会引发角色的互斥性,举一个现实中的案例来解释互斥性:张三是软件部的负责人但因为工作的特殊性也同样隶属于业务部的普通员工,我们设定负责人是可以要求人事部门给本部门进行招聘的,在实际的情况中,张三能给软件部招聘新员工,但是不能给业务部招聘员工。我们把这个案例运用在系统中,张三则是拥有负责人和普通员工两个角色,但是招聘的功能如果不加以控制,则会发生张三给业务部招人的结果。于是为了解决角色的这类问题,引入了职责划分的方案。
  4. 职责划分分为:静态、动态。所谓静态职责划分则是在角色创建之初就已经确定了角色的职责内容。动态职责划分是系统运行过程中对用户已有的角色进行控制,例如:某些角色不能共存在用户身上(互斥)、角色或角色的分配数量限定(控制用量)、角色与角色同时只能激活一个进行使用(时刻唯一)。

引入角色的概念后,实际上这已经是一个比较完整的RBAC的权限设计的模型了。

权限实体图

4.数据表的设计思路

根据3的结论,实质上已经有了一个基础的表设计的雏形。在这里就有一些值得注意的点。

  • (1)问:权限表是否有必要存在?
  • (1)答:这个要结合系统的实际使用场景进行考虑,如果系统中的权限的对象很单一,比如只有页面,或者只有api接口的话,其实权限表可有可无。增加权限表反而会导致初始化项目权限的工作量增加。但是若系统中的权限对象是多个,那么权限表的存在就有了更深层次的意义。在权限对象是多个的情况,权限表的存在就是为了更好更抽象的组合“最小特权”及“责任划分”的操作对象。同时,一旦系统中的操作对象增加了,只需要给权限表增加一个对象表和关系表就可以了。这样易于扩展。
  • (2)问:api接口和页面实际上是没有关系的,但是在鉴权活动是有关系的,页面若和api没有一点绑定联系的话,服务端接口调用的时候则要么拦截掉所有指定的接口(页面和api接口没绑定的话,则页面的接口调用都不能成功),服务端接口完全不拦截接口,也会不安全,但是api接口和页面功能在表结构层面的绑定会产生运维的大量工作成本,如何更好的设计。
  • (2)答:在权限如何划分中已经提过了这一点,在表结构中,我们可以增加一张业务模块表和操作表(也可以在数据字典表中增加这两类数据),我们可以在页面和功能点钟 绑定业务模块和操作表关系,在api接口的代码层面去绑定业务模块和操作,在逻辑上绑定关系,解耦表结构之间的关系,那么可以在一定程度上解决这一点,这样做只会出现一种问题,那就是用户访问页面的时候可调用的api接口会比实际可调用的接口数要多,但是前端权限管理会隐藏功能点,这样就在可视化的程度上解决了这个问题。

5.安全框架

由于我们是基于RBAC的权限设计,现行java框架下最常见的就是shiro和Spring Security 。这两个就是仁者见仁智者见智了,我两者都实用过。仅建议使用shiro的话,可以更好的理解RBAC的设计思路,Spring Security 也是个不错的框架,但是它涉及到的概念太多,并不利于初学者去了解最基本的权限设计。我在这只在学习的角度上去比较这两个框架,并没有再其他领域去做比较,也不去比较。

引用的文章

权限系统与RBAC模型概述[绝对经典]

© 著作权归作者所有

共有 人打赏支持
cross___
粉丝 14
博文 7
码字总数 15096
作品 0
武汉
高级程序员
加载中

评论(23)

cross___
cross___

引用来自“MGL_TECH”的评论

难的不是这些 最难的就是数据权限 那些数据可以查看 那些数据是可以删除
对于数据权限,其实最好能通过功能权限来封闭它,控制到这一级,很不方便,而且对系统的用户素质要求比较高。
haitaosoft
haitaosoft
为了简易一些,我把 角色 定位为 用户的各种集合
孤独的探索号
孤独的探索号
赞,分析得很详细透彻。
至于权限框架可以试试APIJSON哦,提供自动化权限管理,
3行代码可配置一张表对应各种角色的增删改查权限
https://my.oschina.net/tommylemon/blog/1574430
MGL_TECH
MGL_TECH
难的不是这些 最难的就是数据权限 那些数据可以查看 那些数据是可以删除
cross___
cross___

引用来自“cross___”的评论

@sxgkwei 嗯,还真不巧,之前我和我们技术部的老大就为了你说的这个还争论了一番,他的模型比你还多一层概念,你现在说的是权限中引入了 “非”的概念产生的,而我们当时说的是,权限在角色层面的三种状态,“默认使用”(有则可用),“授权使用”(高于默认的使用),“禁止使用”(不允许使用)。
用户能拥有多个角色,而角色则拥有这些不同状态的权限,使用起来就非常复杂,而且还具有冲突性,就例如用户拥有的角色A和角色B,角色A授权使用权限D,角色B禁止使用权限D。那么冲突的时候,程序又如何判断,于是由引入了一层概念。用户的角色策略,比如默认有限策略、禁止使用优先、授权使用优先。来处理这种冲突的关系。
从某个角度上来看这个好像是可行的,但是我个人认为,这种设计有点脱离实际(用户的素质是否能理解这种关系,如果不理解或说不需要用户自定义权限的话,这种设计的存在根本没必要),并且复杂化了使用逻辑。
但是也不能完全的否认这种形式的存在,因为某些业务系统肯定有类似这方面的存在,这就是所谓的脱离了实际业务谈设计都是耍流氓。但是我认可一种原则,我们可以根据业务复杂度和用户的自身素质程度正比例逐级扩充权限的使用维度和逻辑复杂度(并不代表操作界面的复杂)。

引用来自“sxgkwei”的评论

我只能说,你老大真是想多了。在“非”与“是”同时存在的情况下,很多普通用户都理解不了,还指望客户理解你们方案里的这一套?而且,权限系统始终只是辅助性系统,真正对用户产生价值的,还是业务部分。只要业务系统做的深入做的好,权限系统就算粒度粗点/不好用点/有些权限分配实现不了点,客户都是可以勉为其难就那样儿的。所谓冗余设计,就是花了80分的精力去做实际只有20分的用户会用到的东西。要抓主要矛盾,并在有限条件下尽量解决次要矛盾,这样的系统,就是完美系统啦。
我非常赞同你的观点,我很反感脱离实际的设计。以点概面的构想,真的很没有大局观。为了实现一种功能,而不考虑实际真正的用途。
sxgkwei
sxgkwei

引用来自“cross___”的评论

@sxgkwei 嗯,还真不巧,之前我和我们技术部的老大就为了你说的这个还争论了一番,他的模型比你还多一层概念,你现在说的是权限中引入了 “非”的概念产生的,而我们当时说的是,权限在角色层面的三种状态,“默认使用”(有则可用),“授权使用”(高于默认的使用),“禁止使用”(不允许使用)。
用户能拥有多个角色,而角色则拥有这些不同状态的权限,使用起来就非常复杂,而且还具有冲突性,就例如用户拥有的角色A和角色B,角色A授权使用权限D,角色B禁止使用权限D。那么冲突的时候,程序又如何判断,于是由引入了一层概念。用户的角色策略,比如默认有限策略、禁止使用优先、授权使用优先。来处理这种冲突的关系。
从某个角度上来看这个好像是可行的,但是我个人认为,这种设计有点脱离实际(用户的素质是否能理解这种关系,如果不理解或说不需要用户自定义权限的话,这种设计的存在根本没必要),并且复杂化了使用逻辑。
但是也不能完全的否认这种形式的存在,因为某些业务系统肯定有类似这方面的存在,这就是所谓的脱离了实际业务谈设计都是耍流氓。但是我认可一种原则,我们可以根据业务复杂度和用户的自身素质程度正比例逐级扩充权限的使用维度和逻辑复杂度(并不代表操作界面的复杂)。
我只能说,你老大真是想多了。在“非”与“是”同时存在的情况下,很多普通用户都理解不了,还指望客户理解你们方案里的这一套?而且,权限系统始终只是辅助性系统,真正对用户产生价值的,还是业务部分。只要业务系统做的深入做的好,权限系统就算粒度粗点/不好用点/有些权限分配实现不了点,客户都是可以勉为其难就那样儿的。所谓冗余设计,就是花了80分的精力去做实际只有20分的用户会用到的东西。要抓主要矛盾,并在有限条件下尽量解决次要矛盾,这样的系统,就是完美系统啦。
cross___
cross___
@sxgkwei 嗯,还真不巧,之前我和我们技术部的老大就为了你说的这个还争论了一番,他的模型比你还多一层概念,你现在说的是权限中引入了 “非”的概念产生的,而我们当时说的是,权限在角色层面的三种状态,“默认使用”(有则可用),“授权使用”(高于默认的使用),“禁止使用”(不允许使用)。
用户能拥有多个角色,而角色则拥有这些不同状态的权限,使用起来就非常复杂,而且还具有冲突性,就例如用户拥有的角色A和角色B,角色A授权使用权限D,角色B禁止使用权限D。那么冲突的时候,程序又如何判断,于是由引入了一层概念。用户的角色策略,比如默认有限策略、禁止使用优先、授权使用优先。来处理这种冲突的关系。
从某个角度上来看这个好像是可行的,但是我个人认为,这种设计有点脱离实际(用户的素质是否能理解这种关系,如果不理解或说不需要用户自定义权限的话,这种设计的存在根本没必要),并且复杂化了使用逻辑。
但是也不能完全的否认这种形式的存在,因为某些业务系统肯定有类似这方面的存在,这就是所谓的脱离了实际业务谈设计都是耍流氓。但是我认可一种原则,我们可以根据业务复杂度和用户的自身素质程度正比例逐级扩充权限的使用维度和逻辑复杂度(并不代表操作界面的复杂)。
cross___
cross___

引用来自“哈库纳”的评论

阿里云 RAM 授权模型就可以的 、AWS 以及各种云平台的 访问权限控制都是这一套。 比RBAC要可靠的多,而且 例如 STS 这种短时授权管理 都有的。
RAM是一种更高端的权限玩法了,可以看做RBAC的进阶版。但是如果别人连RBAC都不理解清楚或理解出偏差了,一下子接触RAM的话,一下子很难弄懂其中关系~~
哈库纳
哈库纳

引用来自“哈库纳”的评论

阿里云 RAM 授权模型就可以的 、AWS 以及各种云平台的 访问权限控制都是这一套。 比RBAC要可靠的多,而且 例如 STS 这种短时授权管理 都有的。
https://help.aliyun.com/learn/learningpath/ram.html?spm=a2c4g.11186623.2.1.Fqhc9n
哈库纳
哈库纳
阿里云 RAM 授权模型就可以的 、AWS 以及各种云平台的 访问权限控制都是这一套。 比RBAC要可靠的多,而且 例如 STS 这种短时授权管理 都有的。
JavaScript杂谈

浏览器内的事件队列 众所周知JavaScript是基于单线程运行的,同时又是可以异步执行的,一般来说这种既是单线程又是异步的语言都是基于事件来驱动的,恰好浏览器就给JavaScript提供了这么一个...

掘金官方
2017/12/06
0
0
架构师杂谈

架构师,这个title就和总监之类的title一样,已经彻底被用烂了,但在一个软件产品的生命周期中,架构师是实实在在的一个极度重要的角色,这篇文章就来讲讲我觉得的架构师的画像,到底具备什么...

fastjrun
2016/09/21
54
0
软件设计杂谈

disclaimer: 本文所讲的设计,非UI/UE的设计,单单指软件代码/功能本身在技术上的设计。UI/UE的主题请出门右转找特赞(Tezign)。 在如今这个Lean/Agile横扫一切的年代,设计似乎有了被边缘化...

-鹏
2015/09/21
44
0
软件开发杂谈 001

1. 软件架构设计可以基于数据库的模型设计也可以基于领域模型设计。对于业务系统来说,如果他的核心是数据处理和分析,而且数据量很大可以在架构设计时采用基于数据库建模的方式,对于一些中...

青夜之衫
2017/12/05
0
0
杂谈nginx 301 重定向在非常规破解中的利用

杂谈nginx 301 重定向在非常规破解中的利用 火星信息安全研究院2017-12-281 阅读 Python 在某些特定的情况下,如果软件采用本地加服务器校验的方式进行注册时候。单纯的本地破解可能很快就是...

火星信息安全研究院
2017/12/28
0
0

没有更多内容

加载失败,请刷新页面

加载更多

CentOS7防火墙firewalld操作

firewalld Linux上新用的防火墙软件,跟iptables差不多的工具。 firewall-cmd 是 firewalld 的字符界面管理工具,firewalld是CentOS7的一大特性,最大的好处有两个:支持动态更新,不用重启服...

dingdayu
今天
1
0
关于组件化的最初步

一个工程可能会有多个版本,有国际版、国内版、还有针对各种不同的渠道化的打包版本、这个属于我们日常经常见到的打包差异化版本需求。 而对于工程的开发,比如以前的公司,分成了有三大块业...

DannyCoder
今天
2
0
Spring的Resttemplate发送带header的post请求

private HttpHeaders getJsonHeader() { HttpHeaders headers = new HttpHeaders(); MediaType type = MediaType.parseMediaType("application/json; charset=UTF-8"); ......

qiang123
昨天
3
0
Spring Cloud Gateway 之 Only one connection receive subscriber allowed

都说Spring Cloud Gateway好,我也来试试,可是配置了总是报下面这个错误: java.lang.IllegalStateException: Only one connection receive subscriber allowed. 困扰了我几天的问题,原来...

ThinkGem
昨天
27
0
学习设计模式——观察者模式

1. 认识观察者模式 1. 定义:定义对象之间一种一对多的依赖关系,当一个对象状态发生变化时,依赖该对象的其他对象都会得到通知并进行相应的变化。 2. 组织结构: Subject:目标对象类,会被...

江左煤郎
昨天
4
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部