2. tenant 组件:feign 调用时,通过 header 透传 Tenant 信息

This commit is contained in:
YunaiV 2022-06-11 23:13:58 +08:00
parent ca6e7a4528
commit f08fe24174
17 changed files with 126 additions and 19 deletions

View File

@ -14,6 +14,7 @@
"gateway": { "gateway": {
"baseUrl": "http://127.0.0.1:48080/admin-api", "baseUrl": "http://127.0.0.1:48080/admin-api",
"systemBaseUrl": "http://127.0.0.1:48080/admin-api", "systemBaseUrl": "http://127.0.0.1:48080/admin-api",
"infaBaseUrl": "http://127.0.0.1:48080/admin-api",
"token": "test1", "token": "test1",
"adminTenentId": "1", "adminTenentId": "1",

View File

@ -0,0 +1,17 @@
package cn.iocoder.yudao.framework.common.enums;
/**
* RPC 相关的枚举
*
* 虽然放在 yudao-spring-boot-starter-rpc 会相对合适但是每个 API 模块需要使用到所以暂时只好放在此处
*
* @author 芋道源码
*/
public class RpcConstants {
/**
* RPC API 的前缀
*/
public static final String RPC_API_PREFIX = "/rpc-api";
}

View File

@ -38,6 +38,13 @@
<artifactId>yudao-spring-boot-starter-redis</artifactId> <artifactId>yudao-spring-boot-starter-redis</artifactId>
</dependency> </dependency>
<!-- RPC 远程调用相关 -->
<dependency>
<groupId>cn.iocoder.cloud</groupId>
<artifactId>yudao-spring-boot-starter-rpc</artifactId>
<optional>true</optional>
</dependency>
<!-- Job 定时任务相关 --> <!-- Job 定时任务相关 -->
<dependency> <dependency>
<groupId>cn.iocoder.cloud</groupId> <groupId>cn.iocoder.cloud</groupId>

View File

@ -0,0 +1,17 @@
package cn.iocoder.yudao.framework.tenant.config;
import cn.iocoder.yudao.framework.tenant.core.rpc.TenantRequestInterceptor;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
@ConditionalOnProperty(prefix = "yudao.tenant", value = "enable", matchIfMissing = true) // 允许使用 yudao.tenant.enable=false 禁用多租户
public class YudaoTenantRpcAutoConfiguration {
@Bean
public TenantRequestInterceptor tenantRequestInterceptor() {
return new TenantRequestInterceptor();
}
}

View File

@ -0,0 +1,25 @@
package cn.iocoder.yudao.framework.tenant.core.rpc;
import cn.iocoder.yudao.framework.tenant.core.context.TenantContextHolder;
import cn.iocoder.yudao.framework.web.core.util.WebFrameworkUtils;
import feign.RequestInterceptor;
import feign.RequestTemplate;
import static cn.iocoder.yudao.framework.web.core.util.WebFrameworkUtils.HEADER_TENANT_ID;
/**
* Tenant RequestInterceptor 实现类Feign 请求时 {@link TenantContextHolder} 设置到 header 继续透传给被调用的服务
*
* @author 芋道源码
*/
public class TenantRequestInterceptor implements RequestInterceptor {
@Override
public void apply(RequestTemplate requestTemplate) {
Long tenantId = TenantContextHolder.getTenantId();
if (tenantId != null) {
requestTemplate.header(HEADER_TENANT_ID, String.valueOf(tenantId));
}
}
}

View File

@ -1,6 +1,8 @@
package cn.iocoder.yudao.framework.tenant.core.security; package cn.iocoder.yudao.framework.tenant.core.security;
import cn.hutool.core.collection.CollUtil; import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import cn.iocoder.yudao.framework.common.enums.RpcConstants;
import cn.iocoder.yudao.framework.common.exception.enums.GlobalErrorCodeConstants; import cn.iocoder.yudao.framework.common.exception.enums.GlobalErrorCodeConstants;
import cn.iocoder.yudao.framework.common.pojo.CommonResult; import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.util.servlet.ServletUtils; import cn.iocoder.yudao.framework.common.util.servlet.ServletUtils;
@ -53,6 +55,12 @@ public class TenantSecurityWebFilter extends ApiRequestFilter {
this.tenantFrameworkService = tenantFrameworkService; this.tenantFrameworkService = tenantFrameworkService;
} }
@Override
protected boolean shouldNotFilter(HttpServletRequest request) {
return super.shouldNotFilter(request) &&
!StrUtil.startWithAny(request.getRequestURI(), RpcConstants.RPC_API_PREFIX); // 因为 RPC API 也会透传租户编号
}
@Override @Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
throws ServletException, IOException { throws ServletException, IOException {

View File

@ -18,8 +18,6 @@ import java.io.IOException;
*/ */
public class TenantContextWebFilter extends OncePerRequestFilter { public class TenantContextWebFilter extends OncePerRequestFilter {
private static final String HEADER_TENANT_ID = "tenant-id";
@Override @Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
throws ServletException, IOException { throws ServletException, IOException {

View File

@ -1,2 +1,3 @@
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
cn.iocoder.yudao.framework.tenant.config.YudaoTenantRpcAutoConfiguration,\
cn.iocoder.yudao.framework.tenant.config.YudaoTenantAutoConfiguration cn.iocoder.yudao.framework.tenant.config.YudaoTenantAutoConfiguration

View File

@ -44,19 +44,19 @@
<artifactId>spring-boot-starter-security</artifactId> <artifactId>spring-boot-starter-security</artifactId>
</dependency> </dependency>
<!-- 业务组件 -->
<dependency>
<groupId>cn.iocoder.cloud</groupId>
<artifactId>yudao-module-system-api</artifactId> <!-- 需要使用它,进行 Token 的校验 -->
<version>${revision}</version>
</dependency>
<!-- RPC 远程调用相关 --> <!-- RPC 远程调用相关 -->
<dependency> <dependency>
<groupId>cn.iocoder.cloud</groupId> <groupId>cn.iocoder.cloud</groupId>
<artifactId>yudao-spring-boot-starter-rpc</artifactId> <artifactId>yudao-spring-boot-starter-rpc</artifactId>
<optional>true</optional> <optional>true</optional>
</dependency> </dependency>
<!-- 业务组件 -->
<dependency>
<groupId>cn.iocoder.cloud</groupId>
<artifactId>yudao-module-system-api</artifactId> <!-- 需要使用它,进行 Token 的校验 -->
<version>${revision}</version>
</dependency>
</dependencies> </dependencies>
</project> </project>

View File

@ -6,6 +6,11 @@ import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils;
import feign.RequestInterceptor; import feign.RequestInterceptor;
import feign.RequestTemplate; import feign.RequestTemplate;
/**
* LoginUser RequestInterceptor 实现类Feign 请求时 {@link LoginUser} 设置到 header 继续透传给被调用的服务
*
* @author 芋道源码
*/
public class LoginUserRequestInterceptor implements RequestInterceptor { public class LoginUserRequestInterceptor implements RequestInterceptor {
@Override @Override

View File

@ -23,7 +23,7 @@ public class WebFrameworkUtils {
private static final String REQUEST_ATTRIBUTE_COMMON_RESULT = "common_result"; private static final String REQUEST_ATTRIBUTE_COMMON_RESULT = "common_result";
private static final String HEADER_TENANT_ID = "tenant-id"; public static final String HEADER_TENANT_ID = "tenant-id";
private static WebProperties properties; private static WebProperties properties;

View File

@ -37,8 +37,8 @@
<!-- RPC 远程调用相关 --> <!-- RPC 远程调用相关 -->
<dependency> <dependency>
<groupId>cn.iocoder.cloud</groupId> <groupId>org.springframework.cloud</groupId>
<artifactId>yudao-spring-boot-starter-rpc</artifactId> <artifactId>spring-cloud-starter-loadbalancer</artifactId>
</dependency> </dependency>
<!-- Registry 注册中心相关 --> <!-- Registry 注册中心相关 -->

View File

@ -15,3 +15,11 @@ spring:
uri: grayLb://system-server uri: grayLb://system-server
predicates: # 断言,作为路由的匹配条件,对应 RouteDefinition 数组 predicates: # 断言,作为路由的匹配条件,对应 RouteDefinition 数组
- Path=/app-api/system/** - Path=/app-api/system/**
- id: infra-admin-api # 路由的编号
uri: grayLb://infra-server
predicates: # 断言,作为路由的匹配条件,对应 RouteDefinition 数组
- Path=/admin-api/infra/**
- id: infra-app-api # 路由的编号
uri: grayLb://infra-server
predicates: # 断言,作为路由的匹配条件,对应 RouteDefinition 数组
- Path=/app-api/infra/**

View File

@ -1,5 +1,7 @@
package cn.iocoder.yudao.module.infra.enums; package cn.iocoder.yudao.module.infra.enums;
import cn.iocoder.yudao.framework.common.enums.RpcConstants;
/** /**
* API 相关的枚举 * API 相关的枚举
* *
@ -14,7 +16,7 @@ public class ApiConstants {
*/ */
public static final String NAME = "infra-server"; public static final String NAME = "infra-server";
public static final String PREFIX = "/rpc-api/system"; public static final String PREFIX = RpcConstants.RPC_API_PREFIX + "/system";
public static final String VERSION = "1.0.0"; public static final String VERSION = "1.0.0";

View File

@ -42,6 +42,10 @@
<groupId>cn.iocoder.cloud</groupId> <groupId>cn.iocoder.cloud</groupId>
<artifactId>yudao-spring-boot-starter-biz-operatelog</artifactId> <artifactId>yudao-spring-boot-starter-biz-operatelog</artifactId>
</dependency> </dependency>
<dependency>
<groupId>cn.iocoder.cloud</groupId>
<artifactId>yudao-spring-boot-starter-biz-tenant</artifactId>
</dependency>
<!-- Web 相关 --> <!-- Web 相关 -->
<dependency> <dependency>

View File

@ -1,15 +1,12 @@
package cn.iocoder.yudao.module.infra.framework; package cn.iocoder.yudao.module.infra.framework;
import cn.iocoder.yudao.framework.apilog.core.service.ApiAccessLogFrameworkService;
import cn.iocoder.yudao.framework.apilog.core.service.ApiErrorLogFrameworkService;
import cn.iocoder.yudao.framework.apilog.core.service.dto.ApiAccessLogCreateReqDTO;
import cn.iocoder.yudao.framework.apilog.core.service.dto.ApiErrorLogCreateReqDTO;
import cn.iocoder.yudao.framework.operatelog.core.dto.OperateLogCreateReqDTO; import cn.iocoder.yudao.framework.operatelog.core.dto.OperateLogCreateReqDTO;
import cn.iocoder.yudao.framework.operatelog.core.service.OperateLogFrameworkService; import cn.iocoder.yudao.framework.operatelog.core.service.OperateLogFrameworkService;
import cn.iocoder.yudao.module.infra.api.file.FileApi; import cn.iocoder.yudao.framework.tenant.core.service.TenantFrameworkService;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import java.util.List;
import java.util.concurrent.Future; import java.util.concurrent.Future;
@Configuration @Configuration
@ -25,4 +22,19 @@ public class TmpConfiguration {
}; };
} }
@Bean
public TenantFrameworkService tenantFrameworkService() {
return new TenantFrameworkService() {
@Override
public List<Long> getTenantIds() {
return null;
}
@Override
public void validTenant(Long id) {
}
};
}
} }

View File

@ -1,5 +1,7 @@
package cn.iocoder.yudao.module.system.enums; package cn.iocoder.yudao.module.system.enums;
import cn.iocoder.yudao.framework.common.enums.RpcConstants;
/** /**
* API 相关的枚举 * API 相关的枚举
* *
@ -14,7 +16,7 @@ public class ApiConstants {
*/ */
public static final String NAME = "system-server"; public static final String NAME = "system-server";
public static final String PREFIX = "/rpc-api/system"; public static final String PREFIX = RpcConstants.RPC_API_PREFIX + "/system";
public static final String VERSION = "1.0.0"; public static final String VERSION = "1.0.0";