3. 授权模型:RBAC、ABAC、PBAC 详解与选型策略

授权模型这东西,说白了就是「谁在什么条件下能干什么事」。我在接口适配项目里踩过不少坑,最惨的一次是权限模型没选对,导致后期改了整整两周的适配层代码。今天我把三种主流模型掰开揉碎讲清楚,顺便聊聊在接口适配场景下该怎么选。

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

RBAC 是最经典的授权模型。它的核心思路很简单:把权限打包成角色,再把角色分配给用户。

核心公式:用户 → 角色 → 权限

举个例子。一个电商系统的接口适配层,可能有这些角色:

  • 普通用户:只能查自己的订单、修改个人信息
  • 客服:可以查所有用户的订单,但不能改价格
  • 运营:可以管理商品上下架、设置促销活动
  • 管理员:啥都能干

在接口适配中,RBAC 的实现通常长这样:

// 接口适配层的 RBAC 校验示例
public class RbacAuthorizationFilter implements GatewayFilter {
    
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        // 1. 从 token 中提取用户角色
        String role = extractRole(exchange.getRequest());
        
        // 2. 获取当前请求路径对应的权限标识
        String permission = getPermissionByPath(exchange.getRequest().getURI().getPath());
        
        // 3. 校验角色是否拥有该权限
        if (!hasPermission(role, permission)) {
            return Mono.error(new AuthorizationException("权限不足"));
        }
        
        return chain.filter(exchange);
    }
    
    private boolean hasPermission(String role, String permission) {
        // 实际项目中这里会查 Redis 或本地缓存
        Map<String, Set<String>> rolePermissions = loadRolePermissions();
        return rolePermissions.getOrDefault(role, Collections.emptySet())
                             .contains(permission);
    }
}

我的经验:RBAC 最适合角色相对稳定的场景。我在一个内部管理系统里用过,角色不超过 20 个,权限配置一目了然。但如果你有几千个用户,每个用户都需要定制权限,RBAC 就会变得很痛苦——角色会膨胀到难以管理。

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

ABAC 比 RBAC 灵活得多。它不看「你是什么角色」,而是看「你、资源、环境都有什么属性」。

ABAC 的决策公式是:

允许访问 = 主体属性 AND 资源属性 AND 环境属性 AND 操作类型

举个例子。在接口适配层,一个 ABAC 策略可能是这样:

  • 主体属性:用户部门 = "销售部",职级 >= "P7"
  • 资源属性:数据敏感级别 = "机密"
  • 环境属性:访问时间 = "工作时间",IP 段 = "内网"
  • 操作类型:查询

只有同时满足以上所有条件,才允许访问。

ABAC 的策略引擎实现起来会复杂一些:

// ABAC 策略评估伪代码
public class AbacPolicyEngine {
    
    public boolean evaluate(Subject subject, Resource resource, Action action, Environment env) {
        // 加载所有匹配的策略
        List<Policy> policies = loadPolicies(subject, resource, action);
        
        for (Policy policy : policies) {
            // 逐一评估策略中的条件
            boolean subjectMatch = matchSubject(policy.getSubjectRules(), subject);
            boolean resourceMatch = matchResource(policy.getResourceRules(), resource);
            boolean envMatch = matchEnvironment(policy.getEnvironmentRules(), env);
            
            if (subjectMatch && resourceMatch && envMatch) {
                return policy.getEffect() == Effect.ALLOW;
            }
        }
        
        return false; // 默认拒绝
    }
}

我曾经踩过的坑:ABAC 虽然灵活,但策略数量一多,性能就会急剧下降。有一次我在接口适配层用了 ABAC,结果每次请求都要评估 50 多条策略,接口响应时间从 5ms 飙升到 200ms。后来加了策略缓存和预编译,才把性能拉回来。

3.3 PBAC:基于策略的访问控制

PBAC 可以理解为 ABAC 的升级版。它把授权逻辑完全抽象成「策略」,策略可以动态加载、热更新,甚至支持策略的组合与优先级。

PBAC 的核心特点是:

  • 策略与代码分离:策略写在配置文件或数据库中,不用改代码
  • 支持策略组合:允许多条策略叠加,按优先级裁决
  • 运行时热更新:策略变更后,不用重启服务

一个典型的 PBAC 策略配置:

{
  "policies": [
    {
      "id": "policy-001",
      "name": "销售部查看客户数据",
      "priority": 10,
      "effect": "allow",
      "conditions": {
        "subject.department": "sales",
        "resource.type": "customer_data",
        "resource.sensitivity": {"lte": "confidential"},
        "env.time": {"between": ["09:00", "18:00"]}
      }
    },
    {
      "id": "policy-002",
      "name": "全局拒绝夜间访问",
      "priority": 100,
      "effect": "deny",
      "conditions": {
        "env.time": {"between": ["22:00", "06:00"]}
      }
    }
  ]
}

注意:PBAC 的策略优先级很重要。上面的例子中,policy-002 优先级更高(100 > 10),所以即使销售部满足 policy-001 的条件,如果在夜间访问,最终结果还是拒绝。

3.4 三种模型对比

我把三种模型的核心差异整理成了表格,方便你对比:

维度 RBAC ABAC PBAC
粒度 粗粒度(角色级) 细粒度(属性级) 细粒度(策略级)
灵活性 低(角色固定) 高(属性组合) 极高(策略热更新)
性能 高(简单查表) 中(需评估条件) 中低(策略解析开销)
维护成本 低 中 高(需策略管理平台)
适用场景 角色稳定的内部系统 多维度权限控制 动态变化的复杂权限

3.5 接口适配中的选型策略

在接口适配场景下,选型不能只看模型本身,还得考虑适配层的特殊性。我个人习惯按这几个维度来决策:

  1. 接口数量:少于 50 个接口,RBAC 够用;超过 200 个,考虑 ABAC 或 PBAC
  2. 权限变化频率:每周变更少于 5 次,RBAC;频繁变更,上 PBAC
  3. 性能要求:要求 P99 延迟 < 10ms,优先 RBAC;可以接受 50ms 以内,ABAC 或 PBAC
  4. 团队规模:小团队(< 10 人),RBAC 最省心;大团队需要权限管理平台,PBAC 更合适

我的建议:如果你刚开始做接口适配,从 RBAC 起步准没错。等发现角色膨胀到难以维护时,再逐步引入 ABAC 或 PBAC。别一上来就搞复杂的策略引擎——你想想看,万一策略写错了,整个适配层的权限就全乱了。

3.6 三种模型的选型决策流程

下面这张图是我在实际项目中总结的选型决策流程,帮你快速判断该用哪种模型:

授权模型选型决策流程图 授权模型选型决策流程 开始选型 接口数量 < 50? 是 否 RBAC 权限变化频繁? 是 否 PBAC P99 < 10ms? 是 否 RBAC(性能优先) ABAC 确定授权模型 提示:实际选型还需考虑团队规模、现有基础设施、合规要求等因素

3.7 避坑指南

最后分享几个我亲身踩过的坑:

我曾经犯过的错:

  • 角色膨胀:在一个 CRM 系统里,我一开始只设计了 5 个角色,半年后膨胀到 47 个。每个角色对应一组权限,维护起来简直噩梦。后来重构时引入了 ABAC,用部门+职级+数据范围三个属性替代了 40 多个角色。
  • 策略冲突:PBAC 的策略多了以后,很容易出现「允许」和「拒绝」同时匹配的情况。我后来强制要求每条策略必须有优先级,并且默认拒绝,才解决了这个问题。
  • 性能陷阱:ABAC 在接口适配层做权限校验时,如果每次请求都去数据库查策略,性能会非常差。我的解决方案是:策略预加载到本地缓存 + 策略表达式预编译 + 热点策略走硬编码。

嗯,授权模型这块就讲这么多。记住一句话:没有最好的模型,只有最适合你场景的模型。RBAC 简单可靠,ABAC 灵活强大,PBAC 动态可控——选哪个,取决于你的接口适配层到底需要多细的权限控制。