From 176d146b8e41c2d6cb000fac3312e76fc35a8d8b Mon Sep 17 00:00:00 2001 From: ouyangxq <775153912@qq.com> Date: Tue, 1 Sep 2026 19:25:48 +0800 Subject: [PATCH] fix: preserve merchant warehouse authorities overseas --- auth/AGENTS.md | 2 +- .../java/com/baiyue/auth/service/OverseasTokenService.java | 1 + .../com/baiyue/auth/service/OverseasTokenServiceTest.java | 6 ++++-- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/auth/AGENTS.md b/auth/AGENTS.md index 59c7b03d3..6672fdf90 100644 --- a/auth/AGENTS.md +++ b/auth/AGENTS.md @@ -16,7 +16,7 @@ | 内部账号管理与 scope | `controller/InternalAccountController.java`、`service/AccountManagementService.java` | | 统一 JWT 签发与 JWKS | `config/AuthSecurityConfig.java`、`config/AuthSecurityProperties.java`、`service/AuthService.java`;Auth 是国内与海外仓共用的唯一用户 Token 签发方,JWKS 公钥发布按认证接口契约实现 | | 国内小 JWT 与会话 | `service/AuthService.java`、`service/TokenSessionStore.java`;浏览器登录 Token 只承载稳定身份、应用域和版本声明,国内服务结合 Redis 会话校验 | -| 海外访问 Token 签发 | `service/OverseasTokenService.java`;登录/刷新编排使用同一用户身份同时签发短时 RS256 海外 Token,限定海外 Audience,只保留平台海外仓/海外业务/海外主数据及 `lastleg:*` 权限前缀;前端统一认证层负责按区域 API 自动选择 | +| 海外访问 Token 签发 | `service/OverseasTokenService.java`;登录/刷新编排使用同一用户身份同时签发短时 RS256 海外 Token,限定海外 Audience,只保留平台海外仓/海外业务/海外主数据、客户海外仓 `merchant:warehouse:*` 及 `lastleg:*` 权限前缀;前端统一认证层负责按区域 API 自动选择 | | 海外 PDA 实时会话校验 | `controller/InternalAccountController.java`、`service/OverseasSessionValidationService.java`;只接受海外 Gateway 已验签后提取的 userId/tokenVersion/overseasWarehouseId,以内部服务令牌保护并实时联查 IAM 当前仓绑定 | | Token 会话与权限快照 | `service/TokenSessionStore.java`、`client/AuthorizationLoader.java`、`client/IamAuthorizationClient.java`;消费端映射见 `../common-security/src/main/java/com/baiyue/common/security/RedisAccessTokenSessionValidator.java`、`JwtClaimsMapper.java` | | 注册协作 | `service/MerchantRegistrationService.java` | diff --git a/auth/src/main/java/com/baiyue/auth/service/OverseasTokenService.java b/auth/src/main/java/com/baiyue/auth/service/OverseasTokenService.java index 4d274f63e..41a6eead3 100644 --- a/auth/src/main/java/com/baiyue/auth/service/OverseasTokenService.java +++ b/auth/src/main/java/com/baiyue/auth/service/OverseasTokenService.java @@ -31,6 +31,7 @@ public class OverseasTokenService { "platform:overseas-warehouse:", "platform:overseas-business:", "platform:overseas-master-data:", + "merchant:warehouse:", "lastleg:" ); diff --git a/auth/src/test/java/com/baiyue/auth/service/OverseasTokenServiceTest.java b/auth/src/test/java/com/baiyue/auth/service/OverseasTokenServiceTest.java index ad4f82bf0..1a49a0f5f 100644 --- a/auth/src/test/java/com/baiyue/auth/service/OverseasTokenServiceTest.java +++ b/auth/src/test/java/com/baiyue/auth/service/OverseasTokenServiceTest.java @@ -49,10 +49,12 @@ class OverseasTokenServiceTest { account.setId(42L); account.setAccountStatus("ACTIVE"); account.setDefaultTenantId(999L); account.setDefaultMembershipId(84L); account.setDefaultAppCode("MERCHANT"); String authority = "platform:overseas-master-data:quote:list"; + String merchantAuthority = "merchant:warehouse:delivery:list"; String lastlegAuthority = "lastleg:pda:operate"; String domesticAuthority = "platform:firstleg:order:list"; AuthorizationSnapshot snapshot = new AuthorizationSnapshot(42L, 0L, 84L, "PLATFORM", "WEB", - Set.of("OVERSEAS_WAREHOUSE_PDA_OPERATOR"), Set.of(authority, lastlegAuthority, domesticAuthority), 7L, 900L); + Set.of("OVERSEAS_WAREHOUSE_PDA_OPERATOR"), + Set.of(authority, merchantAuthority, lastlegAuthority, domesticAuthority), 7L, 900L); Jwt encoded = org.mockito.Mockito.mock(Jwt.class); when(accounts.findById(42L)).thenReturn(account); when(authorizationLoader.load(account)).thenReturn(snapshot); @@ -75,7 +77,7 @@ class OverseasTokenServiceTest { .containsEntry("token_version", 0) .containsEntry("overseas_warehouse_id", 900L) .containsEntry("roles", Set.of("OVERSEAS_WAREHOUSE_PDA_OPERATOR")) - .containsEntry("authorities", Set.of(authority, lastlegAuthority)) + .containsEntry("authorities", Set.of(authority, merchantAuthority, lastlegAuthority)) .doesNotContainKeys("userId", "tenantId", "appCode", "permissionVersion"); assertThat(response.expiresIn()).isEqualTo(900); }