ThinkPHP6不内置ABAC,需手动实现AbacEvaluator类,通过提取subject、resource、action、environment四类属性,匹配数据库策略并执行表达式求值,最终在中间件中调用决策。

ThinkPHP6 本身不支持基于属性的访问控制(ABAC),它只内置了 RBAC(基于角色)和简单 ACL(基于资源+用户 ID)的能力。要实现 ABAC,必须手动构建整套逻辑,不能靠 Auth::check() 或中间件自动完成。
ABAC 的核心是运行时评估四类属性:主体(subject)、资源(resource)、操作(action)、环境(environment),然后匹配策略规则并返回允许/拒绝。TP6 没有 AbacPolicy 类、没有 AbacMiddleware,也没有现成的策略解析器。
你需要自己实现一个 AbacEvaluator 类,包含三个关键环节:
-
属性提取
立即学习“PHP免费学习笔记(深入)”;
- 主体:从
$request->getAttribute('user')获取当前用户,并提取其部门、职级、标签、所属组织等字段 - 资源:根据路由或请求参数识别目标资源,比如
/api/posts/123→Post[id=123],再查数据库补全category=tech, author_id=456, status=draft - 操作:取
$request->method()和路由名(如'post.update'),或自定义动作标识(如'edit_own_draft') - 环境:检查
date('H')、$request->ip()、$request->header('User-Agent')、是否 HTTPS 等
- 主体:从
-
策略匹配与表达式求值
- 策略存数据库或配置文件,每条含
id,effect(allow/deny),condition(如"user.department == 'finance' && resource.amount <= 50000") - 使用 PHP
eval()(需严格校验字符串安全性)或轻量表达式引擎(如symfony/expression-language)解析执行 - 注意布尔短路、空值处理、类型隐式转换风险
- 策略存数据库或配置文件,每条含
-
决策执行
- 多策略时按优先级或顺序遍历,首个
effect == 'allow'且条件为 true 则放行;若全不匹配或遇到 deny 且条件满足,则拒绝 - 在权限中间件中调用该评估器,例如:
$evaluator = new AbacEvaluator(); if (!$evaluator->evaluate($request)) { abort(403, 'Access denied by ABAC policy'); }
- 多策略时按优先级或顺序遍历,首个
策略不能写死在代码里,必须可动态增删改
建议用独立数据表存储策略,字段包括:policy_name, effect, subject_expr, resource_expr, action_expr, env_expr, priority, enabled。配合后台管理界面,让运维人员调整策略而无需发版。
ABAC 在 TP6 中不是“开启开关”,而是需要你亲手搭起属性管道、策略引擎和决策闸门。它灵活但成本高,适合对合规性、多维控制要求严的场景,比如金融系统审批流、多租户数据隔离、动态敏感字段脱敏等。



















