Commit f0402f69e1328496fe2ade87354c8e9c87663fe0

Authored by YunaiV
1 parent 040899d8

fix:【framework 框架】修改配置会导致 TenantIgnore 注解的 controller 接口过滤失效,https://gitee.com/z…

…hijiantianya/yudao-cloud/issues/ICUQL9
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; @@ -44,8 +44,7 @@ import org.springframework.web.servlet.mvc.method.RequestMappingInfo;
44 import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping; 44 import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;
45 import org.springframework.web.util.pattern.PathPattern; 45 import org.springframework.web.util.pattern.PathPattern;
46 46
47 -import java.util.Map;  
48 -import java.util.Objects; 47 +import java.util.*;
49 48
50 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList; 49 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList;
51 50
@@ -84,41 +83,13 @@ public class YudaoTenantAutoConfiguration { @@ -84,41 +83,13 @@ public class YudaoTenantAutoConfiguration {
84 // ========== WEB ========== 83 // ========== WEB ==========
85 84
86 @Bean 85 @Bean
87 - public FilterRegistrationBean<TenantContextWebFilter> tenantContextWebFilter(TenantProperties tenantProperties) { 86 + public FilterRegistrationBean<TenantContextWebFilter> tenantContextWebFilter() {
88 FilterRegistrationBean<TenantContextWebFilter> registrationBean = new FilterRegistrationBean<>(); 87 FilterRegistrationBean<TenantContextWebFilter> registrationBean = new FilterRegistrationBean<>();
89 registrationBean.setFilter(new TenantContextWebFilter()); 88 registrationBean.setFilter(new TenantContextWebFilter());
90 registrationBean.setOrder(WebFilterOrderEnum.TENANT_CONTEXT_FILTER); 89 registrationBean.setOrder(WebFilterOrderEnum.TENANT_CONTEXT_FILTER);
91 - addIgnoreUrls(tenantProperties);  
92 return registrationBean; 90 return registrationBean;
93 } 91 }
94 92
95 - /**  
96 - * 如果 Controller 接口上,有 {@link TenantIgnore} 注解,那么添加到忽略的 URL 中  
97 - *  
98 - * @param tenantProperties 租户配置  
99 - */  
100 - private void addIgnoreUrls(TenantProperties tenantProperties) {  
101 - // 获得接口对应的 HandlerMethod 集合  
102 - RequestMappingHandlerMapping requestMappingHandlerMapping = (RequestMappingHandlerMapping)  
103 - applicationContext.getBean("requestMappingHandlerMapping");  
104 - Map<RequestMappingInfo, HandlerMethod> handlerMethodMap = requestMappingHandlerMapping.getHandlerMethods();  
105 - // 获得有 @TenantIgnore 注解的接口  
106 - for (Map.Entry<RequestMappingInfo, HandlerMethod> entry : handlerMethodMap.entrySet()) {  
107 - HandlerMethod handlerMethod = entry.getValue();  
108 - if (!handlerMethod.hasMethodAnnotation(TenantIgnore.class)) {  
109 - continue;  
110 - }  
111 - // 添加到忽略的 URL 中  
112 - if (entry.getKey().getPatternsCondition() != null) {  
113 - tenantProperties.getIgnoreUrls().addAll(entry.getKey().getPatternsCondition().getPatterns());  
114 - }  
115 - if (entry.getKey().getPathPatternsCondition() != null) {  
116 - tenantProperties.getIgnoreUrls().addAll(  
117 - convertList(entry.getKey().getPathPatternsCondition().getPatterns(), PathPattern::getPatternString));  
118 - }  
119 - }  
120 - }  
121 -  
122 @Bean 93 @Bean
123 public TenantVisitContextInterceptor tenantVisitContextInterceptor(TenantProperties tenantProperties, 94 public TenantVisitContextInterceptor tenantVisitContextInterceptor(TenantProperties tenantProperties,
124 SecurityFrameworkService securityFrameworkService) { 95 SecurityFrameworkService securityFrameworkService) {
@@ -146,12 +117,41 @@ public class YudaoTenantAutoConfiguration { @@ -146,12 +117,41 @@ public class YudaoTenantAutoConfiguration {
146 GlobalExceptionHandler globalExceptionHandler, 117 GlobalExceptionHandler globalExceptionHandler,
147 TenantFrameworkService tenantFrameworkService) { 118 TenantFrameworkService tenantFrameworkService) {
148 FilterRegistrationBean<TenantSecurityWebFilter> registrationBean = new FilterRegistrationBean<>(); 119 FilterRegistrationBean<TenantSecurityWebFilter> registrationBean = new FilterRegistrationBean<>();
149 - registrationBean.setFilter(new TenantSecurityWebFilter(tenantProperties, webProperties, 120 + registrationBean.setFilter(new TenantSecurityWebFilter(webProperties, tenantProperties, getTenantIgnoreUrls(),
150 globalExceptionHandler, tenantFrameworkService)); 121 globalExceptionHandler, tenantFrameworkService));
151 registrationBean.setOrder(WebFilterOrderEnum.TENANT_SECURITY_FILTER); 122 registrationBean.setOrder(WebFilterOrderEnum.TENANT_SECURITY_FILTER);
152 return registrationBean; 123 return registrationBean;
153 } 124 }
154 125
  126 + /**
  127 + * 如果 Controller 接口上,有 {@link TenantIgnore} 注解,则添加到忽略租户的 URL 集合中
  128 + *
  129 + * @return 忽略租户的 URL 集合
  130 + */
  131 + private Set<String> getTenantIgnoreUrls() {
  132 + Set<String> ignoreUrls = new HashSet<>();
  133 + // 获得接口对应的 HandlerMethod 集合
  134 + RequestMappingHandlerMapping requestMappingHandlerMapping = (RequestMappingHandlerMapping)
  135 + applicationContext.getBean("requestMappingHandlerMapping");
  136 + Map<RequestMappingInfo, HandlerMethod> handlerMethodMap = requestMappingHandlerMapping.getHandlerMethods();
  137 + // 获得有 @TenantIgnore 注解的接口
  138 + for (Map.Entry<RequestMappingInfo, HandlerMethod> entry : handlerMethodMap.entrySet()) {
  139 + HandlerMethod handlerMethod = entry.getValue();
  140 + if (!handlerMethod.hasMethodAnnotation(TenantIgnore.class)) {
  141 + continue;
  142 + }
  143 + // 添加到忽略的 URL 中
  144 + if (entry.getKey().getPatternsCondition() != null) {
  145 + ignoreUrls.addAll(entry.getKey().getPatternsCondition().getPatterns());
  146 + }
  147 + if (entry.getKey().getPathPatternsCondition() != null) {
  148 + ignoreUrls.addAll(
  149 + convertList(entry.getKey().getPathPatternsCondition().getPatterns(), PathPattern::getPatternString));
  150 + }
  151 + }
  152 + return ignoreUrls;
  153 + }
  154 +
155 // ========== MQ ========== 155 // ========== MQ ==========
156 156
157 @Bean 157 @Bean
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; @@ -12,15 +12,16 @@ import cn.iocoder.yudao.framework.tenant.core.service.TenantFrameworkService;
12 import cn.iocoder.yudao.framework.web.config.WebProperties; 12 import cn.iocoder.yudao.framework.web.config.WebProperties;
13 import cn.iocoder.yudao.framework.web.core.filter.ApiRequestFilter; 13 import cn.iocoder.yudao.framework.web.core.filter.ApiRequestFilter;
14 import cn.iocoder.yudao.framework.web.core.handler.GlobalExceptionHandler; 14 import cn.iocoder.yudao.framework.web.core.handler.GlobalExceptionHandler;
15 -import lombok.extern.slf4j.Slf4j;  
16 -import org.springframework.util.AntPathMatcher;  
17 -  
18 import jakarta.servlet.FilterChain; 15 import jakarta.servlet.FilterChain;
19 import jakarta.servlet.ServletException; 16 import jakarta.servlet.ServletException;
20 import jakarta.servlet.http.HttpServletRequest; 17 import jakarta.servlet.http.HttpServletRequest;
21 import jakarta.servlet.http.HttpServletResponse; 18 import jakarta.servlet.http.HttpServletResponse;
  19 +import lombok.extern.slf4j.Slf4j;
  20 +import org.springframework.util.AntPathMatcher;
  21 +
22 import java.io.IOException; 22 import java.io.IOException;
23 import java.util.Objects; 23 import java.util.Objects;
  24 +import java.util.Set;
24 25
25 /** 26 /**
26 * 多租户 Security Web 过滤器 27 * 多租户 Security Web 过滤器
@@ -35,17 +36,26 @@ public class TenantSecurityWebFilter extends ApiRequestFilter { @@ -35,17 +36,26 @@ public class TenantSecurityWebFilter extends ApiRequestFilter {
35 36
36 private final TenantProperties tenantProperties; 37 private final TenantProperties tenantProperties;
37 38
  39 + /**
  40 + * 允许忽略租户的 URL 列表
  41 + *
  42 + * 目的:解决 <a href="https://gitee.com/zhijiantianya/yudao-cloud/issues/ICUQL9">修改配置会导致 @TenantIgnore Controller 接口过滤失效</>
  43 + */
  44 + private final Set<String> ignoreUrls;
  45 +
38 private final AntPathMatcher pathMatcher; 46 private final AntPathMatcher pathMatcher;
39 47
40 private final GlobalExceptionHandler globalExceptionHandler; 48 private final GlobalExceptionHandler globalExceptionHandler;
41 private final TenantFrameworkService tenantFrameworkService; 49 private final TenantFrameworkService tenantFrameworkService;
42 50
43 - public TenantSecurityWebFilter(TenantProperties tenantProperties,  
44 - WebProperties webProperties, 51 + public TenantSecurityWebFilter(WebProperties webProperties,
  52 + TenantProperties tenantProperties,
  53 + Set<String> ignoreUrls,
45 GlobalExceptionHandler globalExceptionHandler, 54 GlobalExceptionHandler globalExceptionHandler,
46 TenantFrameworkService tenantFrameworkService) { 55 TenantFrameworkService tenantFrameworkService) {
47 super(webProperties); 56 super(webProperties);
48 this.tenantProperties = tenantProperties; 57 this.tenantProperties = tenantProperties;
  58 + this.ignoreUrls = ignoreUrls;
49 this.pathMatcher = new AntPathMatcher(); 59 this.pathMatcher = new AntPathMatcher();
50 this.globalExceptionHandler = globalExceptionHandler; 60 this.globalExceptionHandler = globalExceptionHandler;
51 this.tenantFrameworkService = tenantFrameworkService; 61 this.tenantFrameworkService = tenantFrameworkService;
@@ -103,7 +113,8 @@ public class TenantSecurityWebFilter extends ApiRequestFilter { @@ -103,7 +113,8 @@ public class TenantSecurityWebFilter extends ApiRequestFilter {
103 private boolean isIgnoreUrl(HttpServletRequest request) { 113 private boolean isIgnoreUrl(HttpServletRequest request) {
104 String apiUri = request.getRequestURI().substring(request.getContextPath().length()); 114 String apiUri = request.getRequestURI().substring(request.getContextPath().length());
105 // 快速匹配,保证性能 115 // 快速匹配,保证性能
106 - if (CollUtil.contains(tenantProperties.getIgnoreUrls(), apiUri)) { 116 + if (CollUtil.contains(tenantProperties.getIgnoreUrls(), apiUri)
  117 + || CollUtil.contains(ignoreUrls, apiUri)) {
107 return true; 118 return true;
108 } 119 }
109 // 逐个 Ant 路径匹配 120 // 逐个 Ant 路径匹配
@@ -112,6 +123,11 @@ public class TenantSecurityWebFilter extends ApiRequestFilter { @@ -112,6 +123,11 @@ public class TenantSecurityWebFilter extends ApiRequestFilter {
112 return true; 123 return true;
113 } 124 }
114 } 125 }
  126 + for (String url : ignoreUrls) {
  127 + if (pathMatcher.match(url, apiUri)) {
  128 + return true;
  129 + }
  130 + }
115 return false; 131 return false;
116 } 132 }
117 133