From f0402f69e1328496fe2ade87354c8e9c87663fe0 Mon Sep 17 00:00:00 2001 From: YunaiV Date: Sat, 30 Aug 2025 19:59:15 +0800 Subject: [PATCH] =?UTF-8?q?fix=EF=BC=9A=E3=80=90framework=20=E6=A1=86?= =?UTF-8?q?=E6=9E=B6=E3=80=91=E4=BF=AE=E6=94=B9=E9=85=8D=E7=BD=AE=E4=BC=9A?= =?UTF-8?q?=E5=AF=BC=E8=87=B4=20TenantIgnore=20=E6=B3=A8=E8=A7=A3=E7=9A=84?= =?UTF-8?q?=20controller=20=E6=8E=A5=E5=8F=A3=E8=BF=87=E6=BB=A4=E5=A4=B1?= =?UTF-8?q?=E6=95=88=EF=BC=8Chttps://gitee.com/zhijiantianya/yudao-cloud/i?= =?UTF-8?q?ssues/ICUQL9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../config/YudaoTenantAutoConfiguration.java | 64 +++++++++---------- .../security/TenantSecurityWebFilter.java | 28 ++++++-- 2 files changed, 54 insertions(+), 38 deletions(-) diff --git a/yudao-framework/yudao-spring-boot-starter-biz-tenant/src/main/java/cn/iocoder/yudao/framework/tenant/config/YudaoTenantAutoConfiguration.java b/yudao-framework/yudao-spring-boot-starter-biz-tenant/src/main/java/cn/iocoder/yudao/framework/tenant/config/YudaoTenantAutoConfiguration.java index 0d9783ef9e..2ff9fe4849 100644 --- a/yudao-framework/yudao-spring-boot-starter-biz-tenant/src/main/java/cn/iocoder/yudao/framework/tenant/config/YudaoTenantAutoConfiguration.java +++ b/yudao-framework/yudao-spring-boot-starter-biz-tenant/src/main/java/cn/iocoder/yudao/framework/tenant/config/YudaoTenantAutoConfiguration.java @@ -44,8 +44,7 @@ import org.springframework.web.servlet.mvc.method.RequestMappingInfo; import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping; import org.springframework.web.util.pattern.PathPattern; -import java.util.Map; -import java.util.Objects; +import java.util.*; import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList; @@ -84,41 +83,13 @@ public class YudaoTenantAutoConfiguration { // ========== WEB ========== @Bean - public FilterRegistrationBean tenantContextWebFilter(TenantProperties tenantProperties) { + public FilterRegistrationBean tenantContextWebFilter() { FilterRegistrationBean registrationBean = new FilterRegistrationBean<>(); registrationBean.setFilter(new TenantContextWebFilter()); registrationBean.setOrder(WebFilterOrderEnum.TENANT_CONTEXT_FILTER); - addIgnoreUrls(tenantProperties); return registrationBean; } - /** - * 如果 Controller 接口上,有 {@link TenantIgnore} 注解,那么添加到忽略的 URL 中 - * - * @param tenantProperties 租户配置 - */ - private void addIgnoreUrls(TenantProperties tenantProperties) { - // 获得接口对应的 HandlerMethod 集合 - RequestMappingHandlerMapping requestMappingHandlerMapping = (RequestMappingHandlerMapping) - applicationContext.getBean("requestMappingHandlerMapping"); - Map handlerMethodMap = requestMappingHandlerMapping.getHandlerMethods(); - // 获得有 @TenantIgnore 注解的接口 - for (Map.Entry entry : handlerMethodMap.entrySet()) { - HandlerMethod handlerMethod = entry.getValue(); - if (!handlerMethod.hasMethodAnnotation(TenantIgnore.class)) { - continue; - } - // 添加到忽略的 URL 中 - if (entry.getKey().getPatternsCondition() != null) { - tenantProperties.getIgnoreUrls().addAll(entry.getKey().getPatternsCondition().getPatterns()); - } - if (entry.getKey().getPathPatternsCondition() != null) { - tenantProperties.getIgnoreUrls().addAll( - convertList(entry.getKey().getPathPatternsCondition().getPatterns(), PathPattern::getPatternString)); - } - } - } - @Bean public TenantVisitContextInterceptor tenantVisitContextInterceptor(TenantProperties tenantProperties, SecurityFrameworkService securityFrameworkService) { @@ -146,12 +117,41 @@ public class YudaoTenantAutoConfiguration { GlobalExceptionHandler globalExceptionHandler, TenantFrameworkService tenantFrameworkService) { FilterRegistrationBean registrationBean = new FilterRegistrationBean<>(); - registrationBean.setFilter(new TenantSecurityWebFilter(tenantProperties, webProperties, + registrationBean.setFilter(new TenantSecurityWebFilter(webProperties, tenantProperties, getTenantIgnoreUrls(), globalExceptionHandler, tenantFrameworkService)); registrationBean.setOrder(WebFilterOrderEnum.TENANT_SECURITY_FILTER); return registrationBean; } + /** + * 如果 Controller 接口上,有 {@link TenantIgnore} 注解,则添加到忽略租户的 URL 集合中 + * + * @return 忽略租户的 URL 集合 + */ + private Set getTenantIgnoreUrls() { + Set ignoreUrls = new HashSet<>(); + // 获得接口对应的 HandlerMethod 集合 + RequestMappingHandlerMapping requestMappingHandlerMapping = (RequestMappingHandlerMapping) + applicationContext.getBean("requestMappingHandlerMapping"); + Map handlerMethodMap = requestMappingHandlerMapping.getHandlerMethods(); + // 获得有 @TenantIgnore 注解的接口 + for (Map.Entry entry : handlerMethodMap.entrySet()) { + HandlerMethod handlerMethod = entry.getValue(); + if (!handlerMethod.hasMethodAnnotation(TenantIgnore.class)) { + continue; + } + // 添加到忽略的 URL 中 + if (entry.getKey().getPatternsCondition() != null) { + ignoreUrls.addAll(entry.getKey().getPatternsCondition().getPatterns()); + } + if (entry.getKey().getPathPatternsCondition() != null) { + ignoreUrls.addAll( + convertList(entry.getKey().getPathPatternsCondition().getPatterns(), PathPattern::getPatternString)); + } + } + return ignoreUrls; + } + // ========== MQ ========== @Bean diff --git a/yudao-framework/yudao-spring-boot-starter-biz-tenant/src/main/java/cn/iocoder/yudao/framework/tenant/core/security/TenantSecurityWebFilter.java b/yudao-framework/yudao-spring-boot-starter-biz-tenant/src/main/java/cn/iocoder/yudao/framework/tenant/core/security/TenantSecurityWebFilter.java index 690e392d2e..5858ec73a6 100644 --- a/yudao-framework/yudao-spring-boot-starter-biz-tenant/src/main/java/cn/iocoder/yudao/framework/tenant/core/security/TenantSecurityWebFilter.java +++ b/yudao-framework/yudao-spring-boot-starter-biz-tenant/src/main/java/cn/iocoder/yudao/framework/tenant/core/security/TenantSecurityWebFilter.java @@ -12,15 +12,16 @@ import cn.iocoder.yudao.framework.tenant.core.service.TenantFrameworkService; import cn.iocoder.yudao.framework.web.config.WebProperties; import cn.iocoder.yudao.framework.web.core.filter.ApiRequestFilter; import cn.iocoder.yudao.framework.web.core.handler.GlobalExceptionHandler; -import lombok.extern.slf4j.Slf4j; -import org.springframework.util.AntPathMatcher; - import jakarta.servlet.FilterChain; import jakarta.servlet.ServletException; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; +import lombok.extern.slf4j.Slf4j; +import org.springframework.util.AntPathMatcher; + import java.io.IOException; import java.util.Objects; +import java.util.Set; /** * 多租户 Security Web 过滤器 @@ -35,17 +36,26 @@ public class TenantSecurityWebFilter extends ApiRequestFilter { private final TenantProperties tenantProperties; + /** + * 允许忽略租户的 URL 列表 + * + * 目的:解决 修改配置会导致 @TenantIgnore Controller 接口过滤失效 + */ + private final Set ignoreUrls; + private final AntPathMatcher pathMatcher; private final GlobalExceptionHandler globalExceptionHandler; private final TenantFrameworkService tenantFrameworkService; - public TenantSecurityWebFilter(TenantProperties tenantProperties, - WebProperties webProperties, + public TenantSecurityWebFilter(WebProperties webProperties, + TenantProperties tenantProperties, + Set ignoreUrls, GlobalExceptionHandler globalExceptionHandler, TenantFrameworkService tenantFrameworkService) { super(webProperties); this.tenantProperties = tenantProperties; + this.ignoreUrls = ignoreUrls; this.pathMatcher = new AntPathMatcher(); this.globalExceptionHandler = globalExceptionHandler; this.tenantFrameworkService = tenantFrameworkService; @@ -103,7 +113,8 @@ public class TenantSecurityWebFilter extends ApiRequestFilter { private boolean isIgnoreUrl(HttpServletRequest request) { String apiUri = request.getRequestURI().substring(request.getContextPath().length()); // 快速匹配,保证性能 - if (CollUtil.contains(tenantProperties.getIgnoreUrls(), apiUri)) { + if (CollUtil.contains(tenantProperties.getIgnoreUrls(), apiUri) + || CollUtil.contains(ignoreUrls, apiUri)) { return true; } // 逐个 Ant 路径匹配 @@ -112,6 +123,11 @@ public class TenantSecurityWebFilter extends ApiRequestFilter { return true; } } + for (String url : ignoreUrls) { + if (pathMatcher.match(url, apiUri)) { + return true; + } + } return false; }