diff --git a/yanzhu-framework/yanzhu-spring-boot-starter-biz-tenant/src/main/java/com/yanzhu/framework/tenant/core/security/TenantSecurityWebFilter.java b/yanzhu-framework/yanzhu-spring-boot-starter-biz-tenant/src/main/java/com/yanzhu/framework/tenant/core/security/TenantSecurityWebFilter.java index 746141f..9cfcd0b 100644 --- a/yanzhu-framework/yanzhu-spring-boot-starter-biz-tenant/src/main/java/com/yanzhu/framework/tenant/core/security/TenantSecurityWebFilter.java +++ b/yanzhu-framework/yanzhu-spring-boot-starter-biz-tenant/src/main/java/com/yanzhu/framework/tenant/core/security/TenantSecurityWebFilter.java @@ -64,6 +64,18 @@ public class TenantSecurityWebFilter extends ApiRequestFilter { @Override protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws ServletException, IOException { + // 首先检查是否是忽略租户的 URL,如果是,则直接跳过所有租户相关检查 + if (isIgnoreUrl(request)) { + Long tenantId = TenantContextHolder.getTenantId(); + // 如果是允许忽略租户的 URL,若未传递租户编号,则默认忽略租户编号,避免报错 + if (tenantId == null) { + TenantContextHolder.setIgnore(true); + } + // 继续过滤 + chain.doFilter(request, response); + return; + } + Long tenantId = TenantContextHolder.getTenantId(); // 1. 登陆的用户,校验是否有权限访问该租户,避免越权问题。 LoginUser user = SecurityFrameworkUtils.getLoginUser(); @@ -83,27 +95,20 @@ public class TenantSecurityWebFilter extends ApiRequestFilter { } } - // 如果非允许忽略租户的 URL,则校验租户是否合法 - if (!isIgnoreUrl(request)) { - // 2. 如果请求未带租户的编号,不允许访问。 - if (tenantId == null) { - log.error("[doFilterInternal][URL({}/{}) 未传递租户编号]", request.getRequestURI(), request.getMethod()); - ServletUtils.writeJSON(response, CommonResult.error(GlobalErrorCodeConstants.BAD_REQUEST.getCode(), - "请求的租户标识未传递,请进行排查")); - return; - } - // 3. 校验租户是合法,例如说被禁用、到期 - try { - tenantFrameworkService.validTenant(tenantId); - } catch (Throwable ex) { - CommonResult result = globalExceptionHandler.allExceptionHandler(request, ex); - ServletUtils.writeJSON(response, result); - return; - } - } else { // 如果是允许忽略租户的 URL,若未传递租户编号,则默认忽略租户编号,避免报错 - if (tenantId == null) { - TenantContextHolder.setIgnore(true); - } + // 2. 如果请求未带租户的编号,不允许访问。 + if (tenantId == null) { + log.error("[doFilterInternal][URL({}/{}) 未传递租户编号]", request.getRequestURI(), request.getMethod()); + ServletUtils.writeJSON(response, CommonResult.error(GlobalErrorCodeConstants.BAD_REQUEST.getCode(), + "请求的租户标识未传递,请进行排查")); + return; + } + // 3. 校验租户是合法,例如说被禁用、到期 + try { + tenantFrameworkService.validTenant(tenantId); + } catch (Throwable ex) { + CommonResult result = globalExceptionHandler.allExceptionHandler(request, ex); + ServletUtils.writeJSON(response, result); + return; } // 继续过滤 diff --git a/yanzhu-module-system/src/main/java/com/yanzhu/module/system/dal/mysql/oauth2/OAuth2AccessTokenMapper.java b/yanzhu-module-system/src/main/java/com/yanzhu/module/system/dal/mysql/oauth2/OAuth2AccessTokenMapper.java index 9878f99..03eb129 100644 --- a/yanzhu-module-system/src/main/java/com/yanzhu/module/system/dal/mysql/oauth2/OAuth2AccessTokenMapper.java +++ b/yanzhu-module-system/src/main/java/com/yanzhu/module/system/dal/mysql/oauth2/OAuth2AccessTokenMapper.java @@ -32,9 +32,14 @@ public interface OAuth2AccessTokenMapper extends BaseMapperX selectListByUserIdAndUserType(Long userId, Integer userType) { return selectList(OAuth2AccessTokenDO::getUserId, userId, OAuth2AccessTokenDO::getUserType, userType); } + @TenantIgnore // 删除 token 的时候,需要忽略租户编号。原因是:用户可能切换租户后登出,此时 token 的租户 ID 与当前租户不一致 + default int deleteByIdIgnoreTenant(Long id) { + return delete(OAuth2AccessTokenDO::getId, id); + } } diff --git a/yanzhu-module-system/src/main/java/com/yanzhu/module/system/service/oauth2/OAuth2TokenServiceImpl.java b/yanzhu-module-system/src/main/java/com/yanzhu/module/system/service/oauth2/OAuth2TokenServiceImpl.java index 9526928..2a594db 100644 --- a/yanzhu-module-system/src/main/java/com/yanzhu/module/system/service/oauth2/OAuth2TokenServiceImpl.java +++ b/yanzhu-module-system/src/main/java/com/yanzhu/module/system/service/oauth2/OAuth2TokenServiceImpl.java @@ -147,7 +147,7 @@ public class OAuth2TokenServiceImpl implements OAuth2TokenService { if (accessTokenDO == null) { return null; } - oauth2AccessTokenMapper.deleteById(accessTokenDO.getId()); + oauth2AccessTokenMapper.deleteByIdIgnoreTenant(accessTokenDO.getId()); oauth2AccessTokenRedisDAO.delete(accessToken); // 删除刷新令牌 oauth2RefreshTokenMapper.deleteByRefreshToken(accessTokenDO.getRefreshToken()); @@ -162,7 +162,7 @@ public class OAuth2TokenServiceImpl implements OAuth2TokenService { } accessTokens.forEach(accessToken -> { // 删除访问令牌 - oauth2AccessTokenMapper.deleteById(accessToken.getId()); + oauth2AccessTokenMapper.deleteByIdIgnoreTenant(accessToken.getId()); oauth2AccessTokenRedisDAO.delete(accessToken.getAccessToken()); // 删除刷新令牌 oauth2RefreshTokenMapper.deleteByRefreshToken(accessToken.getRefreshToken()); diff --git a/yanzhu-server/src/main/resources/application-local.yaml b/yanzhu-server/src/main/resources/application-local.yaml index 9ad98c9..72826bd 100644 --- a/yanzhu-server/src/main/resources/application-local.yaml +++ b/yanzhu-server/src/main/resources/application-local.yaml @@ -190,6 +190,7 @@ logging: com.yanzhu.module.iot.dal.tdengine: DEBUG com.yanzhu.module.iot.service.rule: debug com.yanzhu.module.ai.dal.mysql: debug + com.yanzhu.module.product.dal.mysql: debug org.springframework.context.support.PostProcessorRegistrationDelegate: ERROR # TODO 芋艿:先禁用,Spring Boot 3.X 存在部分错误的 WARN 提示 # Flowable 工作流引擎配置 diff --git a/yanzhu-server/src/main/resources/application.yaml b/yanzhu-server/src/main/resources/application.yaml index 2aa4698..c751ddc 100644 --- a/yanzhu-server/src/main/resources/application.yaml +++ b/yanzhu-server/src/main/resources/application.yaml @@ -67,6 +67,7 @@ flowable: mybatis-plus: configuration: map-underscore-to-camel-case: true # 虽然默认为 true ,但是还是显示去指定下。 + log-impl: org.apache.ibatis.logging.stdout.StdOutImpl # 开启SQL语句打印到控制台 global-config: db-config: id-type: NONE # “智能”模式,基于 IdTypeEnvironmentPostProcessor + 数据源的类型,自动适配成 AUTO、INPUT 模式。