企业系统 RBAC 权限模型
"谁能看到工资列?"在成熟的系统里,这个问题的答案是一份报表,而不是一次会议。基于角色的访问控制(RBAC)——把用户归入角色、把权限授予角色——是标准答案,在组织架构长出獠牙之前一直美好。本文讲经典模型,以及它在真实企业里通常裂开的三个地方。
把经典模型做对
RBAC 分三层:用户获得角色;角色携带权限;权限命名对资源的动作——对"销售订单""工资报表"的"读""审批""删除"。两条规则保持它干净:权限绝不直接授予用户,只经由角色;权限要细粒度("审批销售订单")而非页面级("能进订单页面"),于是一个角色可以组合多个权限,而不必每页一个新角色。用户的权限恰好是其所有角色权限的并集——永不手工越权。
裂口一:角色爆炸
"华东销售经理""华西销售经理""试用期初级华东销售经理"——组织发明角色的速度超过 IT 建模的速度。解法是层级加约束:一小撮基础角色(销售、经理),叠加一个数据范围(华东、华西)而不是烘进角色名,再加互斥规则(同一用户不能同时是同流程的"申请人"与"审批人")。三种机制替代数百个近重复角色。
裂口二:数据范围是被遗忘的维度
"销售经理"只说了职能,哪些行呢?经理只看本区的订单,HR 只看本部门的工资。这就是数据范围,它以两种方式失败:逐条查询硬编码(脆弱、不一致),或只活在前端(直连 API 即可绕过)。正确的位置是在数据访问层统一施加的范围过滤,由用户角色属性推导,并像安全代码一样测试——因为它就是。
裂口三:校验落在错误的层
藏起按钮不是安全。每一层都必须校验:
- 界面层——藏起用户不能做的操作(体验好,安全为零)
- API 网关——拒绝未认证与未授权调用
- 服务层——校验该动作的具体权限
- 数据层——对每条查询施加数据范围过滤
任何一层缺失,其上各层都只是装饰。统一门户从同一角色模型渲染菜单,用户看见的就是他能做的。
审计与定期复核
没有复核的权限模型会悄悄腐烂。记录每一次授权、每一次角色变更、每一次"被拒后重试"的访问模式。每季度复核角色指派——人积角色如 lint,两个项目前那笔"临时"权限至今还在。角色变更要对接人事事件:调岗发生时旧角色应自动终止,而不是等谁想起来。
默认拒绝,例外留痕
对新的权限请求,默认答案应是否定的;要翻转,须留下书面的业务理由。例外授权要到期:给每个一次性访问设结束日期,由系统自动收回。多年下来,仅此一个习惯——默认拒绝、例外到期——对最小权限的贡献超过任何制度文档,因为它把权限增长从"不断累积"变成了"刻意且可复核的决定"。
结语
RBAC 要在企业现实里活下来,就要保持权限细粒度、把数据范围建模为一等维度、在每层落实校验、按日程复核。安全是报表而非会议,并不更没人情味——它只是唯一能扩展的那种。身份与权限定了,消费它们的系统——门户、文档、流程——都继承同一套保证。