美文网首页软件开发
如何建设一个权限系统

如何建设一个权限系统

作者: 骆宏 | 来源:发表于2018-08-15 21:15 被阅读850次

1.权限系统是什么

权限系统就是系统的安保系统,保障系统的功能谁能使用,谁可以操作哪些数据

2.权限系统的组成

  • 功能权限

决定了用户能够使用哪些功能

  • 行数据权限

决定了用户能够使用哪些行数据

  • 列数据权限

决定列用户能够查操作哪些列的数据

3.功能权限系统的实现方式

  • tomcat的内置权限
  • shiro
  • spring security
  • 自定义的权限系统

3.1.功能权限的粒度大小

  • 粗粒度,只控制菜单的展示
  • 细粒度,控制web系统,所有可操作的按钮的展示,同时后端还应该能够对url进行拦截

3.2.如何实现细粒度的功能权限控制

  • 每个功能,使用一个namespace表示,比如user.add,user.update,user.delete
  • 用户登录时,获取该用户所有的namespace
  • 渲染界面时,根据namespace的范围,来决定是否显示该功能
  • 后端拦截的实现和前端基本一致,每个功能namespace绑定后端对应的uri
  • 后端session存储该用户所有的uri
  • 请求时,filter过滤该uri,如果具备访问权限,通过请求

3.3.RBAC(Role Base Acess Control)模型的介绍

权限模型

在授权时,把权限都集中收于给Role,然后将Role授予User,达到提高效率的一个方式,但是本质还是把权限授予给了具体的用户。

3.4.基于RBAC的衍生模型

RBAC衍生模型

衍生了用户组的概念

3.5.RBAC等模型的本质

无论模型怎么变化,但是最终的权限落地,都是将权限授予用户。在方案选型时,要关注业务的复杂度与哪种模型的匹配度较为吻合,切勿好高骛远,过度选型。

4.行数据权限

数据权限的实现,目前业界并无通用的解决方案,所以这里面主要是介绍一种模型,大家可以借助模型,去发现系统的数据权限模型

4.1识别权限实体

在做数据权限时,第一步就是要识别出权限实体。下面举几个例子

  • crm系统,权限实体是客户
  • 订单管理系统,权限实体是订单
  • 库存管理系统,权限实体是货品

4.2.识别系统要做到哪种级别权限控制

  • 只读、只写、读写
  • 是否有部门领导
  • 是否需要部门传递关系
    比如在上面的图片中,假设员工骆宏属于A部门,那么员工A是否能够看到(B,C,D,E,F,G,H,G,K),如果可以,就代表具备传递性

4.3.数据存储的实现方式

  • 将权限数据,权限实体实体数据独立出来存储
  • 将权限数据寄存与权限实体中
    下面分别举个列子
    假设有下面的场景,订单1000001,员工A,员工B,其中存储订单的数据叫做lh_order

方案1: [1000001,A]的数据需要存储在一个数据权限表中,我们叫他lh_auth_data,那么就存储一条[1000001,A]
方案2:直接把数据存储在lh_order即可,也就是jt_order中有一条积累[1000001,A]
这两个方案都可以,但是查询的性能会有却别

4.3.1.方案优缺点对比

方案1由于多了一个表,在查询时,可能会导致性能下降,但是却留了一个很好的扩展点,比如1000001同时支持B管理,只需要在lh_auth_data插入[1000001,B]
方案2查询性能较好,但是却扩展不易,假设需要支持B,那么将处理起来非常棘手

4.4.数据的sql查询模型

假设权限实体是:account、product_group、country

select xxx from xx_table where account in (xxx) and product_group in (xxx) and country in (xxx)

4.5.查询性能的问题

在4.4的查询模型中,我们发现使用的是in查询,我们都知道,mysql的in是有效率问题的,当数据规模来到kw级别时,上面的模型就会出现性能的极速下降。
为了突破该性能限制,我们借助tree,以及mysql的前置like查询


20180408123706965.png
A: 10
B: 10001
C: 10002
D: 10003
E: 10001001
F: 10001002
...

假设我们能够将权限实体,进一步的用tree来组织,然后将权限实体的in转换为tree key like '10001%'的模型,我们可以发现,即利用上了mysql的索引,又解决了in的效率问题。

4.5.1.小心tree的key陷阱

在上面,我们使用tree key来处理,但是我们注意到,tree key是有数量限制的,比如A的直接子节点,key范围是:[10001,99999],假设超过了该tree key时,需要考虑怎么进行数据保护。

5.列数据权限

5.1数据

我们先看一个简单的列子,用户管理,api返回的数据如下

[
    {
        "name": "骆宏",
        "age": 27,
        "tel": "15013336**4",
        "school": "广东海洋大学",
        "job": "高级开发工程师"
    },
    {
        "name": "骆宏",
        "age": 27,
        "tel": "15013336**4",
        "school": "广东海洋大学",
        "job": "高级开发工程师"
    }
]

5.2.前端界面的效果

对A用户,无权限控制的现实效果

名字 年龄 电话 学校 工作
骆宏 26 1380013800 广东海洋大学 高级java开发工程师

对B用户,age、tel无权限查看

名字 年龄 电话 学校 工作
骆宏 * * 广东海洋大学 高级java开发工程师

编辑界面同理,直接变成disabled即可

5.2.设计实现

实现主要有如下几个步骤

5.2.1.进行数据namespace

比如下面数据

{
    "name": "骆宏",
    "age": 27,
    "tel": "15013336**4",
    "school": "广东海洋大学",
    "job": "高级开发工程师"
}

借用功能权限的设计,给需要做列权限控制的数据,进行数据namespace,比如用户管理的namespace为user.module,可具备管理的key有name,age,tel,school,job

5.2.1.对数据进行授权

将用户管理(user.module)的name,age,tel,school,job访问权限授予角色A

5.2.1.获取权限上下文

将系统的所有权限,使用权限上下文抽象
上下文数据结构类似下面

{
    "name": "角色A",
    "用户列表": [1,2,3,4],
    "功能权限列表":["user.add","user.delete"],
    "行权限列表":["部门key1","部门key2","部门key3"],
    "列权限列表":[{    
            "name": "用户管理",
            "columns": "可以访问的列"
    }]          
}

5.2.1.后端过滤

在访问时,根据用户id,以及权限上下文,将无权限访问的key,设置为*

6.面对权限系统的变化

唯一不变的,只有变化。在建设系统时,有时候一开始并未能很直接的catch住核心业务,或者是核心业务本身也是变化的。所以在设计权限时,应该做到

  • mvp原则,也就是最小可用原则
  • 预留变化,比如上面提到的存储方案,是将权限数据剥离权限实体呢,还是与权限实体共存
  • 保持权限的简单,不要过度预测,不要过度设计,比如RBAC模型的决策时,是否一上来就选择RBAC的扩展模型,还是先使用最简单的RBAC模型

6.权限代码的抽象

  • 抽象出权限上下文
  • 需要权限支持的模块,集成时统一调用权限上下文的api,切忌将权限模块的代
    码污染了其他模块
    DataAuthContext dataAuthContent = dataAuthContextService.getByUserId(userId);

7.写在最后

没有最完美的设计,只有最适合的设计。权限模型在建设系统时,是非常关键的一步,做好了,后面的人处理权限时,非常简单。如果做的不好,那么权限的代码就会遍布系统,遍布N个模块,重构过N个权限系统的我,苦不堪言...

谢谢大家看到最后,Thank you for you reading
参考链接:功能权限的设计
数据权限的设计

相关文章

  • 如何建设一个权限系统

    1.权限系统是什么 权限系统就是系统的安保系统,保障系统的功能谁能使用,谁可以操作哪些数据 2.权限系统的组成 功...

  • 缓存知识

    权限系统是管理类系统中必不可少的一个模块,一个好的缓存设计更是权限系统的重中之重,今天来聊下如何更好设计权限系统的...

  • 后台系统权限设计总结

    后台系统权限设计总结做B端后台,一个老生常谈的话题就是权限控制,如何做权限控制,初步整理一下。用户场景后台系统常常...

  • day22-权限体系补充和用户管理的知识

    column -t 对齐 补充、权限如何让系统安全 文件名存放在文件所在目录的block ※一、权限如何让系统安全...

  • 设计一个权限系统

    对于任何一个成熟的系统而言,如何设计权限体系,是我们在项目设计之初就应该考虑的。在笔者看来,一个完善的权限系统可以...

  • Android基础(30)动态权限、安全

    1)动态权限适配方案,权限组的概念 2)权限管理系统(底层的权限是如何进行 grant 的)?http://www...

  • #03: 2017 Apr

    如何设计网站权限系统? Solving problems with proc Caveats of select/...

  • Oracle 用户相关操作

    oracle数据库的权限系统分为系统权限与对象权限。系统权限( database system privilege...

  • 权限管理

    1:权限的分类 什么是权限? ORACLE的权限由系统权限、对象权限组成。 系统权限:是指对数据库系统及数...

  • Oraoracle创建用户、角色、授权、建表

    (转载) oracle数据库的权限系统分为系统权限与对象权限。系统权限( database system priv...

网友评论

  • Zero_杀:感谢分享
    骆宏:这个更多是方法论,代码细节,大家可以根据业务场景,进行思考

本文标题:如何建设一个权限系统

本文链接:https://www.haomeiwen.com/subject/arcgbftx.html