V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
igeeky
V2EX  ›  程序员

诚心请教: 如何优雅的实现对数据的权限控制?

  •  
  •   igeeky · 2020-09-12 11:28:19 +08:00 · 7062 次点击
    这是一个创建于 1532 天前的主题,其中的信息可能已经有所发展或是发生改变。

    我实现了一个RBAC的权限系统. 它能很好的对 api 接口的权限进行控制. 具体功能及实现请参考这里: https://github.com/iGeeky/wolf/blob/master/README-CN.md

    我现在想添加数据的权限控制, 如下下面一个例子:

    • 用户 A只能查询及审核属于自己业务范围的视频数据(比如通过 tag 区分)

    目前的 RBAC 只能实现, 如果给了用户 A查询及审核视频的权限, 也就对所有视频都有了相应权限.

    我考察了一下, 感觉使用ABAC实现对数据的访问控制, 可能是一个比较常用的方法, 比如上面的例子中, 可以定义这样的策略:

    测试数据:

    用户: {用户名: 用户 A, 角色: 短视频审核员, 部门: 运营 1 组, ...}
    视频: {标题: 短视频, TAG: 短视频, ...}
    

    策略(这里不是严格按照 ABAC 或 RBAC 的架构及概念来描述的):

    用户: 用户.角色 = 短视频审核员
    资源: 视频
    动作: 读取,审核
    匹配策略: 视频.TAG = 短视频
    

    如果在业务系统内实现上面的逻辑, 应该是比较好实现这样一套控制策略的. wolf 的架构是与业务系统完全解耦的, 它是在 http 代理层实现的. 因此在目前 wolf 中实现却有一些难题:

    • 视频信息并不在 wolf 系统中,所以也拿不到视频的 TAG 信息. Wolf 也不希望读取业务系统数据.
    • 视频的读取及审核操作是在业务系统中实现的, Wolf 并不能直接控制.

    对于以上问题, 大家有什么好的解决方案没?

    33 条回复    2020-09-13 13:08:07 +08:00
    workwonder
        1
    workwonder  
       2020-09-12 11:46:01 +08:00 via Android
    ABAC - 基于属性的权限控制,说白了就是在应用内部适当的地方做权限判别。
    个人觉得在代理层(网关)做权限控制很难保证灵活性。
    igeeky
        2
    igeeky  
    OP
       2020-09-12 11:48:32 +08:00
    @workwonder 嗯,难点就是在这儿. 我想实现一个通用的权限系统. 如果与应用进行了过多的耦合, 就缺少通用性.
    workwonder
        3
    workwonder  
       2020-09-12 11:48:33 +08:00 via Android
    37Y37
        4
    37Y37  
       2020-09-12 11:49:08 +08:00
    这个就是对象权限控制,给对象赋权,django 的 guradian 实现的就挺好,可以看看
    workwonder
        5
    workwonder  
       2020-09-12 11:53:09 +08:00 via Android
    @37Y37 只能查询指定分类的视频,看起来是“集合”权限,想知道 guradian 能不能帮忙?
    securityCoding
        6
    securityCoding  
       2020-09-12 12:03:31 +08:00
    没有什么好的办法,只能传入标识在业务内部来做
    workwonder
        7
    workwonder  
       2020-09-12 12:08:14 +08:00 via Android
    @securityCoding 我也觉得如果权限控制上升到“策略”级别,那么只有走到应用内部才方便收集完整的上下文数据。
    dk7952638
        8
    dk7952638  
       2020-09-12 13:01:07 +08:00   ❤️ 5
    数据权限我还真的做过很多的尝试,说几点谈不上经验的经验吧
    1,数据权限控制设计不宜过于灵活,过于灵活的数据权限只会变成运维和性能的负担,不如直接去业务里实现
    2,通过大量的实践,基于组织架构的数据权限控制是最合理与通用的,也是最贴合实际场景的
    3,数据的过滤最好直接基于 SQL 进行,这样可以避免持久层框架的技术绑定
    最后我们目前使用的是基于 Druid 框架 AST 解析的动态数据过滤,通过读取用户的数据权限,自动把数据权限相关的条件注入到 SQL 中
    igeeky
        9
    igeeky  
    OP
       2020-09-12 13:04:51 +08:00
    @securityCoding 嗯, 这是一种可行的办法. 像上面的例子中, 可以把上面的匹配策略条目,通过请求头传到业务后端: X-Policy: 视频.TAG = 短视频. 业务端需要根据该策略表达式,进行查询及更新的过滤.
    retanoj
        10
    retanoj  
       2020-09-12 13:05:01 +08:00 via iPhone
    我瞎说一个:可以 aop 来做么?
    Hackerchai
        11
    Hackerchai  
       2020-09-12 13:08:17 +08:00 via Android   ❤️ 1
    可以试试 Casbin,各种语言都有支持,可以看一下[官网]( https://casbin.org)
    igeeky
        12
    igeeky  
    OP
       2020-09-12 13:09:11 +08:00
    @dk7952638 嗯, 感谢分享. 基于 SQL 是什么意思? 是在应用层配置配置成 SQL 片段吗? 比如上面的示例配置成: video.tag = 'short_video' ?
    Druid 可能在我这儿用不上. wolf 是在网关层面实现的. 与语言跟框架无关.
    Hackerchai
        13
    Hackerchai  
       2020-09-12 13:09:29 +08:00 via Android
    [Rust][权限控制][Casbin] Rust 下成熟好用的权限控制库
    https://www.v2ex.com/t/703209
    可以参考我另一篇帖子的介绍
    Hackerchai
        14
    Hackerchai  
       2020-09-12 13:13:50 +08:00 via Android
    Casbin 支持 ACL, RBAC, ABAC 等常用的访问控制模型,同时也支持分组
    igeeky
        15
    igeeky  
    OP
       2020-09-12 13:17:15 +08:00
    @Hackerchai 嗯, 这个项目不错, 我云学习一下.
    dk7952638
        16
    dk7952638  
       2020-09-12 13:19:00 +08:00
    如果是网关的和可能确实和我说的不是一个思路的,但是我觉得网关做数据权限过滤有点不太合适,比如说有 100 个视频,属于用户 A 的有 10 个,通过你的网关进行过滤,每次请求取十个视频,如果正巧前十个都是不属于 A 的,那么可能你最后只会返回一个空数据集,这明显和用户查询属于自己的前 10 个视频的期望不符
    Firewine
        17
    Firewine  
       2020-09-12 13:21:01 +08:00 via Android
    api 控制权限?
    Hackerchai
        18
    Hackerchai  
       2020-09-12 13:22:16 +08:00 via Android
    @igeeky 如果遇到问题可以去 q qun/gitter/forum,社区开发者可以提供技术支持
    igeeky
        19
    igeeky  
    OP
       2020-09-12 13:29:35 +08:00
    @dk7952638 是存在这个问题,而且返回的数据还不一定包含策略里面的所有属性,那么做策略判断也是个难题.
    igeeky
        20
    igeeky  
    OP
       2020-09-12 13:30:35 +08:00
    @Firewine 目前实现了 API 的权限控制, 希望实现 API 里面的数据的权限控制.
    37Y37
        21
    37Y37  
       2020-09-12 13:58:06 +08:00
    @workwonder guardian 的权限控制很细,能到 object 的粒度,也就是说你能给数据库里的每一条数据都单独赋权,这里有篇介绍文章,看看 https://blog.ops-coffee.cn/s/mhmww0p2lhvzofrsfa6s3a
    gaius
        22
    gaius  
       2020-09-12 17:34:11 +08:00 via Android
    权限系统只做通用的数据范围,架构 /部门这些,与角色组合。 不然我那么多业务系统,都要给你定制 tag/数据集吗。
    KuroNekoFan
        23
    KuroNekoFan  
       2020-09-12 17:42:36 +08:00
    没有实践过,感觉要做细会挺 dirty 的
    igeeky
        24
    igeeky  
    OP
       2020-09-12 19:02:14 +08:00
    @gaius tag 只是举个例子, 它可以是任何字段.
    gmywq0392
        25
    gmywq0392  
       2020-09-12 19:36:42 +08:00
    通过 XACML 实现 ABAC 呢
    cnxiaowen
        26
    cnxiaowen  
       2020-09-12 21:41:17 +08:00
    先用数据表落地用户的数据范围,例如公司、部门、地区、代表处等;然后才能在接口侧校验用户的权限(不是接口权限)
    inwar
        27
    inwar  
       2020-09-12 21:43:31 +08:00 via Android
    权限系统只能做个粗粒度,具体还要靠业务
    jones2000
        28
    jones2000  
       2020-09-12 21:54:58 +08:00
    这种具体业务具体分析了, 通用的不好做, 除非你已经有上千个应用场景再使用了, 否在靠自己想出来的应用场景是没有用的。实际情况很复杂,特别是涉及到数据库,不同的 DBA 设计的库都是不一样的。
    igeeky
        29
    igeeky  
    OP
       2020-09-12 22:22:09 +08:00
    @jones2000 嗯, 确实要做好很难.
    levelworm
        30
    levelworm  
       2020-09-13 02:18:48 +08:00 via Android
    可以在数据仓库层次做么
    lihongming
        31
    lihongming  
       2020-09-13 03:05:29 +08:00 via iPhone
    感觉楼主是想做微服务架构中的 API Gateway 吧?

    如果是的话,可以参考一下 AWS,AWS 的各项服务自身只做特别简单的权限控制,复杂控制是靠 Lambda 等其它服务实现的。服务收到请求后先把 Event 发给 Lambda,由 Lambda 返回 true 或者 false,然后再继续,这样就解偶了。
    xuanbg
        32
    xuanbg  
       2020-09-13 09:56:39 +08:00
    @dk7952638 #8 我多年的实践得到的结论也是如此。不过针对具体的业务如果基于组织架构的数据权限控制不能满足需求的话,可单独进行基于用户组的权限设置和控制。
    igeeky
        33
    igeeky  
    OP
       2020-09-13 13:08:07 +08:00
    @lihongming 倒不是做 API Gateway,只做其中的一块: 后台用户的认证及权限管理.
    感谢你的建议, 我会了解一下 AWS 的权限实现.
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   3470 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 31ms · UTC 04:35 · PVG 12:35 · LAX 20:35 · JFK 23:35
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.