权限控制模型

最原始的权限模型(Role Based Access Control)

用户-角色-权限,三者分别都是多对多的关系,所以抽出来两张表,关系结构为:

  • 用户表
  • 用户-角色对应表
  • 角色表
  • 角色-权限对应表
  • 权限表
    image

哪里不好

这个模型能够适应基本的权限控制情况,但是组织结构一旦复杂,这个就不够用了。

情况:一些权限控制不应该到业务层去实现,也不可能一直去添加角色,同样是项目经理,对应的是不同的项目,对于资源的划分就变的很麻烦了,每个资源都要去划分。而且按钮和菜单应该怎么去做。等用户量大的时候,一个一个的赋予角色就麻烦了,而且这个角色也会有很多个,不利于管理和维护,角色如何去分层次。

如何做到字段级别的权限控制?

改进版本1

加入组织表。

这个版本主要是解决组织之间的角色关系,以及方便对整个用户组里的用户赋权。

用户组织也是有权限的,把用户分组,因为一些权限是直接根据组来的,组织也有角色,也对应着权限,这样直接赋权限的时候就会方便点,加入这个组织就可以了。

个人的权限 = 自己拥有的角色的权限 + 组织角色拥有的权限

image

疑问

  • 组织也分上下级的关系,因为是树形结构,那么是不是涉及到权限的继承?
  • 不对,组织到底是个怎么样的概念,是协同上的那种树形结构,

应用场景

  • 用户组织,如技术研发部、平台研发部,这些都是平行的组织,对应着自己组织的权限,可是这样和直接赋给这个人,xx成员的角色有什么区别?
  • 区别在于,用户组织,其实是一个很多角色的组合,里面包含着很多角色和权限,避免去一次一次的重复给组内的需要的角色
  • 但是假如这种情况,一个组内,也是有不同的等级的,比如项目组长、普通员工和实习生,这三者的权限又是不一样的。这个好像又回到之前那个模型的问题了
  • 组织只能适用于一些宽泛的场景,比如大家都是研发中心的员工,这个自然是和客服中心区分开来了;
  • 这个组织存在的意义是什么?就是一个大的角色而已,不对不是一个角色,这个组织可以有多个角色
  • 角色挂在组织下,组织就是角色组,角色组也可以不参与角色分配,只是为了看起来能够更加清晰??对,可以这样做

角色和用户组有什么区别

  • 角色是一组权限的集合
  • 用户组是一组角色的集合?也不一定,也可以作为一个大的角色赋给全部人,方便统一处理,用户组就是一组用户的集合,这一群用户是一个组织,给组织赋权就是给组织内的全部用户赋权
  • 角色组的出现,一是为了让组织结构看起来更加清晰,二是方便统一的对某个组织进行权限的控制,不对,角色组和用户组是两个概念!!
  • 用户组在一些时候,其实就是一个大的角色

改进版本2

改进权限表,把菜单、页面元素等东西列出来。

image

要解决的问题是,资源和权限操作并不好区分。

要控制的资源,主要有:菜单,页面上的各种元素如按钮,文件,以及还有一个就是url访问的页面需要进行控制

  • 不同用户拥有的菜单不同
  • 可以看到的页面元素也不同
  • 可以访问的文件也不同
  • 可以直接访问的页面也不同,一些页面需要有特定的权限才可以访问

前三者基本上就一个查的权限,最后一个涉及的较多,可以用url来进行区分和控制

权限表给一个类型,来判断这个权限id对应的是哪个类型的资源

这样是不是就解决了菜单控制的问题?

这样设计会更加便于拓展,有什么新的资源或者其他的东西需要进行权限控制,只要再添加一张关联表和资源表就行

页面元素怎么放里面?给编码,每个元素都有一个编码,使用一定的命名形式

查出来的权限有哪些?其实就角色和权限id,全部的id都放在authorizationInfo中,info是个集合,渲染页面的时候会去遍历这个集合,如果有就渲染出来,但是页面元素这种资源不能太多,某些关键的按钮和表单,用jsp的hasPermission标签的形式就可以做到

完整数据库设计:
image

角色组

角色组不给权限,只是作为一个分上下级的东西,或者其他的结构?这个不参与权限的分配,所以这个才是最重要的,用户组只是为了方便操作,这个才是直观的部门分层

使用场景:

总结

添加了一个用户组的概念

用户组就是一组用户的集合,当给用户组赋予角色的时候,整个组内的成员都会获得这个角色以及它的权限。这样就方便了加减角色的操作,当用户量足够大的时候,就不用去挨个赋权。

好像很鸡肋,又回到了一开始,用户组就是一个大角色的概念,没什么存在的意义。除了一次性的给多个用户赋角色。

所以用户的权限 = 用户组的权限 + 用户自身有的角色权限

把权限表细化

权限分很多种,操作也是一种权限,不仅仅是那些静态的资源才有权限。所以在权限表中加入一个type字段,表明这个是什么类型的权限,是menu的还是file的,或者是control的,然后每个对应的type都单独拿出去作为一张表,这样就可以把操作和静态资源看做是一个东西来进行管理。

加入角色组的概念

角色组是不参与权限的分配的,只是拿来进行组织结构的划分,划分的结构可以是树形结构。

声明

  • 一个用户只能属于一个用户组
  • 用户组有继承机制,但是只能有一个父用户组
  • 一个用户组可以有多个角色和权限
  • 权限是不能直接赋给用户的,需要去创建一个角色,把权限赋给角色,然后角色赋给用户,这样的方式去进行授权操作
  • 用户的权限信息,包括permission和role这两种
  • (应该加入一个权限互斥组)!不然一些情况没办法实现

使用场景模拟

场景一

  • 大家都是研发中心的员工,和客服中心的员工的基础权限是不一样的,比如研发中心的可以访问需求网站并且下载文档,客服中心的可以访问客户沟通网站

答:划分好权限后,把权限赋给角色,分别是需求网站访问者、文档下载者和客户沟通网站访问者。研发中心和客服中心就是两个不同的用户组,这三个角色赋给用户组后,组内的全部用户就都有了这个角色,都有了对应的权限。

场景二

  • 研发中心的全部用户对这个页面有读的权限,里面的主管用户对这个页面有读和写的权限

答:直接在权限type为功能操作那边进行拦截,写是一个角色A,读是一个角色B,对应着相应的权限,角色A赋给研发中心用户组,角色B赋给主管,这样就完成了这个场景

场景三

  • 用户都有访问这个页面的权限,但是不同的用户看到的菜单和页面元素不同

答:首先菜单和页面元素全部被划分成资源,放到权限表外联的表中,在用户登录进行授权的时候,这些对应的权限id就全部被写入到用户的权限信息中,渲染页面的时候就会去遍历用户的权限信息,有哪些就显示哪些。

场景四

  • 总经理临时需要加一个权限

答:那就去新建一个角色,把这个权限赋给这个角色,然后把角色添加给总经理用户,这样就完成了授权。

场景五

  • 用户个人角色的权限和用户组权限冲突,比如实习生也算是挂在研发中心下面的,但是权限和正式员工不同,协同上一些信息是没有访问权限的,这个如何处理

答:这个模型不应该出现权限冲突的情况,有就是有,没有就是没有。如果用户组有,个人角色没有,那就是有;如果用户组没有,个人角色有,那还是有。如果个人不应该有组织的某个角色,那就直接不能加入这个组织,因为组织的基础角色和他不符。所以用户组的权限需要是最基础的通用的权限。

需要加入一个约束机制,冲突的角色应该只能添加一个。

场景六

  • 用户组如何去分级和继承权限

答:整个研发中心有研发中心的权限A,客服中心有权限B,研发中心下面的技术研发部的权限为a,平台研发部的权限为b,客服中心下面的维护中心的权限为c,那么技术研发部的用户的权限 = A + a + 自己本身;同理。

场景七

  • 每个人只能查看自己的工资信息,这个应该如何实现?

答:应该在业务层实现,查工资这个权限应该在小组中就定义好【查工资者】这一个角色,然后在执行查工资的操作的时候,传入id,返回个人的工资信息并显示。

场景八

  • 要取消组内的某个人的权限,这个权限来自于用户组,如何操作

答:直接把这个人移出组?感觉不对,难道要为了他去特地创建一个角色,可是只能这么做,把这个角色从他身上取掉,退出这个用户组,然后给他一个阉割过的角色。

场景九

  • 父用户组有的功能,但是下面的子用户组需要禁止这个权限,如何操作?

答:参考场景五。分组的时候就需要考虑到这个问题,那样的话这个模型是不是就有问题了。

网上的回答是:1、加入互斥角色;2、有一个基数约束(领导的数量是有限的);3、有先决条件角色(你想当技术专家,你首先必须是高级工程师,需要获得低一级的角色权限);4、运行时互斥。

好像已经背离了基于资源的权限控制,现在就是基于角色的,所以问题很大。但是角色其实就是资源权限的一个封装啊,就是一个权限的集合,只是为了更加符合人类思考的常理,不可能去后面拖着一堆权限,最后组装成permission的时候,其实也是根据角色去查询具体的权限的啊,这个是系统框架层次需要去思考的问题,现在只是一个数据库设计而已,依旧可以通过user-role-permission三表来查询到user的permission。

现在的问题在于如何去取消权限

问石磊

模型更改,加入部门的概念,不能用用户组来模拟部门,部门不应该有权限,只是一个逻辑上的分区

新模型要点

  • 用户组可以继承,继承的是父类的角色
  • 用户组和角色之间的关系是:用户组只能有一个角色,角色可以赋给多个用户组
  • 用户可以单独赋予权限
  • 一个用户可以加入多个用户组
  • 取消权限是一个灾难,一旦涉及到取消,就要把用户移出当前用户组,其实可以解决啊!!要做的操作比较少的
  • 是否存在权限冲突的情况(不是很想的到场景)
  • 关键在于用户组的分类,之前想的是把用户组作为有相同角色的全部用户的集合,想一起方便的赋权,但是这样就违背了组织本来的概念。现在把用户组通过部门来进行管理,部门不涉及权限。
  • 但是如果用户组下面还有用户组的话,是不是就会有问题。用户组的表应该怎么设计,部门的表又应该怎么设计?是不是应该去取消用户组的继承,部门的东西全部在部门的逻辑分组中完成,一个用户组只能属于一个部门,用户组下面只有用户。但是这样设计的话,就没有一级一级继承下来的意思了,或者说本来就不应该有这个想法,继承不应该是在这边继承,换个角度去思考,因为一个用户可以加入多个用户组,所以用户可以继承到多个角色,虽然没有一级级的角色继承,你是研发中心的员工,所以有研发中心的员工的基础权限,你是研发中心的技术研发部的员工,所以有技术研发部的权限 + 研发中心的基础权限,这样就是一种继承。如果换成现在这种模型,就是部门下面会有部门和用户组,你又是研发中心的普通员工,也是技术研发部的普通员工,所以你有这两个用户组的角色,所以用户会和用户组有一个多对多的对应表
  • 首先,没有人是可以游离于组织之外的,每个人都至少属于一个组织,实习生属于实习生的组织 + 实习生所在的部门的组织,用户组的概念要更正,用户组首先是一个用户的集合,其次他本身拥有一个角色,有等级的角色,如,基础角色A,中级角色B,高级角色C,终极角色D,首先全部人都有基础角色A,正式员工会加一个B角色,高级员工再加个C,以此类推。
  • 要明确,这个是数据库设计,不是框架层次的设计,一些业务上的东西应该交给框架或者是业务代码去实现。
  • 为什么不能给用户组赋予多个角色?没必要

常用场景模拟

  • 实习生转正了

答:给他加入到中级用户组即可。

  • 换了一个组织,从技术研发部到了公共支持部

答:直接把用户的用户组更改一下,放到另外一个部门下的用户组里就行

-