---
schema: "hl-changelog/v2"
ticket: "5626"
title: "fleet管理端接口角色权限收紧（非车务角色403拦截）"
consumer: "admin"
author: "wx(GIT)"
change_type: "修改接口"
backend_status: "deployed"
gateway_status: "verified"
frontend_status: "not_required"
frontend_owner: ""
frontend_ref: ""
target_release: ""
verified_at: ""
status_note: "后端完成：PR #5628 已合并 dev-v3 并部署 TEST（hl-gateway 双实例），网关验证通过（CUSTOMIZER/ROOM_MANAGER 调 fleet 写接口 code=403，VEHICLE_MANAGER 正常放行，只读车型列表排除路径不受影响）。无请求/响应契约变化，仅权限行为收紧。"
updated_at: "2026-08-06"
base: "dev-v3"
generated: "2026-08-06T23:30:00+08:00"
---

# fleet 管理端接口角色权限收紧（非车务角色 403 拦截）

> 后端完成：PR #5628 已合并 dev-v3 并部署 TEST，网关验证通过。

## 关联 / 联系人

### 链接

- **Issue**: [#5626](https://git.1814.love:8443/wx/HL/issues/5626)
- **PR**: [#5628](https://git.1814.love:8443/wx/HL/pulls/5628)
- **Merge commit**: [b08f1b953](https://git.1814.love:8443/wx/HL/commit/b08f1b953)

### 联系人

- **后端负责人**: @wx

## 背景

P0 安全缺陷：定制师（CUSTOMIZER）等非车务角色可调用车务管理员写接口（实测成功删除司机、调用派单接口透到业务校验）。服务层已有 `FleetAdminRoleGuardInterceptor`（/admin/fleet/** 仅 VEHICLE_MANAGER/SUPER_ADMIN），但网关层缺少角色路由校验，两层防线缺一层。

## 方案

**网关层补角色门禁，与服务层同口径双保险**：

1. `JwtAuthFilter` ADMIN 分支对 `/admin/fleet/**` 做角色门禁——仅 **VEHICLE_MANAGER / SUPER_ADMIN** 放行，其余角色（CUSTOMIZER/ROOM_MANAGER/OPERATOR/MATERIAL_ADMIN/CUSTOMER_SERVICE/ADMIN 等）一律返回 `code=403 无权限访问车务管理，请切换到车务角色`，不透到业务校验
2. 排除路径与服务层拦截器对齐：`GET /admin/fleet/vehicle-types/list`（订单域只读车型大类列表）任意 admin 角色可读，避免误伤订单用车需求消费
3. 防绕过：服务发现前缀（`/hl-fleet-service/...`）与 matrix 参数路径均不能绕过门禁
4. 多角色账号必须先切换到车务角色（`/admin/auth/switch-role`）才能调用车务接口

## 变更接口

| 方法 | 路径 | 服务 | 说明 |
|---|---|---|---|
| 全部 | `/admin/fleet/**`（排除 `GET /admin/fleet/vehicle-types/list`） | hl-gateway + hl-fleet-service | 角色门禁：仅 VEHICLE_MANAGER/SUPER_ADMIN 可访问，非车务角色 `code=403` |

**无请求/响应契约变化**——仅权限行为收紧：非车务角色从「可调用并执行」变为「403 无权限」，车务角色行为不变。涉及写接口示例：`DELETE /admin/fleet/drivers/{driverId}`、`POST /admin/fleet/assignments/batch`、`POST /admin/fleet/vehicles`、`POST /admin/fleet/vehicles/{id}` 等全部 `/admin/fleet/**` 管理接口。

## 行为变化

- 前端管理后台中，**CUSTOMIZER 等非车务角色**访问 fleet 管理功能将收到 `code=403`「无权限访问车务管理，请切换到车务角色」（Result 协议统一错误体，HTTP 200 + code=403）
- **VEHICLE_MANAGER / SUPER_ADMIN** 行为完全不变
- 多角色账号（如 wx 同时持有 CUSTOMIZER+VEHICLE_MANAGER）需先切换角色为车务管理员再操作车务功能
- 服务层 `FleetAdminRoleGuardInterceptor` 维持既有拦截（网关拦截后请求通常到不了服务层，两层均返回同一 403 语义）

## 前端/调用方动作

无需改动（Result 协议统一处理 403；车务功能仅车务角色可见）。若前端存在「定制师视角展示车务入口」的情况，建议按 403 隐藏/禁用入口（可选优化，不阻塞后端验收）。

## 验证证据

- **测试**：网关 JwtAuthFilterTest 26/26（新增多角色越权矩阵 14 例：CUSTOMIZER/ROOM_MANAGER/OPERATOR/MATERIAL_ADMIN/CUSTOMER_SERVICE/ADMIN/SALES/DESIGNER/unknown-role → 403；VEHICLE_MANAGER/SUPER_ADMIN → 放行；排除路径放行；服务发现前缀/matrix 参数防绕过）、JwtAuthFilterGrasslandGuideTest 38/38、TraceIdFilterTest 3/3；fleet FleetAdminRoleGuardInterceptorTest 16/16（新增非车务角色参数化矩阵）；fleet 全量 verify 3240 例仅 ReleaseE 8033 环境基线失败（干净基线同表现）；gateway 全量仅 CrossSchemaMigrationAuditTest 基线失败（#5435 引入，与本次无关）；fleet spotless:check 通过
- **部署**：hl-gateway 双实例 UP（23:13-23:14 滚动部署）
- **网关验证**：CUSTOMIZER 删司机/派单/建车辆 → `code=403 无权限访问车务管理`；ROOM_MANAGER 删司机 → 403；VEHICLE_MANAGER 删司机 → 透到业务层（600205 司机不存在，不误伤）；CUSTOMIZER `GET /admin/fleet/vehicle-types/list` → 200 放行
