Merge remote-tracking branch 'origin/test' into dev

# Conflicts:
#	auth/AGENTS.md
#	auth/src/main/java/com/baiyue/auth/service/OverseasTokenService.java
#	auth/src/test/java/com/baiyue/auth/service/OverseasTokenServiceTest.java
This commit is contained in:
2026-09-02 18:14:50 +08:00
3 changed files with 5 additions and 3 deletions
+1 -1
View File
@@ -17,7 +17,7 @@
| 登录标识与企业联系人解耦 | `service/AccountManagementService.java`、`dto/AccountManagementDtos.java`、`service/MerchantRegistrationService.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,只保留平台海外仓/海外业务/海外主数据、客户海外仓 `merchant:warehouse:*` 及 `lastleg:*` 权限前缀;前端统一认证层负责按区域 API 自动选择 |
| 海外访问 Token 签发 | `service/OverseasTokenService.java`;登录/刷新编排使用同一用户身份同时签发短时 RS256 海外 Token,限定海外 Audience,只保留平台海外仓/海外业务/海外主数据、客户海外仓 `merchant:warehouse:*`、海外财务 API 所需的 `platform:finance:*` 及 `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` |
@@ -32,6 +32,7 @@ public class OverseasTokenService {
"platform:overseas-business:",
"platform:overseas-master-data:",
"merchant:warehouse:",
"platform:finance:",
"lastleg:"
);
@@ -51,10 +51,11 @@ class OverseasTokenServiceTest {
String authority = "platform:overseas-master-data:quote:list";
String merchantAuthority = "merchant:warehouse:delivery:list";
String lastlegAuthority = "lastleg:pda:operate";
String financeAuthority = "platform:finance:fee-source:edit";
String domesticAuthority = "platform:firstleg:order:list";
AuthorizationSnapshot snapshot = new AuthorizationSnapshot(42L, 0L, 84L, "PLATFORM", "WEB",
Set.of("OVERSEAS_WAREHOUSE_PDA_OPERATOR"),
Set.of(authority, merchantAuthority, lastlegAuthority, domesticAuthority), 7L, 900L);
Set.of(authority, merchantAuthority, lastlegAuthority, financeAuthority, domesticAuthority), 7L, 900L);
Jwt encoded = org.mockito.Mockito.mock(Jwt.class);
when(accounts.findById(42L)).thenReturn(account);
when(authorizationLoader.load(account)).thenReturn(snapshot);
@@ -77,7 +78,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, merchantAuthority, lastlegAuthority))
.containsEntry("authorities", Set.of(authority, merchantAuthority, lastlegAuthority, financeAuthority))
.doesNotContainKeys("userId", "tenantId", "appCode", "permissionVersion");
assertThat(response.expiresIn()).isEqualTo(900);
}