权限模型概述:从“谁能用”到“怎么用”的进化

权限模型这个事,说白了就是回答三个问题:谁?能干什么?在哪儿干? 我做了十几年安全架构,见过太多项目在权限设计上翻车。有的模型太死板,业务灵活了它就卡壳;有的又太自由,最后权限膨胀到谁也管不住。嗯,这一章我们就来聊聊权限模型是怎么演进的,以及今天主流的四种模型到底该怎么选。

权限模型的发展历程

我最早接触权限系统是在一个金融项目中,当时用的是最古老的方式——直接在代码里写死用户列表。你想想看,那会改一次权限就要重新编译部署,简直是噩梦。后来慢慢有了成熟的模型,我大致把这段历史分成四个阶段:

  • 第一阶段(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 模型的精髓。
  • 适用于等级森严的组织结构。
注意:MAC 的运维成本很高。我见过一个团队花了两周配置策略,结果上线第一天就把数据库写权限配错了。如果团队没有专职安全运维,慎用 MAC。

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(强制访问控制) 资源/用户超过 50? DAC(自主访问控制) 需要动态规则? RBAC(基于角色) ABAC(基于属性) 💡 决策提醒 • 安全要求高 → 优先考虑 MAC,但必须有专人维护。 • 用户/资源量大 + 环境变化快 → ABAC 是更好的选择。 • 中小团队/传统应用 → RBAC 依然是性价比最高的模型。

我个人习惯的选型原则:

  • 如果系统有涉密或合规要求(如等保三级以上),MAC 是必选项,至少要在核心模块实施。
  • 如果团队运维能力一般,优先选 RBAC + 少量 DAC 组合。
  • 如果已经在做微服务或云原生,ABAC 几乎是必然趋势——别犹豫,直接上策略引擎。

写在最后:模型没有银弹

你仔细想想看,其实这四种模型对应的是不同年代和不同约束下的最优解。DAC 简单但危险,MAC 安全但笨重,RBAC 平衡但会膨胀,ABAC 灵活但复杂。没有哪个模型能一劳永逸。我曾经在同一个系统里混合使用 RBAC 和 ABAC:基础权限用角色管,细粒度和动态条件用属性管。效果好,但架构复杂度也上去了。

嗯,记住一件事:选模型之前,先搞清楚你的安全目标是什么、团队能力在哪里、业务变化有多快。这三条想明白了,模型自然就浮出来了。