基于 RBAC 的 Web 应用权限管理的思考

写在最前

  • 仅针对单一应用, 如果需要多应用的统一权限管理, 可能还需要加上「应用」这个层级的范围
  • 以类似「白名单」的形式来计算权限, 保持的是一种累加的方式, 没有考虑权限互斥的情况, 也没有加入「黑名单」的设置
  • 如果不需要特别针对某一个用户授权, 可以在角色绑定时, 只使用组id
  • 通过设置一定的规则, 通过初始化的方式, 可以实现应用权限的自省, 如下,
    • 资源类型表: {'id': 1, 'name': '*', 'desc': 'ALL'}
    • 资源操作表: {'id': 1, 'name': '*', 'desc': 'ALL'}
    • 权限表: {'id': 1, 'res_kind_id': 1, 'res_verb_id': 1}
    • 角色表: {'id': 1, 'name': 'Administrator', 'desc': 'Administrator'}
    • 角色权限表: {'id': 1, 'role_id': 1, 'perm_id': 1}
    • 用户表: {'id': 1, 'name': 'System'}
    • 用户组表: {'id': 1, 'name': 'Administrator'}
    • 组用户关联表: {'id': 1, 'group_id': 1, 'user_id': 1}
    • 数据权限表: {'id': 1, 'desc': 'Administrator', 'res_kind': 1, 'res_attr': 1, 'operator': '', 'pattern': '', 'dup_op': '', 'priority': 1}
    • 角色绑定表: {'id': 1, 'role_id': 1, 'kind': 'group', 'kind_id: 1', 'scope_id': 1}

数据库设计

  • 所有的表默认包含 id(自增主键)
  • 对于关联表, 外键的是通过业务逻辑来实现, 并非是物理上的外键关联(在建表时声明 ForeignKey)


    authorization.png

资源类型 (ResourceKind)

  • 定义当前系统存在的资源类型, 例如, 菜单/ 按钮/ 用户/ 角色 等

资源操作 (ResourceVerb)

  • 定义可以对资源进行的操作, 例如, 查看/ 增加/ 删除/ 更新/ 授权 等

资源类型元信息 (ResourceMeta)

  • 定义了某一资源类型所包含的属性信息, 包括类型/ 约束 等

具体的资源表 (ConcreteResource)

  • 定义具体的资源表, 表名与 ResourceKind 相关, 字段信息来自 ResourceMeta

对于具体的、已知需求的应用来说, 以上的信息都是已知的, 类似于枚举, 可以通过配置文件的形式来替代

权限表 (Permission)

  • 资源类型id + 资源操作id

角色表 (Role)

  • 是一组权限的集合, 因此, 需要与权限进行绑定

角色权限表 (RolePermission)

  • 角色id + 权限id, 定义角色可以操作哪些资源, 将权限与角色绑定在一起
  • 权限与角色绑定在一起之后, 才算是完成一个角色完整的定义

数据权限 (DataScope)

  • 定义数据的操作规则, 即在通过操作资源类型认证的情况下, 对于具体的资源是否可以应用此操作, 例如, 用户A查看非管后台类型的菜单, 这里的「非后台类型」就是数据权限, 即 菜单会有一个属性 kind(描述菜单类型)
  • 所包含的字段
    • desc: 范围描述
    • res_kind: 资源类型id
    • res_attr: 资源类型的具体属性
    • operator: 操作符, 例如, =, != 等, 这里可以根据实际需求来设置
    • pattern: 需要匹配的信息, 例如, 'not_admin'
    • dup_op: 当同一个属性有多种不同的数据权限时, 如何连接此条权限, 例如, and, or 等
    • priority: 优先级, 当用户拥有 对同一个资源的不同操作时, 会按照优先级的大小, 通过 dup_op 进行条件拼接
  • 数据权限在使用时的形式, <res_kind>.<res_attr> <:operator> <pattern>, 例如, menu.kind = 'not_admin'
  • 特别的,
    • 针对全部资源类型, 可以设定, res_kind = '*'
    • 类推, 针对整个资源类型, 可以设定 res_attr = '*'

用户表 (User)

  • 保存用户信息

用户组 (Group)

  • 组信息

组用户关联表 (GroupUser)

  • 组id + 用户id, 将用户与组绑定在一起

角色绑定表 (RoleBind)

  • 角色id + 组id/用户id + 数据权限id, 表明「当前(组内)用户」可以「在一定范围内」对资源「进行角色拥有的全部操作」
  • 在绑定时, 需要注意数据权限的优先级问题

极简页面(部分)

simple_ui.png

写在最后

  • 如有错误, 请各位多多包含, 期待你的指教.
  • 年前会基于此实现权限模块, 代码随后更新到 Github

参考资料

  • Microsoft Azure 的权限设计
  • Kubernetes 的权限设计
  • RBAC 说明
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,723评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,003评论 3 391
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,512评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,825评论 1 290
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,874评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,841评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,812评论 3 416
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,582评论 0 271
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,033评论 1 308
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,309评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,450评论 1 345
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,158评论 5 341
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,789评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,409评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,609评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,440评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,357评论 2 352

推荐阅读更多精彩内容