فهرست منبع

fix: 条件表租户隔离 — 已登录用户走 tenant_id 过滤,无认证回调保持跳过

alphaH 3 هفته پیش
والد
کامیت
6704a40995
1فایلهای تغییر یافته به همراه53 افزوده شده و 27 حذف شده
  1. 53 27
      java/src/main/java/com/payment/platform/core/tenant/TenantInnerInterceptor.java

+ 53 - 27
java/src/main/java/com/payment/platform/core/tenant/TenantInnerInterceptor.java

@@ -21,37 +21,48 @@ import java.util.Set;
 @Component
 public class TenantInnerInterceptor extends TenantLineInnerInterceptor {
 
+    /**
+     * 始终跳过的表 — 无 tenant_id 列,或系统级共享表。
+     * 支付业务表已移出(由 getTenantId() 返回 null 处理无认证场景)。
+     */
     private static final Set<String> IGNORE_TABLES = Set.of(
             "sys_tenant",         // 租户表自身
-            "sys_user",           // 用户表(登录时无租户上下文)
-            "sys_role",           // 角色表
-            "sys_menu",           // 菜单表
-            "sys_dept",           // 部门表
-            "sys_position",       // 岗位表
-            "sys_dict_type",      // 字典类型
-            "sys_dict_data",      // 字典数据
-            "sys_param",          // 系统参数
-            "sys_notice",         // 通知公告
-            "sys_log",            // 操作日志
-            "sys_role_menus",     // 角色菜单关联表(无 tenant_id 列)
-            "sys_user_roles",     // 用户角色关联表(无 tenant_id 列)
-            "sys_user_positions", // 用户岗位关联表(无 tenant_id 列)
-            "sys_user_social",    // 用户第三方登录(无 tenant_id 列)
+            "sys_role",           // 角色表(平台共享)
+            "sys_menu",           // 菜单表(平台共享)
+            "sys_dept",           // 部门表(平台共享)
+            "sys_position",       // 岗位表(平台共享)
+            "sys_dict_type",      // 字典类型(平台共享)
+            "sys_dict_data",      // 字典数据(平台共享)
+            "sys_param",          // 系统参数(平台共享)
+            "sys_notice",         // 通知公告(平台共享)
+            "sys_log",            // 操作日志(跨租户审计)
+            "sys_role_menus",     // 关联表(无 tenant_id 列)
+            "sys_user_roles",     // 关联表(无 tenant_id 列)
+            "sys_user_positions", // 关联表(无 tenant_id 列)
+            "sys_user_social",    // 关联表(无 tenant_id 列)
             "pay_service_provider",         // 服务商配置(无 tenant_id 列)
             "pay_service_provider_profile", // 服务商业务凭证(无 tenant_id 列)
-            "pay_employee",         // 员工表(登录时无租户上下文)
-            "sys_invitation_code", // 邀请码表(无 tenant_id 列,系统级功能)
+            "sys_invitation_code",          // 邀请码表(无 tenant_id 列)
+            "sys_role_depts"                // 关联表(无 tenant_id 列)
+    );
+
+    /**
+     * 有 tenant_id 列,但会被无认证场景(通知回调/定时任务)访问的表。
+     * 无认证时跳过(保持旧行为);用户已登录时正常应用租户过滤。
+     */
+    private static final Set<String> CONDITIONAL_TABLES = Set.of(
+            "sys_user",              // 用户表(登录时无租户上下文)
+            "pay_employee",          // 员工表(登录时无租户上下文)
             "pay_alipay_notify_log", // 支付宝通知日志(异步回调无认证上下文)
-            "sys_role_depts",       // 角色部门关联表(无 tenant_id 列)
-            "pay_bill",             // 消费账单(通知处理无认证上下文)
-            "pay_bill_order",       // 账单订单(通知处理无认证上下文)
-            "pay_bill_voucher",     // 账单发票(通知处理无认证上下文)
-            "pay_transfer",         // 转账记录(通知处理无认证上下文)
-            "pay_deposit",          // 充值记录(通知处理无认证上下文)
-            "pay_expense_rule",     // 费控规则(通知处理无认证上下文)
-            "pay_expense_quota",    // 费控额度(通知处理无认证上下文)
+            "pay_bill",              // 消费账单(通知处理无认证上下文)
+            "pay_bill_order",        // 账单订单(通知处理无认证上下文)
+            "pay_bill_voucher",      // 账单发票(通知处理无认证上下文)
+            "pay_transfer",          // 转账记录(通知处理无认证上下文)
+            "pay_deposit",           // 充值记录(通知处理无认证上下文)
+            "pay_expense_rule",      // 费控规则(通知处理无认证上下文)
+            "pay_expense_quota",     // 费控额度(通知处理无认证上下文)
             "pay_expense_institution", // 费控制度(通知处理无认证上下文)
-            "pay_facetoface_order" // 当面付申请单(定时轮询无认证上下文)
+            "pay_facetoface_order"   // 当面付申请单(定时轮询无认证上下文)
     );
 
     public TenantInnerInterceptor() {
@@ -75,8 +86,8 @@ public class TenantInnerInterceptor extends TenantLineInnerInterceptor {
 
             @Override
             public boolean ignoreTable(String tableName) {
-                // 管理员跳过租户隔离,可查看所有租户数据
                 Authentication auth = SecurityContextHolder.getContext().getAuthentication();
+                // 超级管理员跳过租户隔离,可查看所有租户数据
                 if (auth != null && auth.getPrincipal() instanceof LoginUser user) {
                     if (user.getIsSuperuser() != null && user.getIsSuperuser()) {
                         return true;
@@ -86,7 +97,22 @@ public class TenantInnerInterceptor extends TenantLineInnerInterceptor {
                 if (cleaned != null && cleaned.contains(".")) {
                     cleaned = cleaned.substring(cleaned.lastIndexOf('.') + 1);
                 }
-                return IGNORE_TABLES.contains(cleaned);
+                // 始终跳过的表(无 tenant_id 列 / 系统级共享表)
+                if (IGNORE_TABLES.contains(cleaned)) {
+                    return true;
+                }
+                // 条件表:有 tenant_id 列,但会被无认证场景访问
+                // 用户已登录 → 不跳过,正常应用租户过滤
+                // 无认证(通知回调/定时任务)→ 跳过,保持旧行为
+                if (CONDITIONAL_TABLES.contains(cleaned)) {
+                    if (auth != null && auth.getPrincipal() instanceof LoginUser user) {
+                        if (user.getTenantId() != null) {
+                            return false; // 已登录用户 → 应用租户过滤
+                        }
+                    }
+                    return true; // 无认证上下文 → 跳过
+                }
+                return false;
             }
         });
     }