多租户 SaaS 产品权限系统设计

多租户 SaaS 产品需要配套功能灵活和强大的权限系统,才能满足其租户灵活自定义用户权限的需求。本文通过分层抽象用户、产品和开发三方各自对权限系统的不同理解来分离关注点、解耦实现,既满足了各方需求,又保证了权限系统的稳定性。

多租户 SaaS 产品权限系统设计

系统架构

系统的权限设计可粗可细,对用户来说只关心每个角色能干什么,而对开发人员来说就必须要细到每个菜单、按钮和 API。为了让用户、产品和开发都能够从各自的角度去设计和理解权限,从上到下,由粗到细,抽象了三层权限,分别为 Role、Privilege 和 Resource。层与层之间均为多对多关系,每层可以按自己的粒度来划分系统权限,如有变动只需调整映射关系,无需修改权限验证代码。

库表设计

UML 模型

  1. 默认 Role 为所有团队共用,其关联 Privilege 随产品功能升级而自动调整,用户自定义 Role 需要自己手动配置;
  2. Resource 按照前端功能实现划分为模块、功能和操作三个层级;
  3. API 按照后端功能实现划分为微服务、模块和 API 三个层级;
  4. 如果业务上并没有新增 Privilege 时其父节点所关联 Role 自动拥有该 Privilege 的需求,或者想简化连表查询,Role 与 Privilege、Privilege 与 Resource、Resource 与 Api 之间都只在树形结构的最底层叶子结点进行关联,也就是不支持通配符匹配,上层组结点仅用于树形呈现;
  5. 权限验证时,前端根据当前菜单或按钮所需的 permissions 检查当前用户的 permissions 是否满足(全部或任意),后端先获取当前 API 所关联的 Resources 的 permissions,然后检查当前用户的 permissions 是否满足(任意);

示例数据

Role(角色)

id
team_id
project_id
name
description
is_default
1
null
null
TEAM_OWNER
团队拥有者
true
2
null
null
TEAM_ADMIN
团队管理员
true
3
null
null
TEAM_MEMBER
团队成员
true

Privilege(权限)

id
parent_id
order
name
description
1
null
0
功能权限

2
1
0
数据集功能

3
2
0
数据集创建

4
2
1
数据集修改

5
2
2
数据集查看

6
2
3
数据集删除

7
null
1
管理权限

8
7
0
团队成员管理

9
8
0
团队成员邀请

10
8
1
团队成员移除

Resource(资源)

id
parent_id
order
permission
description
1
null
0
null
数据集模块
2
1
0
null
数据集功能
3
2
0
dataset:dataset:create
数据集创建
4
2
1
dataset:dataset:edit
数据集修改
5
2
2
dataset:dataset:view
数据集查看
6
2
3
dataset:dataset:delete
数据集删除
7
1
1
null
数据功能
8
7
0
dataset:data:upload
数据上传
9
7
1
dataset:data:delete
数据删除
10
1
2
null
本体功能
11
10
0
dataset:ontology:create
Class 创建
12
10
1
dataset:ontology:delete
Class 删除

Api(接口)

id
parent_id
order
path
description
1
null
0
null
数据集微服务
2
1
0
null
数据集模块
3
2
0
/dataset/dataset/create
数据集创建
4
2
1
/dataset/dataset/edit/{1}
数据集修改
5
2
2
/dataset/dataset/list
数据集列表
6
2
3
/dataset/dataset/info/{1}
数据集查看
7
2
4
/dataset/dataset/delete/{1}
数据集删除