openApiService = $openApiService; } /** * 处理请求 * * @param Request $request * @param Closure $next * @param string $requiredScope 必需的权限范围 * @return mixed */ public function handle(Request $request, Closure $next, string $requiredScope) { // 获取应用信息 $app = $this->getAppFromRequest($request); if (!$app) { return $this->forbiddenResponse('应用信息不存在'); } // 检查权限范围 if (!$this->checkScope($app, $requiredScope)) { return $this->forbiddenResponse("缺少必需的权限范围: {$requiredScope}"); } // 记录权限检查日志 $this->logScopeCheck($app, $requiredScope, $request); return $next($request); } /** * 从请求中获取应用信息 * * @param Request $request * @return OpenApiApp|null */ protected function getAppFromRequest(Request $request): ?OpenApiApp { // 从请求属性中获取应用信息(由认证中间件设置) return $request->attributes->get('openapi_app'); } /** * 检查权限范围 * * @param OpenApiApp $app * @param string $requiredScope * @return bool */ protected function checkScope(OpenApiApp $app, string $requiredScope): bool { // 获取应用的权限范围 $appScopes = $app->scopes ?? []; // 如果应用没有配置权限范围,拒绝访问 if (empty($appScopes)) { return false; } // 检查是否有管理员权限(拥有所有权限) if (in_array('ADMIN', $appScopes)) { return true; } // 检查是否直接拥有所需权限 if (in_array($requiredScope, $appScopes)) { return true; } // 检查权限依赖关系 return $this->checkScopeDependencies($appScopes, $requiredScope); } /** * 检查权限依赖关系 * * @param array $appScopes 应用拥有的权限 * @param string $requiredScope 需要的权限 * @return bool */ protected function checkScopeDependencies(array $appScopes, string $requiredScope): bool { // 获取权限枚举实例 $scopeEnum = SCOPE_TYPE::tryFrom($requiredScope); if (!$scopeEnum) { return false; } // 检查权限依赖 $dependencies = $scopeEnum->getDependencies(); foreach ($dependencies as $dependency) { if (in_array($dependency, $appScopes)) { return true; } } // 检查权限继承(如果有写权限,通常也有读权限) if (str_ends_with($requiredScope, '_READ')) { $writeScope = str_replace('_READ', '_WRITE', $requiredScope); if (in_array($writeScope, $appScopes)) { return true; } } return false; } /** * 记录权限检查日志 * * @param OpenApiApp $app * @param string $requiredScope * @param Request $request * @return void */ protected function logScopeCheck(OpenApiApp $app, string $requiredScope, Request $request): void { Log::info("Scope check passed", [ 'app_id' => $app->app_id, 'required_scope' => $requiredScope, 'app_scopes' => $app->scopes, 'uri' => $request->getRequestUri(), 'method' => $request->getMethod(), 'ip' => $request->ip(), ]); } /** * 返回权限不足响应 * * @param string $message * @return \Illuminate\Http\JsonResponse */ protected function forbiddenResponse(string $message) { return response()->json([ 'error' => 'insufficient_scope', 'message' => $message, 'required_scopes' => func_get_args()[1] ?? null, ], 403); } }