From 8fc48f013ff8306fd7ef54de85a2d3c76808894b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=96=AF=E7=8B=82=E7=9A=84=E7=8B=AE=E5=AD=90Li?= <15040126243@163.com> Date: Thu, 24 Sep 2026 14:06:51 +0800 Subject: [PATCH] update sa-token 1.45.0 => 1.46.0 --- pom.xml | 2 +- .../dromara/system/api/model/LoginUser.java | 10 +++++++-- .../core/service/SaPermissionImpl.java | 22 +++++++++++++++++-- .../common/satoken/SaTokenFunctionTest.java | 8 ++++++- 4 files changed, 36 insertions(+), 6 deletions(-) diff --git a/pom.xml b/pom.xml index 449030ab7..f31ed993f 100644 --- a/pom.xml +++ b/pom.xml @@ -35,7 +35,7 @@ 7.17.28 - 1.45.0 + 1.46.0 3.0.1 1.85 diff --git a/ruoyi-api/src/main/java/org/dromara/system/api/model/LoginUser.java b/ruoyi-api/src/main/java/org/dromara/system/api/model/LoginUser.java index 352e330cd..91f5fd8e9 100644 --- a/ruoyi-api/src/main/java/org/dromara/system/api/model/LoginUser.java +++ b/ruoyi-api/src/main/java/org/dromara/system/api/model/LoginUser.java @@ -23,6 +23,12 @@ public class LoginUser implements Serializable { @Serial private static final long serialVersionUID = 1L; + /** + * 登录标识分隔符,用于拼接 userType 与 userId + *

不使用冒号:Sa-Token 1.46.0 起默认禁止 loginId 包含冒号;历史冒号格式仅为兼容旧 token 保留解析 + */ + public static final String LOGIN_ID_SEPARATOR = "-"; + /** * 用户ID */ @@ -136,7 +142,7 @@ public class LoginUser implements Serializable { /** * 获取 Sa-Token 使用的登录标识。 * - * @return 登录标识 + * @return 登录标识(userType-userId) */ public String getLoginId() { if (userType == null) { @@ -145,7 +151,7 @@ public class LoginUser implements Serializable { if (userId == null) { throw new IllegalArgumentException("用户ID不能为空"); } - return userType + ":" + userId; + return userType + LOGIN_ID_SEPARATOR + userId; } } diff --git a/ruoyi-common/ruoyi-common-satoken/src/main/java/org/dromara/common/satoken/core/service/SaPermissionImpl.java b/ruoyi-common/ruoyi-common-satoken/src/main/java/org/dromara/common/satoken/core/service/SaPermissionImpl.java index ddd4c1f4b..b9356a616 100644 --- a/ruoyi-common/ruoyi-common-satoken/src/main/java/org/dromara/common/satoken/core/service/SaPermissionImpl.java +++ b/ruoyi-common/ruoyi-common-satoken/src/main/java/org/dromara/common/satoken/core/service/SaPermissionImpl.java @@ -57,7 +57,7 @@ public class SaPermissionImpl implements StpInterface { java.util.function.Function> localPermissionExtractor, BiFunction> remotePermissionExtractor) { LoginUser loginUser = LoginHelper.getLoginUser(); - if (ObjectUtil.isNull(loginUser) || !loginUser.getLoginId().equals(loginId)) { + if (ObjectUtil.isNull(loginUser) || !loginUser.getLoginId().equals(normalizeLoginId(loginId))) { PermissionService permissionService = getPermissionService(); if (ObjectUtil.isNotNull(permissionService)) { return new ArrayList<>(remotePermissionExtractor.apply(permissionService, resolveUserId(loginId))); @@ -85,7 +85,22 @@ public class SaPermissionImpl implements StpInterface { } /** - * 从登录ID中提取用户ID。 + * 将历史冒号格式的登录ID规范化为当前分隔符格式,保证与旧 token 会话比较的一致性。 + * + * @param loginId 登录ID + * @return 规范化后的登录ID + */ + private String normalizeLoginId(Object loginId) { + String loginIdStr = loginId.toString(); + int separatorIndex = loginIdStr.indexOf(':'); + if (separatorIndex < 0) { + return loginIdStr; + } + return loginIdStr.substring(0, separatorIndex) + LoginUser.LOGIN_ID_SEPARATOR + loginIdStr.substring(separatorIndex + 1); + } + + /** + * 从登录ID中提取用户ID,兼容历史冒号格式与当前分隔符格式。 * * @param loginId 登录ID * @return 用户ID @@ -93,6 +108,9 @@ public class SaPermissionImpl implements StpInterface { private Long resolveUserId(Object loginId) { String loginIdStr = loginId.toString(); int separatorIndex = loginIdStr.indexOf(':'); + if (separatorIndex < 0) { + separatorIndex = loginIdStr.lastIndexOf(LoginUser.LOGIN_ID_SEPARATOR); + } if (separatorIndex < 0 || separatorIndex == loginIdStr.length() - 1) { throw new ServiceException("登录ID格式错误"); } diff --git a/ruoyi-common/ruoyi-common-satoken/src/test/java/org/dromara/common/satoken/SaTokenFunctionTest.java b/ruoyi-common/ruoyi-common-satoken/src/test/java/org/dromara/common/satoken/SaTokenFunctionTest.java index 1276572ef..44be2eaa3 100644 --- a/ruoyi-common/ruoyi-common-satoken/src/test/java/org/dromara/common/satoken/SaTokenFunctionTest.java +++ b/ruoyi-common/ruoyi-common-satoken/src/test/java/org/dromara/common/satoken/SaTokenFunctionTest.java @@ -74,6 +74,7 @@ class SaTokenFunctionTest { /** * 验证当前登录对象的菜单和角色权限直接来自会话快照,并对空权限集合返回可修改空列表。 + * 历史冒号格式与当前分隔符格式的登录ID均应命中会话快照。 */ @Test @DisplayName("读取当前会话权限快照") @@ -94,6 +95,10 @@ class SaTokenFunctionTest { assertEquals(Set.of("system:user:list", "system:user:add"), Set.copyOf(menus)); assertEquals(List.of(), roles); roles.add("temporary"); + + assertEquals(Set.of("system:user:list", "system:user:add"), + Set.copyOf(permission.getPermissionList("sys_user-7", "login"))); + assertEquals(List.of(), permission.getRoleList("sys_user-7", "login")); } } @@ -113,8 +118,9 @@ class SaTokenFunctionTest { SaPermissionImpl permission = new SaPermissionImpl(); assertEquals(List.of("system:dept:list"), permission.getPermissionList("sys_user:9", "login")); + assertEquals(List.of("system:dept:list"), permission.getPermissionList("sys_user-9", "login")); assertThrows(ServiceException.class, () -> permission.getPermissionList("invalid", "login")); - verify(service).getMenuPermission(9L); + verify(service, times(2)).getMenuPermission(9L); } }