做 SaaS 产品这么多年,我发现权限控制是个特别有意思的话题。说它简单吧,很多团队都做得奇奇怪怪;说它复杂吧,掌握了核心原理后其实也就那么回事。
如果你是产品经理、技术负责人,或者正在做 B 端产品的创业者,这篇文章可能会对你有一些帮助。今天咱们就聊聊 SaaS 产品里的权限控制,怎么设计、怎么实施、怎么避坑。
1 为什么权限控制这么重要
说个数据:2022 年 SaaS 安全报告显示,43% 的企业因为权限配置错误导致过数据泄露。而业内人士都知道,实际比例可能高达63%------很多公司出了事都选择悄悄处理,不对外声张(也能理解的)。
再看一下 2020 年,微盟删库事件,一个运维人员因为跟公司有矛盾,趁着自己还有生产环境的管理员权限,直接把核心数据库给删了。
300 万商家的店铺全部瘫痪,整整 7 天无法营业。正值疫情期间,很多商家本来就靠线上维持生计,这一下彻底断了收入来源。最后微盟赔偿了1.5亿,股价暴跌,品牌信誉更是一落千丈。
事后复盘发现问题出在哪?
- 一个人就能删除生产数据库,没有任何审批流程
- 删除操作没有双人复核机制
- 权限过度集中,运维人员的权限大到离谱
以此作为警示:对 SaaS 行业来说,权限管理不是技术问题,是生死问题。
为什么说权限问题往往比较致命?
做了这么多年 ToB 产品,我发现权限问题有几个特点:
1. 爆发性强:不像性能问题是逐渐恶化,权限问题是突然爆发。今天还好好的,明天就可能因为一个配置错误,导致全部客户数据泄露。
2. 影响面广:一个权限漏洞,可能影响所有客户。特别是多租户架构,一个 bug 就能让所有租户的数据混在一起(如果在多租户逻辑中使用的是字段隔离,而且大部分 SaaS 产品是这样做的)。
3. 修复成本高:早期设计不好,后期改造就是噩梦。
4. 信任难恢复:客户把核心数据放在你的系统里,是基于信任。一旦出现权限问题,这种信任很难恢复。哪怕你后来改得再好,客户心里也会有阴影。
权限控制是基础,这就像盖房子,地基不牢,楼盖得越高越危险。
2 权限控制的核心概念
在深入讨论之前,咱们先把几个基本概念理清楚。
2.1 权限的本质是什么
说白了,权限就是回答一个问题:谁能对什么做什么操作?
- 谁:用户、角色、部门
- 什么:功能模块、数据对象、页面按钮
- 操作:查看、创建、编辑、删除、审批
这三个要素组合起来,就构成了权限控制的基础。比如「财务主管可以查看所有部门的报销单」,这就是一条权限规则。
2.2 功能权限和数据权限
很多人容易把这俩混在一起,其实它们解决的是不同维度的问题。
功能权限控制的是「能不能用这个功能」。比如普通员工看不到薪资管理模块,这就是功能权限。实现起来相对简单,一般在前端控制菜单显示,后端做接口校验就行。
数据权限控制的是「能看到哪些数据」。同样是查看订单列表,销售 A 只能看自己的订单,销售主管能看整个团队的订单,老板能看全公司的订单。这就是数据权限,实现起来要复杂得多。
有一个典型案例:某 CRM 系统,销售经理发现自己看不到下属的客户数据,一查才发现只做了功能权限,忘了做数据权限。结果所有销售经理都只能看到自己作为销售时录入的客户,管理功能形同虚设。
2.3 权限的安全边界
做权限控制,安全永远是第一位的。我总结了几个容易踩坑的地方:
前端权限不可信:永远不要只在前端做权限判断,哪怕把按钮隐藏了,懂技术的人照样能通过开发者工具发请求。所有权限判断必须在后端再做一遍。
默认拒绝原则:权限设计应该是「没有明确允许的都是禁止的」,而不是「没有明确禁止的都是允许的」。这个原则能避免很多安全漏洞。
最小权限原则:给用户的权限应该刚好够用就行,不要为了方便给过多权限。特别是生产环境的管理员权限,能不给就不给,给了也要有审计日志。
3 三种主流权限模型
聊完基础概念,咱们来看看业界常用的几种权限模型。每种模型都有自己的适用场景,没有绝对的好坏。
3.1 ACL
ACL,访问控制列表,是最直观的权限模型,直接定义「用户-资源-权限」的对应关系。比如:
- 张三可以编辑文档 A
- 李四可以查看文件夹 B
- 王五可以删除报表 C
优点是简单直接,实现容易。早期的文件系统、简单的内容管理系统多用这种模型。
缺点也很明显:用户一多就没法管理了。假设你有 1000 个用户,100 个资源,每个资源有 5 种操作权限,理论上你需要维护 50 万条权限记录。更要命的是,新员工入职你得一个个配置权限,员工离职你得一个个回收权限,运维成本极高。
所以 ACL 一般只适合用户量少、权限关系简单的场景。如果你的 SaaS 产品用户量大,还是趁早换其他模型。
3.2 RBAC
RBAC,基于角色的访问控制,是目前最主流的权限模型,核心思想是引入「角色」这个中间层。用户不直接拥有权限,而是通过角色来获得权限。
比如定义几个角色:
- 销售员:可以查看和编辑自己的客户、订单
- 销售主管:可以查看和编辑本部门所有客户、订单,可以查看销售报表
- 财务人员:可以查看所有订单,可以开具发票,可以查看财务报表
新员工入职,只需要给他分配对应角色就行了。角色的权限变了,所有该角色的用户权限自动更新。
RBAC 还可以细分为四种类型,实际应用中按需选择:
RBAC0(基本模型):最简单的实现,用户-角色-权限三层结构。大部分中小型 SaaS 产品用这个就够了。
RBAC1(角色分层模型):角色可以继承。比如「销售主管」自动继承「销售员」的所有权限,再加上管理权限。这样可以减少重复配置。
RBAC2(角色限制模型):增加了约束条件。比如「角色互斥」(一个用户不能既是采购员又是审批员),「角色数量限制」(一个用户最多只能有 3 个角色)等。
RBAC3(统一模型):集成了 RBAC1 和 RBAC2 的所有特性,最完整但也最复杂。
我的建议是从 RBAC0 开始,随着业务发展再考虑升级。过度设计只会增加系统复杂度。
3.3 ABAC
ABAC,基于属性的访问控制,是相对较新的模型,通过属性组合来判断权限。这些属性可以来自:
- 用户属性:部门、职级、工龄、地域
- 资源属性:类型、创建者、敏感度、标签
- 环境属性:时间、地点、设备类型
举个例子:"华东区的销售经理在工作时间可以查看本区域高价值客户的信息"。这条规则涉及了用户的地域属性、角色属性,资源的地域属性、价值属性,以及时间这个环境属性。
ABAC 的优势是灵活性极高,可以实现非常精细的权限控制。缺点是实现复杂,性能开销大,权限规则难以理解和调试。
一般来说,如果你的业务场景确实需要这么复杂的权限控制(比如医疗、金融等强监管行业),可以考虑 ABAC。否则 RBAC 就足够了。
4 SaaS 产品的特殊挑战
相比传统的企业内部系统,SaaS 产品在权限控制上面临一些独特的挑战。
4.1 多租户隔离
这是 SaaS 最核心的需求。同一套系统里住着几百上千家企业,必须保证数据完全隔离。A 公司的员工绝对不能看到 B 公司的任何数据。
常见的隔离方案有三种:
独立数据库:每个租户一个数据库。隔离性最好,但成本高,难以维护。适合大客户少量部署的场景。
共享数据库、独立 Schema:每个租户一个 Schema。隔离性不错,成本适中。适合中等规模的 SaaS 产品。
共享数据库、共享表:所有租户的数据都在同一张表里,通过 tenant_id 字段区分。成本最低,但要特别小心 SQL 注入和权限泄露。这是大部分 SaaS 产品的选择。
如果采用第三种方案,一定要在所有 SQL 查询中强制加上 tenant_id 条件。我见过的好做法是在 ORM 层面做全局过滤器,或者在数据库层面用行级安全策略(Row Level Security)。
4.2 组织架构的映射
企业客户通常都有复杂的组织架构,我们的权限系统必须能够映射这种结构。常见的需求包括:
- 树形部门结构,支持多层级
- 一个人可能属于多个部门(兼职、虚拟团队)
- 临时授权(代理、请假)
- 按项目组、按地域等多维度的权限控制
- 集团,公公司等逻辑
我的经验是,组织架构不要做得太复杂,够用就行。很多企业其实就是简单的部门层级 + 角色,硬要上矩阵式组织、事业部制这些复杂结构,反而增加了使用成本。
4.3 权限的动态性
SaaS 产品的权限需求经常变化:
- 新功能上线,需要新的权限点
- 客户要求定制化的权限规则
- 不同行业、不同规模的客户,权限需求差异很大
所以权限系统必须设计得足够灵活。我推荐的做法是:
权限点动态化:不要把权限点写死在代码里,而是存在数据库里,通过配置来管理。
规则引擎:对于复杂的权限判断逻辑,可以引入规则引擎,让权限规则可以通过配置来调整。
权限模板:为不同类型的客户准备权限模板,新客户注册时可以快速初始化。
4.4 性能优化
权限判断是高频操作,一个页面可能要判断几十上百个权限点。如果每次都查数据库,性能肯定扛不住。
常用的优化手段:
缓存:用户登录时把权限信息缓存到 Redis,设置合理的过期时间。权限变更时主动刷新缓存。
权限位图:把权限用位图来表示,一个 long 型变量可以表示 64 个权限点,判断权限只需要位运算。
懒加载:不要一次性加载所有权限,而是按需加载。比如用户进入某个模块才加载该模块的权限。
预计算:对于数据权限,可以预先计算好用户能访问的数据 ID 列表,查询时直接用 IN 条件。
5 设计一个权限系统
说了这么多理论,咱们来点实际的。假设你要为一个 SaaS CRM 系统设计权限控制,应该怎么做?
5.1 需求分析
首先要搞清楚业务需求:
- 系统有哪些功能模块?客户管理、订单管理、报表分析等
- 有哪些角色?销售员、销售主管、客服、财务、管理员等
- 数据权限如何划分?按部门、按区域、按客户等级等
- 有哪些特殊需求?审批流程、临时授权、数据导出限制等
5.2 模型选择
对于 CRM 这种相对标准的业务系统,RBAC 是首选。具体用 RBAC0 还是 RBAC1,看企业规模:
- 中小企业:RBAC0 足够,角色数量有限,权限关系简单
- 大型企业:考虑 RBAC1,利用角色继承减少配置工作
5.3 数据库设计
核心表结构:
sql
-- 用户表
CREATE TABLE users (
id BIGINT PRIMARY KEY,
tenant_id BIGINT NOT NULL,
username VARCHAR(50) NOT NULL,
-- 其他字段...
INDEX idx_tenant (tenant_id)
);
-- 角色表
CREATE TABLE roles (
id BIGINT PRIMARY KEY,
tenant_id BIGINT NOT NULL,
role_name VARCHAR(50) NOT NULL,
parent_id BIGINT, -- 用于角色继承
-- 其他字段...
INDEX idx_tenant (tenant_id)
);
-- 权限表
CREATE TABLE permissions (
id BIGINT PRIMARY KEY,
permission_code VARCHAR(100) NOT NULL, -- 如 'customer.view'
permission_name VARCHAR(100) NOT NULL,
module VARCHAR(50), -- 所属模块
-- 其他字段...
UNIQUE KEY uk_code (permission_code)
);
-- 用户-角色关联表
CREATE TABLE user_roles (
user_id BIGINT NOT NULL,
role_id BIGINT NOT NULL,
PRIMARY KEY (user_id, role_id)
);
-- 角色-权限关联表
CREATE TABLE role_permissions (
role_id BIGINT NOT NULL,
permission_id BIGINT NOT NULL,
PRIMARY KEY (role_id, permission_id)
);
-- 数据权限规则表
CREATE TABLE data_permissions (
id BIGINT PRIMARY KEY,
role_id BIGINT NOT NULL,
resource_type VARCHAR(50), -- 如 'customer', 'order'
rule_type VARCHAR(50), -- 如 'self', 'department', 'all'
rule_value TEXT, -- 具体规则,可以是 JSON
INDEX idx_role (role_id)
);
6 避坑指南
做了这么多项目,我总结了一些常见的坑,希望你能避开:
6.1 过度设计
最常见的错误就是一上来就想做一个「完美」的权限系统。支持 ABAC、支持动态规则、支持工作流集成... 结果做了半年还没上线,业务等不及了。
记住,权限系统是为业务服务的,不是为了秀技术。先满足基本需求,再逐步迭代。
6.2 忽视性能
另一个常见问题是只关注功能,不关注性能。权限判断是高频操作,如果每次都要查十几张表,系统很快就会崩溃。
一定要做好缓存,关键接口要做压测。我的经验是,权限判断的响应时间应该控制在 10ms 以内。
6.3 权限配置过于复杂
有些系统的权限配置界面,复杂得连开发人员都搞不清楚。这样的系统,客户是不会用的。
权限配置要尽量简化,提供合理的默认值和模板。最好能提供权限检查工具,让管理员可以模拟某个用户的权限,看看到底能访问哪些功能和数据。
6.4 缺少审计日志
权限系统必须有完善的审计日志,记录谁在什么时候做了什么操作。特别是权限的授予和回收,必须有据可查。
这不仅是安全需要,很多行业还有合规要求。审计日志最好是独立存储,防止被篡改。
6.5 数据权限的 N+1 问题
实现数据权限时,很容易出现 N+1 查询问题。比如查询订单列表,每个订单都要判断一次是否有权限查看,结果一个列表页产生了上百次数据库查询。
解决方案是在列表查询时就加入权限过滤条件,而不是查出来再过滤。这需要在 SQL 层面就考虑权限问题。
7 其它一些变化
权限控制这个领域,这几年也有一些新的发展趋势:
7.1 Zero Trust 模型
Zero Trust 模型就是我们常说的零信任模型。
传统的权限模型是「城堡式」的:进了城门(登录系统)就基本畅通无阻。Zero Trust 模型要求每次访问都要验证权限,不管你是内部用户还是外部用户。
这对 SaaS 产品来说特别重要,因为用户可能从任何地方、任何设备访问系统。
7.2 AI 辅助的权限管理
利用机器学习来优化权限配置,比如:
- 根据用户行为自动推荐合适的角色
- 检测异常的权限使用,可能是账号被盗用
- 自动发现权限配置中的冲突和冗余
7.3 细粒度的数据权限
不仅控制能不能看某条数据,还要控制能看到数据的哪些字段。比如普通销售能看到客户的基本信息,但看不到信用额度;财务能看到信用额度,但看不到跟进记录。
这需要在字段级别做权限控制,实现起来更复杂,但确实是一些行业的刚需。
8 写在最后
权限控制是 SaaS 产品的基础设施,做好了用户感知不到,做不好用户骂声一片。它不是一个能带来直接收益的功能,但却是产品能否长期发展的关键。
我的建议是:
- 不要等到出问题才重视权限,一开始就要规划好
- 选择适合自己业务的权限模型,不要过度设计
- 功能权限和数据权限要分开考虑,都很重要
- 做好性能优化和安全防护,这是基本要求
- 保持系统的灵活性,因为需求一定会变
技术是为业务服务的。不要为了炫技而把简单问题复杂化,也不要为了省事而在安全问题上偷懒。在这两者之间找到平衡,才是一个成熟的技术方案。
以上。