访问控制与RBAC0:从DAC到ABAC,一套权限模型选型指南

发布时间:2026/10/18 17:24:51
访问控制与RBAC0:从DAC到ABAC,一套权限模型选型指南
简介这是面向网络安全与Java Web开发者的RBAC0访问控制实践资源将访问控制理论中的主体、客体、操作三要素落地为具体代码内容围绕基于角色的访问控制模型展开详解用户、角色、权限三个核心组件以及权限被赋予角色、用户通过扮演角色获取权限的核心逻辑同时呈现固定角色、分离职责、委派管理、非侵入性等特性。源码实现覆盖角色管理、用户管理、权限管理及访问控制决策模块决策模块会在用户操作前依据角色校验权限从数据库表设计到JSP前端均有完整对应可直接对照学习。压缩包共671个文件大小59.74MB以Java源码、JSP页面、class编译文件、jar依赖库和XML/Properties配置为主辅以SQL脚本、CSS/JS及图片资源构成一套完整Web项目。借助UserExample、ItemsExample等类可快速定位用户、商品等业务对象的权限校验逻辑适合为网络服务、企业信息系统、云计算平台等项目引入RBAC模型的开发者亦可作为毕业设计参考。已有187人学习浏览值得安全开发与权限设计方向的学生、工程师系统研读。1. 访问控制到底是什么门卫、门禁卡和一张看不见的规则表先说结论访问控制就是一套“谁能进、能进到哪一层、能做什么操作”的规则。想想办公楼的门禁系统保安不会让所有人进同一个门也不会让进了门的人随便进所有房间能进研发区的人未必进得了财务室能把档案柜里的文件拿出来的人未必能往里放新文件。这套规则搬到计算机世界里就叫访问控制。通俗地说访问控制是系统在每一次资源请求面前扮演“门卫”的机制先确认请求者是谁再查规则表最后给出允许或拒绝。它管的不只是网络入口还有文件、数据库记录、接口调用这些最角落的资源。网络安全里经常被挂在嘴边的“权限管理”底层就是在做访问控制。很多人第一次接触它是想搞懂 RBAC0 这个高频词——访问控制模型里最常用、最容易上手的一种后面我会专门用一章来讲。这份“访问控制理论与策略.zip”正是围绕整套访问控制知识整理的资料看完这篇你至少能分清它到底在讲什么。2. 为什么系统离不开访问控制安全三要素和四个核心概念曾有某公司把文件服务器所有目录设成“所有人可读写”结果一个实习生把测试环境的脚本同步到生产目录覆盖了线上配置整套服务重启失败。整个过程没有一个黑客参与损失却不亚于一次攻击。访问控制看似是个“听起来很基础”的词但它恰恰是防止这类事故的第一道闸门——没有它内鬼、误操作和高危漏洞会一起爆发。2.1 安全三要素机密性、完整性和可用性访问控制一次扛两件业内把安全目标浓缩成三个词机密性、完整性、可用性。机密性要求只有被授权的人才能读取某份数据访问控制用限制“读”权限来实现完整性要求数据不能被未授权的人修改访问控制用限制“写”和“执行”来实现可用性虽然更多和抗攻击、容灾挂钩但一个权限全开、人人可改的系统一旦发生误删误改服务照样不可用。访问控制不是“合规装饰”它是把机密性和完整性从口号变成可执行规则的双手。打个比方大楼的消防通道门如果任何人都能打开“闲人免进”的区域就等于不存在保险柜如果任何人拧一下把手就能开那保险的意义就只剩心理安慰。很多人做系统时总把精力放在加密算法、防火墙规则上却忽略了一个事实再强的加密也防不住一个拥有正当身份、却不该看这份数据的人而访问控制正是挡住这种人的那扇门。访问控制背后还有一个贯穿始终的原则最小权限原则。意思是每个主体只拥有完成自己工作所必需的最少权限不多给一分。权限给少了工作做不了权限给多了一旦这个账号被盗或操作失误损失范围就会被无限放大。判断一个权限设计好不好先问一句话“这个角色真的需要这个操作吗少了它行不行”这一步听起来简单却是所有后续模型要解决的核心矛盾。2.2 四个核心概念主体、客体、权限、引用监控器要读懂任何访问控制模型先记四张牌。主体是发起访问的人、程序或服务进程比如登录用户“张三”、一个定时脚本客体是被访问的资源比如文件、数据库里的某一行、某个接口权限是允许对客体做的操作最常见的是读、写、执行在数据库场景下会细化为增、删、改、查引用监控器是摆在所有访问请求之间的裁决点它必须做到不可绕过、总是被调用、自身不能被篡改。把这些概念放到办公楼里主体是员工客体是各层楼的门禁房间权限是门禁卡上定义的“能进哪几层、是只能看还是能改布局”引用监控器是前台那个每次都核对工牌的保安。一个系统无论采用什么模型本质都是“引用监控器拿着一张规则表对每一个主体的每一次请求做判断”。规则表本身就是授权策略也就是后面要讲的 DAC、MAC、RBAC、ABAC 这些模型的差别所在。除了放行和拒绝引用监控器通常还要做一件事留下审计日志。谁在什么时间、对哪个资源、做了哪个操作都得记下来否则出了问题连复盘都无从谈起。在很多安全审计里“有没有访问控制日志”本身就是合规项之一。所以看一个系统的访问控制做得好不好不能只看“登不登得进去”还要看“每一次请求有没有经过同一个裁决者、有没有留痕”。2.3 访问控制矩阵一张表看懂所有模型的血缘关系把“谁对什么有什么权限”画成一张二维表就是访问控制矩阵。假设系统有主体 A、B客体 file1、file2矩阵可能是这样主体客体file1file2A读、写读B读读、写、执行表格每个格子填的是主体对客体的权限。这张表一般不会整张存下来因为大部分格子是空的太稀疏。真正落地时有两种拆法按列存得到访问控制列表ACL挂在客体上文件系统里最常见按行存得到能力列表Capability List挂在主体上像一把钥匙串。这两种拆法在第 5 章会专门对比。访问控制矩阵更大的价值在于它是一个思考坐标系。DAC 让资源属主自己决定矩阵里的格子怎么填MAC 让系统按安全标签统一填格子属主无权改写RBAC 先把矩阵的行合并成角色再分配给用户ABAC 干脆不维护这张表每次请求时根据属性现算。看到任何一个权限模型先问三个问题谁来填这张表多久填一次用户能不能改自己的格子答案一对模型属于哪一类立刻清楚了。动手设计权限时建议先把主体、客体、操作列出来画一次矩阵再决定用哪种模型。很多权限翻车现场源头就是跳过了矩阵这一步直接在代码里写死 if 判断最后权限散落在各处连自己都说不清谁有什么权限。3. 四种主流访问控制模型DAC、MAC、RBAC、ABAC 分别在治什么病四种模型不是一条进化链不是越靠后越高级。它们是面对不同风险场景长出来的四种解法选错模型和不用模型一样致命。3.1 DAC资源属主说了算像把自己的门禁卡转借给别人DACDiscretionary Access Control自主访问控制的规则是资源的创建者也就是属主可以自行决定谁能访问它、拿到什么权限。你创建了一个文件就可以把读权限给同事、把写权限给合作方这是你“自主”的选择。Linux 文件系统里的 rwx 权限位就是最典型的 DAC属主想给谁开权限就 chmod 给谁。这个模型的好处是直观、灵活贴近人的直觉。但它的问题也很明显权限一旦发出去属主就难以控制后续的传播。你把一个文件读权限给了 AA 又转发给了 BB 再复制一份给别人你根本阻止不了。放到办公楼场景里等于你把门禁卡配了一把给别人别人自己再去配钥匙整栋楼的门禁系统对它毫无办法。所以 DAC 适合共享目录、个人文件这种低风险场景在安全要求高的核心系统里单独用它会非常危险。3.2 MAC系统标签说了算属主也改不了自己的格子MACMandatory Access Control强制访问控制是另一种极端。系统给每个主体和客体都打上安全标签比如“公开、内部、机密、绝密”标签之间定义了严格的层级关系访问决策不由资源属主做而由系统按标签统一裁决。属主想降密、想把自己的文件分享给低密级的人系统会直接拒绝。用办公楼比喻就是楼里每个房间的密级由上级统一制定保安只认标签不认人。就算你是一间办公室的主人也不能把一个机密房间的门禁权限放给一个内部级别的人这不是你能决定的事。MAC 的优点是抗内鬼、能防恶意程序扩散缺点是策略僵硬、配置复杂日常运维成本高。一个容易被忽略的事实是MAC 并不是要替代 DAC而是叠加在 DAC 之上做兜底。比如一个系统可以先有文件属主的 DAC 权限再由 MAC 标签做强制限制两层都通过才放行。理解这一点对后面看 RBAC 与它们的关系很有帮助。3.3 RBAC把权限统一塞进角色不再一个个给人授权RBACRole-Based Access Control基于角色的访问控制是今天企业系统里最常见的模型。它的核心做法是把一堆权限组成一个角色再把用户塞进这个角色里。用户不再直接和权限打交道而是和角色打交道。照进现实就是公司的人事结构公司不会给每个员工单独开权限而是定义“财务专员”“研发工程师”“运营助理”这些岗位新员工入职时分配一个岗位所有权限跟着岗位走离职时把岗位收回就行。RBAC 的好处也正在于此权限变更时不用逐个用户改改角色和权限的关联即可新用户上线、老用户转岗都只动一个关系表。RBAC 的局限在角色设计这一步。角色分得太粗权限会膨胀比如所有普通员工都能导出客户数据角色分得太细会出现角色爆炸一个 30 人的团队可能攒出 80 个角色管理成本比权限本身还高。3.4 ABAC属性动态计算像机场安检的多条件组合ABACAttribute-Based Access Control基于属性的访问控制不再提前给某个用户固定权限而是把主体属性、客体属性、环境条件组合成一条策略每次请求时现算。比如一条规则可以写成只有“部门财务”且“当前时间在 9:00-18:00”且“文件密级≤用户密级”的人才能读取这张报表。类比机场安检不是“持有某张卡就能过”而是“有登机牌 且 身份一致 且 没带违禁品 且 航班还没起飞”才放行。ABAC 适合属性变化快、规则组合多的场景比如项目进行中允许成员访问项目结项后立刻禁止又比如同一份文档在不同时间段开放给不同人群。优点是灵活、细粒度缺点是策略多了以后调试困难性能开销也大规则引擎一旦变成黑匣子排查起来非常费劲。3.5 四个模型一张表谁决策、什么时候用、代价是什么把四种模型放在一起对比模型决策者典型场景主要代价DAC资源属主个人文件、共享目录权限容易扩散MAC系统、安全标签涉密程度高的核心系统配置复杂、不灵活RBAC管理员、角色企业内部系统、管理后台角色设计需要持续治理ABAC策略引擎云平台、微服务网关规则调试和性能成本高这张表是理解访问控制最关键的一页不存在“哪种模型最好”只存在“哪种模型匹配当前风险”。如果每个用户自己管理文件权限就够了DAC 就能胜任如果数据泄露一次就完蛋MAC 更合适绝大多数业务系统在 RBAC 上就能跑得很好ABAC 只有当规则本身成为业务需求时才值得引入。4. RBAC0 是什么用户、角色、权限三层模型为什么够用RBAC 是一个家族业界标准按功能把它拆成 RBAC0 到 RBAC3 四个级别。RBAC0 是最核心的基础版本也是大多数入门资料和不少生产系统实际在用的版本。它把权限关系收敛成三层用户、角色、权限。4.1 三要素用户、角色、权限为什么中间必须隔一层角色RBAC0 的三个核心元素是用户、角色、权限。它最核心的一条约束是用户不能直接拥有权限权限必须先挂到角色上用户再被分配角色。用大白话说权限是能力角色是岗位用户是人人只有坐上岗位才能行使岗位对应的能力。为什么不直接给用户挂权限因为人数一旦多起来直接给人配权限就是灾难。假设系统里有 40 个用户、30 项权限每人按需配置光维护授权关系就要处理成百上千条记录把 30 项权限整理成“编辑”“审核”“管理员”三个角色后给用户分配角色的动作变成 40 条记录里的 3 种选择管理成本瞬间降下来。这也是最小权限原则能真正落地的原因角色把“谁需要什么”从用户维度转换成了岗位维度新增一个员工只需对应一个角色。用一个简单的数据库建表就能看清 RBAC0 的样子。以下是一份常见的 RBAC0 表结构-- 用户表存主体基本信息 CREATE TABLE users ( id INT PRIMARY KEY, name VARCHAR(64) NOT NULL ); -- 角色表角色是权限的容器 CREATE TABLE roles ( id INT PRIMARY KEY, role_name VARCHAR(64) NOT NULL UNIQUE ); -- 权限表一条权限 对某个资源的某种操作 CREATE TABLE permissions ( id INT PRIMARY KEY, resource VARCHAR(64) NOT NULL, -- 客体如 order、report action VARCHAR(16) NOT NULL -- 操作如 read、write、delete ); -- 用户与角色是多对多一个用户可以有多个角色 CREATE TABLE user_roles ( user_id INT NOT NULL, role_id INT NOT NULL, PRIMARY KEY (user_id, role_id) ); -- 角色与权限是多对多一个角色拥有多项权限 CREATE TABLE role_permissions ( role_id INT NOT NULL, permission_id INT NOT NULL, PRIMARY KEY (role_id, permission_id) );查询逻辑是反向操作的系统要判断“用户张三能否删除订单”先拿张三的 user_id 去 user_roles 表查出角色列表再拿这个角色列表到 role_permissions 表里找出所有关联的权限最后比对 permissions 表里是否存在资源为 order、操作为 delete 的记录。整个过程在 users 表里没有任何权限字段这就是用户、角色、权限三层解耦的查询路径。注意参数含义resource 是客体名action 是操作名建议统一用小写字符串存避免大小写不一致导致的权限判断翻车。表结构里还可以加扩展字段比如在 user_roles 表加 valid_until 做临时授权在 permissions 表加 department 做部门维度过滤但核心的“用户-角色-权限”三层关系不需要改动。这也是 RBAC0 生命力强的直接原因表结构足够简单扩展方向清晰团队再小也不会把它写歪。4.2 会话用户激活角色的临时通道权限的“并集”要看清RBAC0 里常被忽略但很关键的是会话Session。用户登录后系统建立一个会话在这个会话里用户激活一个或多个角色系统在判定时只认“当前会话激活的角色”不认“用户拥有的全部角色”。有效权限等于当前激活角色的权限并集。举例某员工同时拥有“编辑”和“审核员”两个角色但当前会话只激活了“编辑”系统就不能让他执行审核操作哪怕他确实有“审核员”这个角色。区分“拥有角色”和“激活角色”能避免很多权限边界上的血泪经验。曾经有一次线上权限事故就是开发者在代码里只判断了“用户是否拥有审核角色”却没有检查会话是否激活它结果一个只有编辑权限会话的用户也能进入审核页面最后花了很长时间定位。提示安全要求高的操作建议在用户进入前强制新建一个会话并只激活必要角色用完再关闭相当于给最小权限原则加一道运行时保险。实现层面会话表至少需要记录 user_id、激活的 role_id、创建时间、过期时间。激活角色时系统按 role_id 去取有效权限并写入会话后续请求不需要每次都连表查权限这也是 RBAC0 在性能上的友好之处。4.3 RBAC0 与 RBAC1/2/3为什么很多系统停在 RBAC0 就够了RBAC 家族四个级别差别在于功能堆叠程度。RBAC0 是基础版本只有用户、角色、权限三层模型RBAC1 加上角色继承比如“管理人员”自动继承“普通员工”的所有权限RBAC2 加上约束例如职责分离、互斥角色规定同一人不能同时拥有出纳和会计两个角色RBAC3 是继承和约束都加上。多数系统停在 RBAC0 的理由非常现实RBAC0 已能描述绝大多数管理后台需求多余的功能反而制造复杂度。角色继承听起来很美实际用起来会发现角色的层级关系一旦超过两层权限就变得难以推演——上级角色权限被改下级跟着变查一个权限问题要在角色树里翻很久像在黑匣子里猜。互斥角色则需要额外开发一套规则引擎否则只靠几张关联表根本约束不住工作量又是成倍增长。还有一层原因在于运维习惯很多团队一开始就照着 RBAC1 设计了角色继承半年后管理员被继承关系折磨得不行最终退回 RBAC0。RBAC0 不是低配它是把“用户-角色-权限”三层模型用到极致的做法当需求真正出现“角色应该自动继承上级权限”或“两个角色必须互斥”时再按需升级到 RBAC1 或 RBAC2 也不迟。5. 最容易混淆的四个概念认证与授权、DAC 与 MAC、ACL 与能力列表、权限与角色访问控制领域的“混乱”很大程度来自几组名称相近、日常语境里经常混用的词。把它们放在一起区分比死记模型定义更管用。5.1 认证 vs 授权 vs 访问控制登录成功不代表你可以为所欲为易混点很多人把“登录成功”当成“能访问系统里的一切”觉得账号密码验证过了剩下的就畅通无阻。为什么混登录和权限判断通常是同一套页面顺序完成的用户输完账号密码就点了进去很少能意识到中间其实隔着两个独立环节。怎么区分认证回答的是“你是谁”手段是密码、验证码、数字证书授权回答的是“你能干什么”输出是一组权限集合访问控制是授权规则在每一次请求上的执行机制外加日志记录。“登录成功”只完成了第一步第二步是系统根据你的身份查出你能访问哪些资源第三步才是按规则放行或拒绝。误把认证当授权就会犯“能登录等于什么都能干”的常识错误。5.2 DAC vs MAC资源属主说了算还是系统标签说了算易混点DAC 和 MAC 都有“AC”又都叫访问控制初学者很容易觉得它们是同一种思想的两个叫法。为什么混在一些实际系统里两者确实同时出现比如一个带强制标签的操作系统安全环境既有 DAC 的 rwx 权限位又有 MAC 的安全标签看起来更像是一回事。怎么区分看“资源属主能不能修改访问规则”。能改、能转让权限的是 DAC无论属主多愿意只要系统标签不允许就放行不了的是 MAC。DAC 是把决定权交给个人MAC 是把决定权收归系统。做安全评估时还有一个速记法DAC 防外行MAC 防内鬼。普通权限混乱用 DAC 修修补补核心高价值资源就要靠 MAC 兜底。5.3 ACL vs 能力列表看门人手里的名单 vs 你口袋里的钥匙串易混点ACL 和能力列表都来自访问控制矩阵都能实现“谁对谁有什么权限”常被当成同义词。为什么混矩阵太稀疏落地时要么按列存、要么按行存两种拆法看起来只是存储方式不同概念上却完全不同。怎么区分ACLAccess Control List挂在客体上回答“这份文件允许谁访问”文件系统的访问控制就是典型能力列表挂在主体上回答“我这张卡能打开哪些门”。用办公楼来说ACL 是每个房间门口贴着的一张“可进入人员表”能力列表是你手里的钥匙串上面串着你能打开的所有房间的钥匙。它们的核心取舍在撤销成本ACL 撤销方便把名单上的人划掉就行但要查询“某个用户所有权限”很慢能力列表查询单个用户权限非常快可钥匙一旦发出去要收回就很麻烦因为钥匙在用户手上。很多系统把两者配合使用粗粒度用 ACL细粒度用能力列表。对比项ACL能力列表挂在谁身上客体文件、资源主体用户、进程回答的问题这个资源谁能访问我能访问哪些资源撤销难易容易修改名单即可困难需要回收钥匙典型场景文件系统权限分布式系统的授权令牌5.4 权限与角色角色不是权限本身而是权限的容器易混点初学者很容易把“角色”和“权限”当成同一层概念觉得角色是权限的一对一拷贝给角色起名叫“管理员”就给管理员逐个加权限。为什么混角色的名字像职位职位听起来就是权限的别名而且权限和角色在很多系统界面上混在一起展示看不出层次。怎么区分角色是权限集合的一个命名容器它本身不包含业务能力能力全在权限上。权限变了角色自动带出变化同一组权限换一个角色名还能复用给不同部门。反例是某系统给每个用户单独配了“查看报表”权限结果报表字段一改需要逐个用户回收正例是定义“报表查看者”角色把“查看报表”挂上去新增员工只需分配角色。判断一个角色设计好不好可以看它的权限是否稳定如果一个角色的权限列表频繁改动说明该角色分得太粗或太细。管理者应该维护“角色-权限”关联而不是维护“用户-权限”关联否则 RBAC 就退化成了 DAC 的变体失去了角色这一层的杠杆作用。6. 什么时候该用哪种访问控制一次真实的权限翻车6.1 大部分内部系统先从 RBAC0 起步团队内部管理后台、内容系统、财务工具这类场景权限需求稳定、用户量不大RBAC0 是最稳的起点。它不会让你在模型上花太多心思表结构一清二楚出了问题也好查。这时候直接上 ABAC 或 MAC等于给自行车装航空发动机。6.2 高安全场景MAC 别想绕开涉及核心账务、敏感数据聚合、强监管要求的系统光靠 RBAC 不够必须引入强制标签做兜底。哪怕平时不常用这一层也要存在因为一旦出现“合法身份的越权读取”事后追责靠的就是这个标签体系。6.3 规则天天变ABAC 才有价值如果权限规则持续变化比如“项目进行中成员可以访问文档结项后关闭”用 RBAC 改写角色会非常痛苦。ABAC 的属性和条件组合能应对这类动态需求但规则数量一旦膨胀调试成本会迅速上升所以要配上策略测试环节。6.4 翻车现场给每个用户直接配权限的做法我在做一个模拟项目X时第一版图省事建了一张 user_permissions 表每个用户一行一行配权限。上线三个月新增一个菜单要手工给 40 个用户补权限有一次 SQL 更新错行把运营组长的删除权限误写在某员工名下过了两天才被发现。那次事故之后我每次做权限需求都强制先走一遍 RBAC0 的角色拆解先列岗位再列操作和资源最后画访问控制矩阵确认每个角色只拥有必要权限再考虑是否引入 ABAC。这份“访问控制理论与策略.zip”里整理的正是这一套从概念到策略选择的完整资料希望帮到你。本文还有配套的精品资源点击获取