4. 核心问题:权限冲突与审批流冲突

说实话,权限和审批流这两块东西,单独拎出来都不算难。但一旦把它们凑到一起,你就会发现——冲突就像影子一样甩不掉。我自己的经验是,很多团队在初期设计时只盯着「谁可以审批」这个表面问题,结果上线后才发现,权限和审批流各自的内核其实在打架。

4.1 当权限遇上审批:两种冲突的本质

先说权限冲突。它指的是用户或角色因为权限分配重叠、继承、或拒绝策略相互矛盾,导致无法确定用户最终拥有什么权限。比如用户A同时属于「财务经理」和「合规审查」两个角色,前者允许他审批报销单,后者却禁止他审批任何涉及自己的单子,你说他到底能不能批?

审批流冲突则更隐蔽。它发生在审批流程本身的节点逻辑与业务规则、角色权限产生矛盾的时候。举个例子:流程要求「部门经理审批后再由财务总监审批」,但部门经理的角色并没有查看报销明细的权限——这就是典型的审批流内部冲突。

我曾在项目里遇到过一个极端案例:一个请假审批流居然有7个节点,每个节点都做了独立的权限校验,结果某个组的组长在第三节点就被卡住了,因为他自己的角色在第二节点被降了权……嗯,最后他们花了两个星期才把整个流程理清楚。

4.2 常见冲突场景

冲突类型 典型表现 风险等级
自己审批自己 审批人的权限包含对自身单据的审批 高
角色权限覆盖 上级角色默认权限覆盖了下级角色的拒绝规则 高
审批人无查看权限 审批节点被分配了无数据查看角色的用户 中
多级权限不一致 不同审批节点要求不同的权限等级,但用户只有一个角色 中
动态角色变更冲突 审批进行中,审批人的角色被撤销,流程直接卡死 高
特别注意:自己审批自己往往不是设计错误,而是权限继承太灵活导致的。我曾经维护过一套系统,默认「部门经理」角色拥有部门内所有单据的审批权,但没排除自己的单据——结果某位经理给自己批了一天假,被审计抓了。

4.3 冲突检测与预判

别等到流程跑起来才去排查冲突。我建议在配置阶段就做这几步:

  1. 权限矩阵交叉检查:列出每个角色在审批流中的权限点(查看、审批、驳回、加签),标出重叠区域。
  2. 审批流模拟运行:用测试数据跑一遍完整流程,尤其关注角色切换和动态继承的点。
  3. 引入冲突规则引擎:把常见的冲突规则(如同人、同组、权限覆盖)写成可配置的表达式,在每次角色或流程变更时自动校验。
  4. 手动边界测试:针对「边界角色」(比如既有管理员又有普通员工身份的用户)单独做测试用例。

我曾经帮一个客户做审计前的自查,就用这套方法挖出来17个隐藏冲突——其中两个是直接可以让审批流死循环的。说白了,预判比事后补救重要得多。

4.4 解决思路与最佳实践

解决权限与审批流的冲突,不能只改一端。我个人的做法是遵循三条原则:

  • 分离权限与审批逻辑:审批流只定义「流程路径」,而不关心「谁有权限走这个路径」——权限校验交给独立的RBAC引擎。
  • 使用策略模式:对每一种冲突场景定义一条处理策略(如拒绝、降权、跳过、人工干预),流程引擎执行到冲突点时自动匹配。
  • 引入冲突仲裁机制:当两个规则同时成立且互相矛盾时,设置优先级或触发人工确认。
小技巧:我习惯在审批流节点上挂一个「冲突标签」,比如自批冲突、权限缺失冲突。这样在日志里一眼就能看出问题出在哪一层的哪个规则上。

再强调一次:不要试图在审批流中写死权限判断。那会让后续的维护变得极其痛苦,改一个角色就要改一遍所有流程。把权限和审批流解耦——这算是我踩过最深的一个坑之后换来的教训。

下面是这一节的核心知识结构图,帮你快速理清两种冲突的关系和应对路径:

权限冲突与审批流冲突关系图 RBAC 权限域 角色分配与继承 权限规则(允许/拒绝) 动态角色变更 审批流域 审批节点定义 审批人分配 流程路径与规则 冲突点 自己审批自己 权限覆盖 解决策略:解耦 + 策略模式 + 冲突仲裁