大型Saas系统的权限体系设计(二)
X0 上期回顾
上文《大型Saas系统的权限体系设计(一)》提到2B的Saas系统的多层次权限体系设计的难题,即平台、平台的客户、客户的客户,乃至客户的客户的客户如何授权,这个可以通过“权限-角色-岗位”三级结构来实现。
但这个只是功能权限,如何在数据权限上进行区分和约束呢?比较极端的做法是在岗位设置上设定数据访问权限,但这会带来一个问题,即每个岗位几乎要等同于权限,需要拆分得很细,这会给管理员带来巨大的配置工作负担。所以比较巧妙的办法是把数据权限的控制拆分成宏观和微观,并且做解耦处理。
X1 行级数据权限控制
宏观数据权限控制,也可以称作行级数据权限控制,即管控到每一条数据记录的可访问范围。这个可以通过在“角色”这个实体上进行定义即可,即包括:
- 本人
- 本人即下属
- 本部门
- 指定个人
- 指定部门
- 全部
如果是“指定个人”和“指定部门”,只要设置具体的个人集合或者部门集合,即可限制该角色可访问的数据范围。
如果是对“本人及下属”,相对麻烦点。因为个人和个人之间的汇报关系比较难设定。而大型组织中常常会存在部门负责人和部门分管领导的管理结构,特别是OA审批中,经常会出现“发起人部门领导审批”和“发起人部门分管领导审批”这类设置,比较难以在组织结构和角色上进行实现。如果直接在用户基础上设立“直属上级”,又会带来另一个不好的结果,即如果领导调离会需要修改一大批下属的“直属上级”,一旦修改不及时就可能导致审批权限的混乱。
比较好的解决办法是把上下级关系建立在部门岗位基础上,由岗位形成上下级关系,而个人可以设定多个岗位,则人与人之间的上下级关系自然而然建立,同时又避免了因为上级岗位变动带来的不必要的大面积变更。
X2 列级数据权限控制
微观数据权限控制,也可以称作列级数据权限控制,即管控到每种业务数据的字段的可访问范围。这个控制相对比较复杂,成本也比较高。
如果建立在权限基础上,会导致权限需要拆分得很细。如果建立在角色基础上,又会对角色的大颗粒度造成破坏。而且,一旦把列级数据权限和行级数据权限纠结在一起,很容易形成渔网效应,失去应有的灵活性和适应性。
所以比较好的解决办法是把列级数据权限和行级数据权限解耦,即可以对列级数据权限单独管理,有需要做列级数据权限管理的业务数据才动态添加。而且列级数据权限控制最好控制到岗位这个级别。如下图:

X3 多租户的权限区隔
再回归到最初的议题,如果对于Saas系统,存在多租户,甚至租户有客户的情况下,如何对不同类型的客户的权限进行区隔?或者是否可以进行区隔,并且部分下放权限设置的权限呢?
答案是肯定的,而且必须下放。
设想下,一个成功的Saas系统,用户少则几万,多则千万,如果这么多的用户的权限管理都归于平台管理员一身,本身就是巨大的成本。所以下放权限管理功能是毋庸置疑的。但怎么下放呢?
- 首先,权限这级应该是收归平台层管理的,角色这级部分也可以归平台层管理,主要是多数租户可以共用的角色。但租户和客户管理员,应该被授予角色创建的权限,这样才可能适应不同组织的特点设计不同的角色。
- 其次,角色应该有权属的概念,即A租户创建的角色和B租户创建的角色是不可以共用的,A租户创建的角色原则上也不适用于A租户的客户。
- 其次,对于权限应该设定适合的角色类型。这样各级管理员在创建用户角色时,将只能在限定的权限范围内去做角色的权限授权(很难想象,你客户的管理员可以在创建角色时看到你平台所有的菜单权限,OMG)。
- 最后,光有权限和角色还不够,非常有必要增加“岗位”的概念。这个岗位虽然只对应一个角色,但同时需要明确所属部门(或组织),这样角色才可能得到最大程度的复用。现实生活中,不同部门的相同职位的管理人员既有相似的工作职能,也可能有不同的工作职能,所以光通过角色去设置可能导致不必要的冲突。
只要我们把角色、岗位之类的权限设置也看成一种数据,并且纳入数据权限控制的范畴,那么多租户的权限区隔就很容易实现了。

X4 结束语
近期也看到有一个开源的授权库模型 Casbin(一个支持如ACL, RBAC, ABAC等访问模型,可用于Golang, Java, C/C++, Node.js, Javascript, PHP, Laravel, Python, .NET (C#), Delphi, Rust, Ruby, Lua (OpenResty), Dart (Flutter)和Elixir的授权库。),国外应用极广。
结合以上拙文,供遇到相同问题并且在思考解决办法的同行参考。赠人玫瑰,手有余香,欢迎不吝赐教或者技术交流。
相关文章:
大型Saas系统的权限体系设计(二)
X0 上期回顾 上文《大型Saas系统的权限体系设计(一)》提到2B的Saas系统的多层次权限体系设计的难题,即平台、平台的客户、客户的客户,乃至客户的客户的客户如何授权,这个可以通过“权限-角色-岗位”三级结构来实现。 但这个只是功能权限&am…...
HTML(四) -- 多媒体设计
目录 1. 视频标签 2. 音频标签 3. 资源标签(定义媒介资源 ) 1. 视频标签 属性值描述autoplayautoplay如果出现该属性,则视频在就绪后马上播放。controlscontrols表示添加标准的视频控制界面,包括播放、暂停、快进、音量等…...
设置苹果电脑vsode在新窗口中打开文件
0、前言 最近切换到mac电脑工作,又得重新安装一些工具软件并设置。虽然这些设置并表示啥复杂的设置,但是久了不设置还是会忘记。于是记录之,也希望给能帮助到需要的人。 我们使用vscode阅读或者编辑文件时,有时候希望同时打开多…...
第二章创建模式—单例设计模式
文章目录 单例模式的结构如何控制只有一个对象呢怎么设计这个类的内部对象外部怎么访问 单例模式的主要有以下角色 单例模式的实现饿汉式 1:静态变量饿汉式 2:静态代码块懒汉式 1:线程不安全懒汉式 2:线程安全—方法级上锁懒汉式 …...
数据结构学习记录——堆的插入(堆的结构类型定义、最大堆的创建、堆的插入:堆的插入的三种情况、哨兵元素)
目录 堆的结构类型定义 最大堆的创建 堆的插入 堆的插入的三种情况 代码实现 哨兵元素 堆的结构类型定义 #define ElementType int typedef struct HNode* Heap; /* 堆的类型定义 */ struct HNode {ElementType* Data; /* 存储元素的数组 */int Size; /* 堆中…...
netperf测试
netperf测试 目录 批量网络流量性能测试 TCP_STREAM测试UDP_STREAM 测试请求/应答网络流量测试 TCP_RR TCP_CRR Netperf 是一个网络性能测试工具,它可以测试网络协议栈的性能,例如TCP和UDP协议。Netperf可以测量网络吞吐量、延迟和CPU利用率等指标。…...
ORACLE常用语句
1.修改用户密码 alter user 用户名 identified by 新密码; 2.表空间扩容 1.增加数据文件 alter tablespace AA add datafile ‘DATA’ size 20G autoextend off; 2.修改数据文件大小 ALTER DATABASE DATAFILE ‘E:\ORACLE\PRODUCT\10.2.0\ORADATA\aa\aa.DBF’ RESIZE 400M;…...
[论文笔记]C^3F,MCNN:图片人群计数模型
(万能代码)CommissarMa/Crowd_counting_from_scratch 代码:https://github.com/CommissarMa/Crowd_counting_from_scratch (万能代码)C^3 Framework开源人群计数框架 科普中文博文:https://zhuanlan.zhihu.com/p/65650998 框架网址:https…...
HCIP-7.2VLAN间通信单臂、多臂、三层交换方式学习
VLAN间通信单臂、多臂、三层交换方式学习 1、单臂路由2、多臂路由3、三层交换机的SVI接口实现VLAN间通讯3.1、VLANIF虚拟接口3.2、VLAN间路由3.2.1、单台三层路由VLAN间通信,在一台三层交换机内部VLAN之间直连。3.2.2、两台三层交换机的之间的VLAN通信。3.2.3、将物…...
PHP快速入门17-用spl_autoload_register实现类的自动加载
文章目录 前言实现过程创建两个类创建入口文件 总结 前言 本文已收录于PHP全栈系列专栏:PHP快速入门与实战 PHP类自动载入是指在PHP应用程序中,当需要使用某个类文件时,系统会自动加载该类文件,无需手动引入。 在PHP中…...
【黑马程序员 C++教程从0到1入门编程】【笔记8】 泛型编程——模板
https://www.bilibili.com/video/BV1et411b73Z?p167 C泛型编程是一种编程范式,它的核心思想是编写通用的代码,使得代码可以适用于多种不同的数据类型。 而模板是C中实现泛型编程的一种机制,它允许我们编写通用的代码模板,然后在需…...
分享10个精美可视化模板,解决95%的大屏需求!
前段时间和朋友一起喝茶,我吐槽着excel表格做报表的繁琐,他惊讶的问我竟然不知道大屏模板这种东西,说是直接套用数据就可以,我震惊的同时吃下了这个安利。 回来之后,我好好研究了一番这个叫可视化大屏的“新鲜玩意儿”…...
好用的项目管理软件的具体功能有哪些
随着企业规模不断的扩大,项目管理往往会面临更多的挑战与难题,最常见的会出现以下几个问题:资源消耗失控,而项目部门和相关部门之间沟通越来越困难;团队凝聚力下降、项目进度难以把控,项目成本几乎失控&…...
< 每日小技巧: 基于Vue状态的过渡动画 - Transition 和 TransitionGroup>
》基于Vue状态的过渡动画 - Transition 和 TransitionGroup 👉 一、Vue Transition 简介> Transition 和 TransitionGroup 之间的区别 👉 二、<Transition> 组件> 触发 <Transition> 组件的场景:> 基于 CSS 的过渡效果&…...
vmware安装redhat 8
vmware安装redhat 8 1、下载镜像文件1.1 镜像文件 2、安装系统2.1、选择自定义安装2.2、兼容性选择2.3、选择镜像文件导入2.4、设置用户名密码2.5、选择虚拟机在磁盘上的位置2.6、选择处理器数量2.7、选择内存大小2.8、选择桥接或NAT2.9、选择SCSI控制器类型2.10、选择虚拟机磁…...
OpenCV C++案例实战三十一《动态时钟》
OpenCV C案例实战三十一《动态时钟》 前言一、绘制表盘二、绘制刻线三、获取系统时间四、结果展示五、源码总结 前言 本案例将使用OpenCV C实现动态时钟效果。原理也很简单,主要分为绘制表盘、以及获取系统时间两步。 一、绘制表盘 首先为了效果显示美观一点&…...
字节后端入门 - Go 语言原理与实践
1.1什么是Go语言 1.2Go语言入门 环境 1.3基础语法 1.3.1变量 var name"value" 自己推断变量类型; 也可以显式类型 var c int 1 name: type(value) 常量: const name "value" g : a"foo" 字符串拼接 1.3.2 if else {}花括号…...
锂电材料浆料匀浆搅拌设备轴承经常故障如何处理?
锂电材料浆料匀浆搅拌设备是锂电池生产中重要的设备之一,用于将活性材料、导电剂、粘结剂和溶剂混合成均匀的浆料,是电极制备过程中不可或缺的步骤。然而,由于高速搅拌和化学腐蚀等因素的影响,轴承经常会出现故障,导致…...
设计模式——设计模式介绍和单例设计模式
导航: 【黑马Java笔记踩坑汇总】JavaSEJavaWebSSMSpringBoot瑞吉外卖SpringCloud黑马旅游谷粒商城学成在线设计模式牛客面试题 目录 一、设计模式概述和分类 1.1 设计模式介绍 1.2 设计模式分类 二、创建型设计模式-单例模式 2.1 介绍 2.2 八种单例模式的创…...
利用Iptables构建虚拟路由器
利用Iptables构建虚拟路由器 (1)修改网络类型 在VMware Workstation软件中选择“编辑→虚拟网络编辑器”菜单命令,在虚拟网络列表中选中VMnet1,将其配置为“仅主机模式(在专用网络内连接虚拟机)”&#x…...
label-studio的使用教程(导入本地路径)
文章目录 1. 准备环境2. 脚本启动2.1 Windows2.2 Linux 3. 安装label-studio机器学习后端3.1 pip安装(推荐)3.2 GitHub仓库安装 4. 后端配置4.1 yolo环境4.2 引入后端模型4.3 修改脚本4.4 启动后端 5. 标注工程5.1 创建工程5.2 配置图片路径5.3 配置工程类型标签5.4 配置模型5.…...
AI Agent与Agentic AI:原理、应用、挑战与未来展望
文章目录 一、引言二、AI Agent与Agentic AI的兴起2.1 技术契机与生态成熟2.2 Agent的定义与特征2.3 Agent的发展历程 三、AI Agent的核心技术栈解密3.1 感知模块代码示例:使用Python和OpenCV进行图像识别 3.2 认知与决策模块代码示例:使用OpenAI GPT-3进…...
前端倒计时误差!
提示:记录工作中遇到的需求及解决办法 文章目录 前言一、误差从何而来?二、五大解决方案1. 动态校准法(基础版)2. Web Worker 计时3. 服务器时间同步4. Performance API 高精度计时5. 页面可见性API优化三、生产环境最佳实践四、终极解决方案架构前言 前几天听说公司某个项…...
Go 语言接口详解
Go 语言接口详解 核心概念 接口定义 在 Go 语言中,接口是一种抽象类型,它定义了一组方法的集合: // 定义接口 type Shape interface {Area() float64Perimeter() float64 } 接口实现 Go 接口的实现是隐式的: // 矩形结构体…...
【JavaSE】绘图与事件入门学习笔记
-Java绘图坐标体系 坐标体系-介绍 坐标原点位于左上角,以像素为单位。 在Java坐标系中,第一个是x坐标,表示当前位置为水平方向,距离坐标原点x个像素;第二个是y坐标,表示当前位置为垂直方向,距离坐标原点y个像素。 坐标体系-像素 …...
基于PHP的连锁酒店管理系统
有需要请加文章底部Q哦 可远程调试 基于PHP的连锁酒店管理系统 一 介绍 连锁酒店管理系统基于原生PHP开发,数据库mysql,前端bootstrap。系统角色分为用户和管理员。 技术栈 phpmysqlbootstrapphpstudyvscode 二 功能 用户 1 注册/登录/注销 2 个人中…...
【前端异常】JavaScript错误处理:分析 Uncaught (in promise) error
在前端开发中,JavaScript 异常是不可避免的。随着现代前端应用越来越多地使用异步操作(如 Promise、async/await 等),开发者常常会遇到 Uncaught (in promise) error 错误。这个错误是由于未正确处理 Promise 的拒绝(r…...
DeepSeek源码深度解析 × 华为仓颉语言编程精粹——从MoE架构到全场景开发生态
前言 在人工智能技术飞速发展的今天,深度学习与大模型技术已成为推动行业变革的核心驱动力,而高效、灵活的开发工具与编程语言则为技术创新提供了重要支撑。本书以两大前沿技术领域为核心,系统性地呈现了两部深度技术著作的精华:…...
AxureRP-Pro-Beta-Setup_114413.exe (6.0.0.2887)
Name:3ddown Serial:FiCGEezgdGoYILo8U/2MFyCWj0jZoJc/sziRRj2/ENvtEq7w1RH97k5MWctqVHA 注册用户名:Axure 序列号:8t3Yk/zu4cX601/seX6wBZgYRVj/lkC2PICCdO4sFKCCLx8mcCnccoylVb40lP...
写一个shell脚本,把局域网内,把能ping通的IP和不能ping通的IP分类,并保存到两个文本文件里
写一个shell脚本,把局域网内,把能ping通的IP和不能ping通的IP分类,并保存到两个文本文件里 脚本1 #!/bin/bash #定义变量 ip10.1.1 #循环去ping主机的IP for ((i1;i<10;i)) doping -c1 $ip.$i &>/dev/null[ $? -eq 0 ] &&am…...
