滚动新闻 →
加拿大报税后发现银行账户填错怎么办 殖民时代法院如何处理债务纠纷 黑脚人控制的北美西部世界 亲共侨领宣国军申请免保释金 遭法官驳回 观美国两党竞争 中国人从中学到什么? 美海关公布年终执法 查获724公斤冰毒 纱窗应该怎么测量尺寸 AI 模型版本管理应该怎样设计,训练完成后的模型如何安全进入生产环境 美议员提案:H-1B薪资从六万升至十四万美元 Cloud SQL 高可用怎么配置,数据库发生实例故障后如何恢复服务 PHP 更新数据时加入 version 字段,可以解决哪些并发问题 57个粉丝的博主发AI视频调侃问界 被索赔百万 笔记本电脑插电才能开机,拔掉充电器马上关机,电池可能出了什么问题 Windows 11 文件分组功能怎么用?让大量文件更加容易浏览 PHP PDO 预处理语句怎么写?从查询参数到安全执行完整演示 辛弃疾为什么能够把豪情写进词里 骗子被耍惨 澳洲初创公司用AI扮受害者收集情报 浙江男没工作杀人泄愤 进写字楼随机砍死女职员 枸杞在中国传统饮食文化中的历史 中国书法为什么强调“气韵” 韩国军事基地曝漏洞 近200辆比亚迪可进出 个人是养老第一责任人? 山东民政厅厅长言论惹议 传成都人从俄罗斯回国后死亡 官方称鼠疫信息保密 如何培养孩子对校园同学的尊重 视频压缩为什么会影响画面细节 川普乔治亚州助选 博顿斯拼首位黑人女州长 胡塞武装持续攻击沙特 油价飙破110美元 美拟升级中国旅行警告 提高“非法拘押”风险等级 中国人存钱不消费 IMF:因沉重医疗成本 伊朗镇压黑幕曝光 革命卫队陷缺钱危机 欧洲三国爆发抗议 比利时警民激烈冲突 双台风夹击太平洋 墨西哥和关岛紧急戒备 武则天为何能够登上皇帝之位 旧房改造是不是一定要大拆大建 官媒转向?《经济日报》下场批判“懂车帝” 川普救油价暂缓对俄制裁 泽连斯基:无法接受 加州多地爆发野火 数栋豪宅遭焚毁 豆瓣酱背后有什么样的地域饮食文化 喜欢自然风景的人怎样安排旅行 汽车启动机故障有哪些常见表现

SaaS 系统如何处理一个账号对应多个角色,权限设计可以这样规划

发布时间: 2026-09-27 14:00:02    最后更新: 2026-10-17 02:16:42    阅读:74  约12 分钟阅读     

SaaS 系统如何处理一个账号对应多个角色,权限设计可以这样规划
图片说明:示意图   图片来源:Public Domain(公有领域)
一个 SaaS 系统发展到一定规模以后,“一个用户到底是什么角色”往往会变成一个比想象中复杂的问题。

最简单的系统可以规定一个账号只能有一个角色,例如普通用户、编辑、管理员。但真正进入企业应用以后,同一个人可能同时承担多种工作:他可能是某个部门的负责人,同时又是项目管理员;在一个项目中拥有编辑权限,在另一个项目中却只能查看;甚至在同一个租户里,他是普通员工,在平台某个特定功能中又拥有管理权限。

如果数据库只给用户表增加一个 role 字段,这种需求很快就会把系统逼入死胡同。

更合理的做法,是把“用户是谁”和“用户能够做什么”分开。用户是身份主体,角色是权限集合,权限描述可以执行什么操作,而资源范围决定这些权限究竟可以作用于哪些数据。

一个账号为什么需要多个角色

假设一家企业使用 SaaS 系统,张三属于销售部门,同时负责一个项目。

在公司层面,他可能是“销售主管”;在项目层面,他又是“项目管理员”;对于财务模块,他可能只有查看权限。

如果系统只允许一个角色,就必须创建一个类似“销售主管+项目管理员+财务查看”的超级角色。

问题在于,这种角色会越来越多。

李四可能是销售主管加项目成员,王五可能是销售主管加财务管理员。几个月以后,系统里就会出现大量针对个人组合出来的角色。

这就是权限设计经常出现的“角色爆炸”。

因此,一个成熟的 SaaS 系统通常允许用户与多个角色建立关联。用户拥有多个角色后,系统再根据这些角色对应的权限计算当前请求是否允许执行。

用户、租户、角色和权限不能混在一起

多租户 SaaS 最容易犯的错误,就是把“用户是管理员”理解成一个全局属性。

实际上,一个用户可能属于多个租户,也可能在不同租户中拥有完全不同的角色。

例如同一个账号加入公司 A 后是普通员工,加入公司 B 后却是管理员。

因此,角色关系通常不能简单设计成:

user_id → role_id

而应该至少考虑租户或者组织上下文。

一个常见设计是使用用户、租户、角色和用户角色关联等数据结构。例如用户表保存账号身份,租户表保存企业或组织,角色表保存角色定义,用户角色关联表保存“哪个用户在什么租户中拥有哪个角色”。

这样,系统判断权限时首先确定当前请求属于哪个租户,然后再判断这个用户在这个租户中拥有哪些角色。

这一步非常重要,因为“管理员”不是一个脱离上下文的绝对身份。

RBAC 是基础,但不要把所有问题都塞进角色

对于绝大多数 SaaS 系统,RBAC,也就是基于角色的访问控制,是一个非常合适的基础模型。

角色可以定义成:

管理员可以管理用户;

编辑可以创建和修改文章;

审核员可以审核文章;

普通用户可以查看文章。

权限则可以进一步拆分成资源和操作。

例如:

article.read

article.create

article.update

article.delete

article.publish

这样,角色只是这些权限的集合。

“编辑”角色可以拥有 article.read、article.create 和 article.update;“审核员”可以拥有 article.read 和 article.publish。

这种设计比在程序代码中到处写:

if ($user->role == 'admin')

更加容易维护。

但 RBAC 解决的是“用户有没有某种能力”,并不自动解决“他可以操作哪一条数据”。

真正复杂的是数据范围

假设张三拥有 article.update 权限。

这是否意味着他可以修改整个 SaaS 平台所有租户的文章?

当然不是。

即使张三拥有编辑权限,也可能只能修改自己部门的文章,或者只能修改自己创建的文章。

因此,权限判断至少需要区分两个层面。

第一层是操作权限,也就是“能不能修改文章”。

第二层是资源范围,也就是“能修改哪些文章”。

例如一个角色可以拥有文章编辑权限,但数据范围限制为当前租户;另一个角色则只能操作自己创建的文章。

这也是为什么 SaaS 权限系统不能只依赖 RBAC。

当权限开始受到部门、地区、项目、资源所有者、组织层级等条件影响时,就需要加入更加细粒度的授权规则。这个时候可以采用 RBAC 与属性或策略条件结合的方式,而不一定需要把整个系统改造成一个复杂的 ABAC 策略引擎。

多个角色的权限通常应该怎么合并

假设一个用户同时拥有“编辑”和“审核员”两个角色。

编辑拥有:

article.read

article.create

article.update

审核员拥有:

article.read

article.publish

那么这个用户最终拥有的有效权限通常就是两个角色权限的集合。

也就是说,多个角色产生的是权限叠加,而不是角色之间互相覆盖。

因此,一般不需要人为给角色设置“管理员优先级100、编辑优先级50”这种机制来决定谁覆盖谁。

真正需要定义的是权限冲突规则。

例如一个角色允许访问某项资源,而另一个角色明确拒绝访问,系统到底采用允许还是拒绝?

这不能靠“哪个角色等级高”简单解决,而应该在整个授权模型建立统一规则。

一种常见做法是明确规定拒绝优先;另一种更简单的 RBAC 系统则尽量避免在角色层面设置显式 deny,只通过授予哪些权限来控制访问。

关键是规则必须稳定、可预测,而且所有业务模块都使用同一套授权逻辑。

角色继承也不要设计得太复杂

角色继承听起来很方便。

例如“管理员”继承“编辑”,于是管理员自动拥有编辑权限。

但角色层级一旦过深,权限关系就会变得很难理解。

管理员继承编辑,编辑继承普通用户,项目管理员又继承编辑,最后某个用户到底为什么拥有某项权限,开发人员甚至需要沿着多层继承关系才能查出来。

因此,对于大多数 SaaS 系统,角色继承应该保持简单。

如果只是为了减少重复权限,可以让高级角色包含基础角色的权限;但不要轻易建立几十层复杂的继承树。

更进一步的系统甚至可以不使用传统的角色继承,而是通过角色组合来解决权限复用问题。

权限模型最怕的并不是代码多,而是管理员自己都无法解释“为什么这个人拥有这个权限”。

不要把权限直接写死在前端

前端可以根据权限隐藏按钮,但这只是用户界面控制,不是安全控制。

例如页面上没有“删除用户”按钮,并不意味着用户没有删除用户的能力。

攻击者完全可以直接调用 API。

因此真正的权限检查必须发生在服务器端。

用户发送一个删除请求以后,后端需要重新确认身份、当前租户、目标资源以及操作权限。

例如用户拥有 user.delete,并不代表他可以删除另一个租户的用户。

后端必须同时验证目标用户是否属于当前租户,以及当前操作者是否有权处理这个资源。

这实际上也是防止 IDOR,也就是通过修改资源 ID 越权访问其他数据的重要措施。

权限缓存可以提高性能,但不能破坏权限一致性

大型 SaaS 系统每一次 API 请求都查询几十张权限表,当然会产生性能问题,因此权限结果经常需要缓存。

例如系统可以缓存某个用户在某个租户中的有效权限集合。

但权限缓存最大的风险就是“权限已经修改,而缓存还没有失效”。

管理员刚刚取消了某个用户的删除权限,如果旧权限还在缓存中,这个用户可能在一段时间内继续执行删除操作。

因此权限缓存必须设计明确的失效机制。

角色变化、用户角色关系变化、权限策略变化以后,应当及时使相关缓存失效。

对于高风险操作,还可以采用更加严格的实时检查,而不是完全依赖长时间缓存。

数据库设计应该保持清晰

一个基础的多角色 SaaS 权限系统,可以从这些核心数据开始设计:

users 保存用户身份。

tenants 保存企业或组织。

roles 保存角色。

permissions 保存系统权限。

user_roles 保存用户、租户与角色之间的关联。

role_permissions 保存角色与权限之间的关联。

业务数据表则根据具体业务增加 tenant_id、owner_id、department_id、project_id 等字段,用于确定资源属于谁。

这样,系统就能够分别回答几个不同的问题:

这个人是谁?

他属于哪个租户?

他在这个租户中是什么角色?

这个角色拥有哪个操作权限?

当前目标资源属于哪个租户?

这个用户是否有权对这条资源执行这个操作?

这几个问题分开以后,权限系统才容易继续扩展。

平台管理员和租户管理员必须分开

SaaS 系统还有一个经常被忽略的问题,就是平台管理员。

平台运营人员和客户企业管理员并不是同一种身份。

例如 SaaS 平台工作人员可能需要管理所有租户,而某家公司自己的管理员只能管理本公司的用户。

如果把两者都简单叫做 admin,后续很容易出现严重的权限边界问题。

因此最好明确区分平台级权限和租户级权限。

平台管理员拥有的是平台管理能力;租户管理员拥有的是当前租户范围内的管理能力。

即使某个租户管理员拥有“用户删除”权限,也不能因为 API 中存在 user_id 就允许他删除其他租户的用户。

权限系统一定要有审计记录

权限本身是安全敏感数据,因此角色和权限发生变化以后,最好留下完整的审计记录。

例如谁修改了谁的角色、什么时候修改、从什么角色改成什么角色、操作者属于哪个租户、修改了什么权限。

对于高风险操作,还应该记录具体资源和操作结果。

这样发生安全事件以后,系统才能回答一个非常现实的问题:

“这个人为什么在昨天晚上突然获得了管理员权限?”

如果没有审计日志,很多时候只能去翻服务器日志,甚至无法确定是谁做的。

不要为了“高级”而过度设计权限系统

SaaS 权限设计有一个很明显的误区,就是一开始就准备 RBAC、ABAC、策略引擎、角色继承、动态表达式、条件权限和复杂权限缓存。

结果系统还没有几个用户,权限代码已经比业务代码复杂。

更实际的路线通常是先建立清晰的 RBAC 基础,让用户可以在不同租户中拥有一个或多个角色,再增加资源范围控制。

当业务确实出现“同一个角色在不同部门权限不同”“只能操作自己创建的数据”“只能访问指定项目”等需求以后,再增加条件授权。

对于多数 SaaS 系统来说,一个结构清楚的 RBAC 加租户隔离,再结合资源级授权,就已经可以覆盖大量实际场景。

权限系统真正难的地方,不是把数据库表设计得多么复杂,而是让每一次授权判断都能够回答清楚三个问题:谁在什么租户中,以什么身份,对哪一个资源,执行什么操作。

一旦这几个概念在架构层面被明确下来,一个账号拥有多个角色就不再是特殊情况,而只是用户与角色之间多对多关系的一种正常表现。真正需要防止的,是角色、租户和数据范围彼此混杂,让一个看似普通的“管理员权限”最终变成跨租户访问数据的漏洞。

喜欢这篇报道?

使用下面的功能,方便以后继续阅读和分享 MNewsTV

设为 Google 新闻首选来源 让 Google 新闻优先显示 MNewsTV 的最新报道 ›
★ 我的收藏 查看已经收藏的文章
关于文章收藏 收藏不需要注册帐号,收藏信息仅保存在当前浏览器中。 删除收藏请进入「我的收藏」进行管理。
分享这篇报道

捐助(Paypal): https://www.paypal.me/observeccp
订阅中国观察电报 Telegram : https://t.me/s/ObserveCCP