RBAC 整合数据权限的设计

2021-12-22 16:03:25 +08:00
 fy1206

在项目实际开发中我们不光要控制一个用户能访问哪些资源,还需要控制用户只能访问资源中的某部分数据。 有什么好的想法可以在下方留言。

4082 次点击
所在节点    程序员
19 条回复
billly
2021-12-22 16:22:33 +08:00
这真的是日经话题了,讨论了这多次,没见到过完美的方案
fy1206
2021-12-22 16:25:35 +08:00
@billly 怎么说
lxmfly123
2021-12-22 16:30:53 +08:00
casl
xuanbg
2021-12-22 16:48:29 +08:00
RBAC:臣妾做不到啊!
xuanbg
2021-12-22 16:52:11 +08:00
RBAC 的 R ,既是 role ,也是 resource 。你只要能准确定义 resource 的话,总是有办法实现的。问题就在于你无法通过一个抽象的系统来描述特定的资源啊。
johnli
2021-12-22 17:05:16 +08:00
我们准备在数据权限上用 ABAC
timethinker
2021-12-22 17:30:31 +08:00
数据权限一般直接穿透到持久层了,一般的做法是直接给每张表加额外的字段,辅以各种框架的拦截器修改 SQL 来实现的。

当然可以使用一张独立的表来跟踪所有的数据行,无论如何,都会引入额外的复杂性。想想操作系统是如何确定当前用户拥有某一个文件的读写权限呢?类似的,你也需要一种像文件系统的东西来支撑。

所以如果不是所有的数据都有这种数据权限的需求的话,直接按照最简单的来做,也就是针对这些有需要的地方,做专门的代码处理逻辑,理解需求真正想要的是什么。
yunye
2021-12-22 17:32:06 +08:00
可以参考下 leancloud 的 ACL 吧
ptrees
2021-12-22 17:57:49 +08:00
个人感觉 linux 的目录系统也可以作为参考吧,属主属组都配置好权限也就有了,当然我自己也不会写,只是一点想法...
learningman
2021-12-22 19:46:28 +08:00
ABAC 吧,懒得写可以试试 casbin ,就是慢点
gotounix
2021-12-22 22:03:20 +08:00
慢慢折腾吧!
菜单权限、接口权限、按钮权限、数据过滤、字段权限,用户、角色、部门、岗位,一堆一堆的,没完没了。
最后就会发现,没有完美解决方案。领导 /客户要什么就给他弄。
ericguo
2021-12-22 23:49:23 +08:00
可以看看这个设计: https://github.com/varvet/pundit#scopes
joesonw
2021-12-23 08:54:25 +08:00
类似于 aws 的 iam 咯。ory.sh 系列产品可以做到。其中策略库是 ory/ladon
gmywq0392
2021-12-23 10:16:20 +08:00
Open Policy Agent 支持 partial evaluation, 做到 Enforce Policy in SQL ,在 DAL 层根据 policy 调整查询范围。
swcat
2021-12-23 11:06:46 +08:00
我说下我的设计把, 最开始是最简单的 RBAC, 但是又涉及到菜单权限, 按钮权限 -> RBAC + 元素权限(菜单, 按钮等和 api 绑定), 根据元素, 生成元素树, 前端页面设置权限那里选择元素树, 元素树反向推出 api 权限, 元素树的一部分生成菜单权限, 一部分生成按钮权限, 实现闭环

字段权限: 通过把某个接口返回的字段放到 data_acl 表 里面(我用的反射, 缓存接口返回字段名到表里面), 如果没有配置自己权限的就返回所有的字段名, 如果配置了就返回自己的字段名
cppc
2021-12-23 11:34:02 +08:00
@swcat 楼主说的数据权限是根据当前用户的权限来控制返回数据的行数,不是某个功能能不能用的问题,也不是某个字段是否回显的问题
fy1206
2021-12-23 11:59:07 +08:00
@swcat 这个设计还是在 RBAC 基础层面,没有突破数据权限层面。
我现在有两个种方案当时感觉都不是很完美
第一种:针对数据规则(规则字段,规则表达式,规则值),把数据规则跟资源和用户进行绑定,怎么绑定?在 RBAC 模型中,用户是通过授予不同的角色来进行资源的管理,同理我们可以让角色在授予权限的时候关联上数据规则,这样最终在系统上就体现为不同的用户拥有不同的数据规则。在系统中实现的话 java 种可以使用 aop 来实现,顶一个数据权限的注解,在对应的资源请求方法上加上注解,然后用 aop 抓取到用户对应角色的所有数据规则进行 SQL 拼接,最终在 SQL 层面实现数据过滤。
第二种:在对象的资源请求表中加上数据筛选字段进行埋点,每次访问时需要来权限系统这边获取当前的角色,然后带上筛选条件去查询,这个方法也是 SQL 层面实现。
第一种方法扩展性强,但是增加系统的复杂层度,而且对性能也有影响
第二种方法对各个功能有侵入性,扩展性不强,每加一个服务都要去设计相应的字段,实现比较容易。
7anshuai
2021-12-23 12:17:50 +08:00
https://github.com/onury/accesscontrol web 前端和 node.js 的话,这个库的思路和用法,个人觉得很不错
swcat
2021-12-23 13:28:12 +08:00
@cppc @fy1206 控制返回数据的行数, 这个是在需要的地方抽象 query, 实现各个层级的 query, 然后在数据库把对应的 query 和角色 /部门 /租户 绑定在一起, 用那个 query 来查传入的参数,

还有一点忘了说, 接口的权限是在 openresty 做的, 接口的数据权限是在应用做的

权限这个做细太难了, 需求也各不相同, 我也只做了 2 点数据权限
1. 数据权限, 不同的角色, 查询需要附加的参数不一样, 比如超级管理员和普通部门, 看到的数据就不一样, 就是上面的 query, 不同的层级的 query, 然后数据库中存, 角色或者用户用到的 query 的关系, 这点忘了写, 刚才, 具化就是当前租户只能看到当前租户的数据, 老板能看到整个的公司的数据, 各个部门只能看到自己部门的数据, 自己只能看到自己的数据, 当然这个可以配置
2. 数据字段的权限, 就如刚才说的, 把不同接口返回的字段列出来, 在数据库里面出不同角色要返回的字段名, 比如普通的人是看不到成本价的, 但是财务能看到并且设置成本价

关于性能问题, 需求都没实现, 谈什么性能问题, 性能可以再优化的, 除非性能实在太差了

其他的实现不不敢乱评判, 符合需求, 扩展性稍微强一点, 鬼知道还会提什么幺蛾子权限需求

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/823787

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX