2、访问控制模型(上):自主访问控制(DAC)、强制访问控制(MAC)、基于角色的访问控制(RBAC)

聊到数据共享,绕不开一个核心问题:谁,能对什么资源,做什么操作。

这就是访问控制模型要解决的事。我做了这么多年权限系统,见过太多“一上来就写 if-else 判断角色”的项目,结果后期改得想哭。说白了,选对模型,比写对代码重要得多。

这一节我们先看三个最经典的模型:DAC、MAC、RBAC。它们就像权限世界的“三原色”,后面的模型基本都是它们的变体或组合。

2.1 自主访问控制(DAC)—— 最像现实世界的模型

DAC 的全称是 Discretionary Access Control。Discretionary 这个词,翻译过来就是“自主决定的”。

什么意思呢?资源的所有者说了算。

你创建了一个文件,你就是它的主人。你可以决定谁能读、谁能写、谁能删。就像你家的房子,你可以给朋友一把钥匙,也可以随时换锁。

核心特征:权限可以传递。A 给了 B 读权限,B 可以再把这个权限转给 C。

我在早期做企业内部文档系统时,就用的 DAC。每个文档的创建者可以手动添加协作者。听起来很灵活对吧?但问题很快就来了。

DAC 的典型场景

  • 文件系统权限:Linux 的 chmod、Windows 的 NTFS 权限,本质都是 DAC。
  • 社交网络:你发一条朋友圈,可以设置“仅好友可见”或“不给谁看”。
  • 云存储共享:Google Drive 或 OneDrive 里,你可以给某个文件生成一个分享链接。

DAC 的坑

我曾经在一个金融项目中看到,员工把机密报表的权限“分享”给了整个部门,理由是“方便协作”。结果呢?一个实习生不小心把文件发到了外部群。

这就是 DAC 最大的问题:权限太分散,控制权在终端用户手里。对于企业级数据安全来说,这简直是噩梦。

避坑指南:DAC 适合个人或小团队协作。一旦超过 50 人,或者涉及合规审计,我建议你慎重。我曾经见过一个 200 人的公司用 DAC 管权限,最后审计时根本说不清谁有什么权限。

2.2 强制访问控制(MAC)—— 系统说了算

如果说 DAC 是“民主”,那 MAC 就是“集权”。

在 MAC 模型里,用户不能决定谁能访问自己的资源。所有权限都由系统管理员根据一套全局规则来设定。用户只能被动接受。

MAC 的核心是标签(Label)。每个用户有一个安全级别,每个资源也有一个安全级别。系统根据这两个标签的对比,决定是否允许访问。

经典的 Bell-LaPadula 模型

这是 MAC 最著名的实现,主要用于军事和政府机构。它的规则很简单:

  • 不上读(No Read Up):低级别用户不能读高级别文件。
  • 不下写(No Write Down):高级别用户不能把内容写到低级别文件里。

你想想看,这其实就是为了防止信息从高密级流向低密级。我当年给一个军工单位做咨询时,他们的系统就是严格的 MAC。一个工程师只能看到自己密级范围内的图纸,哪怕他是项目负责人,也不能越级查看。

个人经验:MAC 的优点是安全等级极高,缺点是灵活性极差。我在项目中很少见到企业用纯 MAC,除非是涉密系统或金融核心交易系统。因为一旦标签定错,改起来非常麻烦。

MAC 的典型场景

  • 军事系统:绝密、机密、秘密、公开四级。
  • 操作系统强制策略:SELinux、AppArmor。
  • 数据库行级安全:某些数据库支持按行设置安全标签。

2.3 基于角色的访问控制(RBAC)—— 企业级的事实标准

好了,前面两个模型都有点极端。DAC 太自由,MAC 太死板。那有没有一个折中的方案?

有,就是 RBAC。这也是我工作中用得最多的模型。

RBAC 的核心思想是:不直接给用户赋权,而是给角色赋权,再把用户放进角色里。

举个例子:你公司有“财务专员”这个角色。这个角色可以“查看财务报表”和“录入凭证”。你把张三和李四都放进这个角色里,他们自动就有了这些权限。如果有一天公司规定财务专员不能再录入凭证了,你只需要改角色的权限,张三和李四的权限就跟着变了。

核心优势:权限管理从“用户维度”变成了“角色维度”。用户数量可能成千上万,但角色数量通常只有几十个。管理成本直线下降。

RBAC 的三个核心规则

  1. 角色继承:高级角色可以继承低级角色的权限。比如“财务经理”继承“财务专员”的所有权限,再加上“审批凭证”的权限。
  2. 职责分离:一个人不能同时拥有两个互斥的角色。比如“采购员”和“审批采购单”不能是同一个人,防止舞弊。
  3. 最小权限:角色只包含完成工作所必需的最小权限集合。

我记得有一次帮一家电商公司重构权限系统。他们之前用 DAC,每个运营人员都能手动给其他同事开权限,结果一个运营主管不小心把“删除商品”的权限给了一个实习生。那天晚上,首页商品被误删了 200 多个。后来我们改成 RBAC,定义了“运营专员”、“运营主管”、“运营经理”三个角色,权限边界一下子就清晰了。

RBAC 的典型实现

元素 说明 示例
用户(User) 系统的操作者 张三、李四
角色(Role) 权限的集合 财务专员、运维工程师
权限(Permission) 对资源的操作 读取订单、删除用户
会话(Session) 用户激活的角色 张三同时激活了“管理员”和“审计员”角色

代码示例:RBAC 核心判断逻辑

下面是一个简化版的 RBAC 权限检查函数。实际项目中会复杂得多,但核心逻辑就是这样:

// 伪代码:检查用户是否有某个权限
function checkPermission(userId, resource, action) {
    // 1. 获取用户的所有角色
    roles = getRolesByUserId(userId);
    
    // 2. 遍历角色,检查是否有权限
    for (role in roles) {
        permissions = getPermissionsByRole(role.id);
        for (perm in permissions) {
            if (perm.resource == resource && perm.action == action) {
                return true;
            }
        }
    }
    
    // 3. 如果所有角色都没有该权限,返回 false
    return false;
}

我建议:在实际项目中,不要每次都去数据库查角色和权限。把用户的角色和权限缓存到 Redis 里,性能会好很多。我曾经优化过一个系统,把权限查询从 200ms 降到了 5ms,就是靠缓存。

2.4 三种模型对比

为了让你看得更清楚,我把它们放在一起比一比:

维度 DAC MAC RBAC
控制主体 资源所有者 系统管理员 角色管理员
灵活性 高 低 中
安全性 低(易泄露) 高 中高
管理成本 高(用户多时) 高(标签维护) 低(角色复用)
适用场景 个人、小团队 军事、涉密系统 企业级应用

2.5 本章知识结构图

下面这张图帮你理清三个模型的核心逻辑:

访问控制模型对比图 三种经典访问控制模型 DAC 自主访问控制 MAC 强制访问控制 RBAC 基于角色控制 资源所有者决定权限 系统标签决定权限 角色决定权限 优点:灵活 缺点:权限易扩散 适合:个人/小团队 优点:安全性高 缺点:灵活性差 适合:涉密系统 优点:管理成本低 缺点:角色爆炸 适合:企业级应用 选型建议 小团队用 DAC,涉密用 MAC,企业级首选 RBAC

2.6 小结

嗯,这一节的内容就到这里。DAC、MAC、RBAC 这三个模型,你不需要死记硬背,关键是要理解它们的设计哲学:

  • DAC 信任用户,把权力下放。
  • MAC 信任系统,用规则锁死。
  • RBAC 信任角色,用抽象简化管理。