From d6e995a954c7cdde3b6e30ca91e9bed19fcfbfff Mon Sep 17 00:00:00 2001 From: chenxing Date: Fri, 11 Sep 2026 09:58:12 +0800 Subject: [PATCH] =?UTF-8?q?fix(sysuser):=20=E7=BC=96=E8=BE=91=E7=94=A8?= =?UTF-8?q?=E6=88=B7=E6=8E=A5=E5=8F=A3=E8=AF=AF=E6=8A=9B=E3=80=8C=E7=BB=84?= =?UTF-8?q?ID=E4=B8=8D=E8=83=BD=E4=B8=BA=E7=A9=BA=E3=80=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit SysUserController.edit 无条件调用 requireGroupInScope(request.getGroupId()), 而该方法对 null 直接抛错;但 service.edit 不读 groupId、DTO 仅在 Create 校验、 前端编辑按契约不提交 groupId,导致每次编辑必崩。改为仅当 groupId 非空时才校验 其落在数据范围内,越权防线仍由 requireUserInScope(id) 承担。mvn test 102 全绿。 --- .../userbase/controller/api/SysUserController.java | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/yunhai/userbase/controller/api/SysUserController.java b/src/main/java/com/yunhai/userbase/controller/api/SysUserController.java index 84dd582..2286c9a 100644 --- a/src/main/java/com/yunhai/userbase/controller/api/SysUserController.java +++ b/src/main/java/com/yunhai/userbase/controller/api/SysUserController.java @@ -66,10 +66,15 @@ public class SysUserController { @OperationLog("编辑用户") @PostMapping("Edit/{id}") public void edit(@PathVariable Integer id, @RequestBody @Validated(ValidationGroups.Update.class) SysUserRequest request) { - // 关键防线:目标用户本身必须与数据范围有交集。request.groupId 只是前端上下文, - // 伪造 groupId(范围内任一组)+ 任意 id 可跨校改他人资料/重置密码(账号接管)。 + // 关键防线:目标用户本身必须与数据范围有交集。伪造任意 id 可跨校改他人资料/重置密码(账号接管), + // 由 requireUserInScope(id) 拦截——它与 request.groupId 无关,是编辑越权的唯一有效锚点。 accessScopeService.requireUserInScope(id); - accessScopeService.requireGroupInScope(request.getGroupId()); + // groupId 对编辑无业务语义(SysUserService.edit 不读取它,仅按 schoolId+roleIds 落身份), + // 且 DTO 与前端契约均声明「groupId 仅 Create 校验、编辑不提交」。故为空时不再拦截(修复「组ID不能为空」); + // 仅当前端确实带了组上下文时,才二次校验该组落在数据范围内,保留防御纵深。 + if (request.getGroupId() != null) { + accessScopeService.requireGroupInScope(request.getGroupId()); + } sysUserService.edit(id, request); }