3. 访问控制模型概述:DAC、MAC、RBAC、ABAC

说到访问控制,我刚开始接触那会儿,简直被各种缩写搞晕了。DAC、MAC、RBAC、ABAC……每个都长得差不多,但内核完全不同。你想想看,一个系统里谁说了算?是文件主人?是安全管理员?还是角色?或者是属性?

这四种模型,说白了就是回答了同一个问题:“凭什么让你访问这个资源?” 但回答方式天差地别。我花了大概两年时间,才真正理解什么时候该用哪个。别急,我一个一个给你拆开讲。

3.1 DAC:自主访问控制

DAC(Discretionary Access Control),全称“自主访问控制”。这是最古老、最直觉的模型。它的核心思想很简单:谁创建了数据,谁就有权决定谁能碰它。

你在 Linux 里用 chmod 755 file 改权限,就是在操作 DAC。文件属于你,你可以给任何人读、写、执行的权利。

  • 优点: 灵活、简单、用户上手快。我早期做小项目时就用它,根本不需要复杂配置。
  • 缺点: 安全性完全依赖人的判断。我曾经在一个项目里看到,普通员工把核心代码库设成了777。为什么?就因为他懒,想让同事省事。这一下,整个系统的防线就破了。
  • 典型应用: 个人电脑、普通文件系统(NTFS/EXT4)、类Unix系统的权限管理。
⚠️ 避坑指南: 我曾经处理过一个金融系统的审计,发现所有业务报表都用的DAC。一个普通文员,因为创建了报表,就顺手把权限开放给了所有部门的实习生。结果数据泄露了。DAC最大的坑就是——它管不住人,尤其管不住“好人办坏事”。

3.2 MAC:强制访问控制

如果说DAC是“兔子窝”,那MAC(Mandatory Access Control)就是“军事基地”。我最早接触MAC,是在一个涉密系统的项目里。那项目要求,一个员工的访问权限,不是他自己能决定的,也不是他领导能决定的,而是系统根据“国家安全等级”强制执行的。

MAC 的核心是标签。每个用户有个“安全级”,每个文件也有个“安全级”。比如:绝密 > 机密 > 秘密 > 公开。你只有机密级,就不能读绝密文件。这层逻辑,代码写死了,谁也无法绕过。

// 伪代码:MAC检查逻辑
if (user.security_level >= resource.security_level) {
    // 允许读取
} else {
    // 拒绝,即使你是管理员也无法降级
}
  • 优点: 安全性极高,不受人为错误影响。管理成本低,规则统一。
  • 缺点: 灵活性极差。我见过一个部门,因为系统MAC策略太死,导致正常业务审批流程卡住了一个月。调整策略需要层层审批,太痛苦了。
  • 典型应用: SELinux、军事/政府系统、多级安全数据库。

3.3 RBAC:基于角色的访问控制

DAC太乱,MAC太死。怎么办?RBAC(Role-Based Access Control)来了。

我记得当年在做一个银行核心系统时,大家都在争论权限怎么设计。有人提出“按人配”,有人提出“按部门配”。最后我们用了RBAC,按角色配。你想想,一个银行有柜员、客户经理、风控经理、行长。这些角色是固定的,而具体谁担任何职,人事变动而已。我把权限给角色,再把角色给人。

角色 可读 可写 可审批 可管理用户
普通员工 ✅ ❌ ❌ ❌
部门主管 ✅ ✅ ✅ ❌
HR经理 ✅ ✅ ❌ ✅

这个模型的好处是,管理效率极高。新人入职,只需关联一个角色,所有权限自动到位。离职也一样,撤销角色即可。

  • 优点: 权限与用户解耦,管理成本低,适合中大企业。
  • 缺点: 角色数量爆炸。我见过一个项目,角色从50个膨胀到500个。为什么?因为业务场景太多,角色太粗不精确,太细则没法维护。
  • 典型应用: 企业ERP、CRM、银行核心系统、大型网站后台。
💡 我的习惯: 做RBAC设计时,我建议先把业务梳理清楚。别一开始就试图覆盖所有边界情况。设定核心角色(不超过10个),再通过“角色继承”解决特殊场景。不要让角色数量超过用户数量的5%。

3.4 ABAC:基于属性的访问控制

现在,我们来到最灵活、最精细的模型——ABAC(Attribute-Based Access Control)。

你想想,RBAC的问题在哪?它只能判断“你是谁”,不能判断“你在哪、什么时间、用什么设备”。比如,一个员工是“财务主管”的角色,白天在公司可以用系统,晚上在家就不能。这个“晚上在家”的信息,RBAC处理不了。

ABAC引入了属性。属性可以是任何东西:用户属性(部门、职级、所在地)、环境属性(时间、IP地点、设备类型)、资源属性(文件密级、创建日期)。权限判断不再是“是/否”,而是“如果条件满足,就允许”。

// ABAC策略示例(XACML风格)
Rule: "允许财务主管在办公时间访问财务系统"
条件:
    user.role == "财务主管"
    AND environment.time >= "09:00" AND environment.time <= "18:00"
    AND resource.name == "财务系统"
  • 优点: 极细粒度,动态决策,支持复杂的上下文逻辑。我曾在某个跨国项目中用它实现“同一个用户,在各自国家只允许访问本国子公司数据”——一组属性规则解决一切。
  • 缺点: 设计复杂,策略冲突风险,性能开销大。我曾经见过一个ABAC系统,规则多达3000条,每次请求都要遍历所有规则,响应时间直接飙到1秒以上。优化后采用了策略索引,才降到50ms。
  • 典型应用: 云平台(AWS IAM、Azure RBAC的扩展)、微服务网关、数据湖精细权限。

3.5 四个模型的对比与选择

好了,四个模型讲完了。你怎么选?我个人的经验是这样的:

场景 推荐模型 为什么
个人开发/小团队 DAC 简单,够用,别想复杂了
金融/政府核心系统 MAC 安全是第一位的,强制等级无法绕过
企业ERP/OA/CRM RBAC 角色明确,管理效率高
多云/微服务/数据湖 ABAC 需要结合环境、时间、来源等上下文
超大规模(10万+用户) RBAC + ABAC 我建议采用混合模式:角色粗粒度,属性细粒度

这里我得提醒一下,很多新手容易犯一个错误:试图用一个模型解决所有问题。我曾经在项目中坚持只用纯ABAC,结果策略写成了天书,维护成本高得吓人。后来规规矩矩切回“RBAC+ABAC”组合,反而更优雅。

另外,实际系统的访问控制,很少是单一模型的。比如AWS IAM,底层是ABAC(用标签和条件),但用户层面上又提供了RBAC的体验(托管角色)。这就是工程上的折中。

💡 个人经验: 在做新系统的访问控制设计时,先别急着选模型。花一天时间画出系统的所有访问场景(高峰时段、敏感数据、外部接口、审计需求)。场景画完了,模型自然就浮出水面了。模型是工具,场景才是老师。
访问控制模型演化与对比 DAC 自主:谁创建谁管理 优点:简单灵活 风险:权限失控 MAC 强制:标签定生死 优点:极强安全 风险:僵化难调 RBAC 角色:把人分组 优点:管理高效 风险:角色膨胀 ABAC 属性:上下文决策 优点:极细粒度 风险:性能开销 如何选择? 小团队/个人 → DAC | 高安全场景 → MAC | 企业组织 → RBAC | 复杂上下文 → ABAC 实际生产环境中,80% 的系统采用 RBAC + ABAC 混合模型,兼顾效率与精细度 模型演进方向:从离散管理到统一策略,从静态到动态 DAC → MAC → RBAC → ABAC (灵活性与安全性逐步提升,复杂度也随之增长)