滚动新闻 →
德州政治格局剧变:民主党在中期选举中全面突破 二手游艇船体应该如何检查 纽约洛克菲勒中心圣诞树正式亮相 幸运市民获赠树枝纪念 美俄乌会谈前夕 基基辅遭袭击 民用设施受损 美军组建‘铁门’特别工作组 筑牢伊朗军备运输防线 澳洲华人外卖员被流浪汉刺死 熊猫外卖遭华人抗议 白宫新闻秘书邀白大拿?川普提议引入格斗冠军应对左派 川普下令司法部调查民主党弹劾计划 波兰克拉科夫枪击案致6死15伤 警方击毙嫌犯 电影项目如何寻找制片公司 网红零食‘肝脆薯了蒜了’健康风险引关注 持枪男子声称受幻听驱使欲刺杀川普 被捕于白宫周边 加拿大退税显示已经发出但没有收到怎么办 加拿大平等权利法律如何建立 华裔社团领袖因涉嫌非法活动遭美国执法部门拘押 意大利外长个人资料遭亲俄黑客泄露 暗网交易引担忧 【笑点解读】美国情景喜剧《生活大爆炸》(The Big Bang Theory)第一季第一集 武汉企业提前还贷遭银行拖延近两月多收利息 波兰克拉科夫枪击案致6死 极右翼影响引关注 感恩节最初到底发生了什么 中东战火升级 美军施压 伊朗急联12国外长 川普提议UFC总裁怀特担任白宫新闻秘书 朝鲜导弹再现乌克兰战场 北约重申俄威胁长期存在 陆媒报尊界认质量问题召回3217辆 几小时后删文 山西男子副驾削苹果急刹车水果刀刺穿心脏 房屋门窗同时出现问题意味着什么 美军空袭伊朗南部 川普称谈判取得突破 10国联合谴责黄之锋案 基金会主席警告勿信中共承诺 多地民众目睹火流星坠落 中国军方高层人事调整引关注 AI 训练为什么需要容错机制,大规模 GPU 集群中的故障概率如何影响架构设计 新西兰大选初步计票结束 两大党得票率差距微乎其微 川普宣布2028年举办全球最大航太展 巴拉圭民众街头欢呼 培尼亚遭弹劾罢免 博索纳罗父子被迫分离 欧美司法战场正在改变保守派政治人物的命运 湖北师大学生拍摄公安人员遭保安拖拽致骨折引争议 Google Cloud Transfer Service 怎么使用,大量文件迁移到云端应该如何安排 美军组建‘铁门’特遣队 筑牢伊朗武器运输防线 波兰克拉科夫主市场广场发生枪击案 至少5人遇难 俄乌冲突升级之际 阿布扎比和谈即将展开 SaaS 数据库分库以后,跨租户查询应该怎样处理

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

发布时间: 2026-09-27 14:00:02    最后更新: 2026-11-07 04:03:54    阅读:99  约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