权限模型概述:从“谁能用”到“怎么用”的进化
权限模型这个事,说白了就是回答三个问题:谁?能干什么?在哪儿干? 我做了十几年安全架构,见过太多项目在权限设计上翻车。有的模型太死板,业务灵活了它就卡壳;有的又太自由,最后权限膨胀到谁也管不住。嗯,这一章我们就来聊聊权限模型是怎么演进的,以及今天主流的四种模型到底该怎么选。
权限模型的发展历程
我最早接触权限系统是在一个金融项目中,当时用的是最古老的方式——直接在代码里写死用户列表。你想想看,那会改一次权限就要重新编译部署,简直是噩梦。后来慢慢有了成熟的模型,我大致把这段历史分成四个阶段:
- 第一阶段(1970s-1980s): 一切靠系统管理员手工维护。典型代表是 Multics 和早期 Unix 的 UID/GID。粗粒度、静态、难扩展。
- 第二阶段(1980s-1990s): DAC(自主访问控制)和 MAC(强制访问控制)走向标准化。我记得那会在做政府项目,MAC 用得很多,因为安全级别够硬,但灵活性真不行。
- 第三阶段(1990s-2010s): RBAC(基于角色的访问控制)成为主流。我在 2000 年代初接手的 ERP 系统就是典型 RBAC,角色一设好,权限管理瞬间清爽很多。
- 第四阶段(2010s-现在): ABAC(基于属性的访问控制)兴起。云原生、微服务、IoT 这些场景里,RBAC 越来越吃力,ABAC 的动态能力正好补上。
如果资源和用户都超过 50 种,就别考虑手工或单层模型了,直接上 RBAC 或 ABAC。
四大主流模型对比
说实话,很多新人容易把模型对立来看。其实它们不是谁替代谁的关系,而是适用场景不同。下面这张表是我自己一直用的对比框架:
| 维度 | DAC | MAC | RBAC | ABAC |
|---|---|---|---|---|
| 核心策略 | 资源所有者决定 | 系统强制规则 | 角色派生权限 | 属性动态评估 |
| 主体 | 用户/用户组 | 安全标签 | 角色 | 用户属性集 |
| 客体 | 文件/目录 | 分级对象 | 业务资源 | 资源属性集 |
| 权限粒度 | 粗(rwx) | 中(等级) | 中(角色权限) | 细(表达式级) |
| 管理复杂度 | 低 | 低-中 | 中 | 高 |
| 典型场景 | 文件系统、个人电脑 | 军方、政府机密 | 企业应用、ERP | 云平台、IoT、API网关 |
DAC:最朴素的“我的地盘我做主”
DAC(Discretionary Access Control)的思路很简单:谁创建了资源,谁就拥有它。Unix 系统的 chmod 就是最典型的例子。我在早期做文件共享系统时,一开始就用的 DAC,结果用户 A 可以把自己的权限转给用户 B,最后权限链乱成一锅粥。
- 优点:实现简单,用户理解成本极低。
- 缺点:无法防止权限扩散(比如“木马程序”利用用户授权)。
- 避坑:我曾经接手的项目,就是因为 DAC 下用户能随意分享权限,最后数据泄露被罚。如果系统里有不可信用户,千万别纯用 DAC。
MAC:强制规则下的“铁板一块”
MAC(Mandatory Access Control)和 DAC 完全相反——规则由系统定,用户没得选。每个主体和客体都有安全标签(如绝密、机密、秘密),只有标签匹配才能访问。我在做涉密系统时用过 SELinux 实现 MAC,效果确实安全,但配置之复杂让我掉了不少头发。
核心要点:
- 标签是静态的,运行期间几乎不会变。
- 禁止“向上读”和“向下写”,这是 BLP 模型的精髓。
- 适用于等级森严的组织结构。
RBAC:角色解耦,企业级的最佳拍档
RBAC(Role-Based Access Control)是目前应用最广的模型,没有之一。它的核心思想是:把权限赋予角色,再把角色赋予用户。这样一来,人事变动时只需调整角色绑定,不用一个个改权限。我记得在 2005 年做银行核心系统时,用的就是 RBAC,角色数设了 300 多个,管理起来还算轻松。
// 一个简化版的 RBAC 判断逻辑
function checkAccess(user, resource, action):
roles = getUserRoles(user) // 获取用户角色列表
for role in roles:
permissions = getRolePermissions(role) // 获取角色权限
if (resource, action) in permissions:
return true
return false
- 标准层级:RBAC0(基础)、RBAC1(角色继承)、RBAC2(约束)、RBAC3(完整模型)。
- 常见问题:角色爆炸。我见过一个 SaaS 系统,角色数超过 2000 个,最后不得不引入“角色组”来压缩。
- 建议:
- 角色数控制在 50 以内,超过就考虑分层或改用 ABAC。
- 务必支持“角色互斥”(比如一个人不能同时是审批者和财务)。
ABAC:属性驱动,动态时代的解药
ABAC(Attribute-Based Access Control)用主体属性 + 资源属性 + 环境属性组成一个布尔表达式,动态计算结果。举个例子:“经理级别以上的员工,在办公时间,可以查看本部门的财务报表”。这里面“经理级别”“办公时间”“本部门”全是属性。我在做云原生 SaaS 平台时,前端 API 网关就用 ABAC,规则引擎一天跑几百万次评估也没压力。
// ABAC 策略示例(伪策略语言)
PERMIT
WHEN user.department == resource.department
AND user.level >= 3
AND time.between("09:00", "18:00")
AND location.in_office == true
- 优势:粒度极细,支持上下文感知(时间、地点、设备)。
- 代价:策略编写和性能调优有门槛。我曾经调试一个复杂的 ABAC 策略,就因为属性取值顺序不对,结果花了三天才定位到。
- 适用场景:微服务、IoT、SaaS 多租户、数据脱敏等。
知识结构图:模型选择决策流
下面这张图是我自己画的一个选型决策流,帮你快速判断当前项目应该用哪种模型。别小看这个流程,我每次新项目启动都会走一遍,避免拍脑袋选错模型。
我个人习惯的选型原则:
- 如果系统有涉密或合规要求(如等保三级以上),MAC 是必选项,至少要在核心模块实施。
- 如果团队运维能力一般,优先选 RBAC + 少量 DAC 组合。
- 如果已经在做微服务或云原生,ABAC 几乎是必然趋势——别犹豫,直接上策略引擎。
写在最后:模型没有银弹
你仔细想想看,其实这四种模型对应的是不同年代和不同约束下的最优解。DAC 简单但危险,MAC 安全但笨重,RBAC 平衡但会膨胀,ABAC 灵活但复杂。没有哪个模型能一劳永逸。我曾经在同一个系统里混合使用 RBAC 和 ABAC:基础权限用角色管,细粒度和动态条件用属性管。效果好,但架构复杂度也上去了。
嗯,记住一件事:选模型之前,先搞清楚你的安全目标是什么、团队能力在哪里、业务变化有多快。这三条想明白了,模型自然就浮出来了。