Merge pull request 'feat(微服务治理工具): 优化portainer转发逻辑' (#836) from otto/microservices:third-party-tool-forward into third-party-tool-forward

This commit is contained in:
otto 2025-03-07 11:04:59 +08:00
commit 713104e353
4 changed files with 39 additions and 4 deletions

View File

@ -22,6 +22,7 @@ public class TokenConstants {
* Sentinel令牌标识 * Sentinel令牌标识
*/ */
public static final String Sentinel_Token_Key = "sentinel_dashboard_cookie"; public static final String Sentinel_Token_Key = "sentinel_dashboard_cookie";
public static final String Portainer_Token_Key = "portainer_api_key";
/** /**
* Sentinel令牌标识 * Sentinel令牌标识
*/ */

View File

@ -10,9 +10,9 @@ import com.microservices.common.core.utils.JwtUtils;
import com.microservices.common.core.utils.ServletUtils; import com.microservices.common.core.utils.ServletUtils;
import com.microservices.common.core.utils.StringUtils; import com.microservices.common.core.utils.StringUtils;
import com.microservices.common.redis.service.RedisService; import com.microservices.common.redis.service.RedisService;
import com.microservices.gateway.CustomExecutorFactory;
import com.microservices.gateway.config.properties.IgnoreWhiteProperties; import com.microservices.gateway.config.properties.IgnoreWhiteProperties;
import com.microservices.gateway.service.ThirdPartyToolService; import com.microservices.gateway.service.ThirdPartyToolService;
import com.microservices.gateway.utils.CustomExecutorFactory;
import com.microservices.system.api.RemoteUserService; import com.microservices.system.api.RemoteUserService;
import com.microservices.system.api.domain.SysUserDeptRole; import com.microservices.system.api.domain.SysUserDeptRole;
import com.microservices.system.api.utils.FeignUtils; import com.microservices.system.api.utils.FeignUtils;

View File

@ -10,8 +10,8 @@ import com.microservices.common.core.utils.CookieUtil;
import com.microservices.common.core.utils.ServletUtils; import com.microservices.common.core.utils.ServletUtils;
import com.microservices.common.core.utils.StringUtils; import com.microservices.common.core.utils.StringUtils;
import com.microservices.common.redis.service.RedisService; import com.microservices.common.redis.service.RedisService;
import com.microservices.gateway.CustomExecutorFactory;
import com.microservices.gateway.service.ThirdPartyToolService; import com.microservices.gateway.service.ThirdPartyToolService;
import com.microservices.gateway.utils.CustomExecutorFactory;
import com.microservices.system.api.RemoteGatewayService; import com.microservices.system.api.RemoteGatewayService;
import feign.Response; import feign.Response;
import org.apache.commons.io.IOUtils; import org.apache.commons.io.IOUtils;
@ -27,9 +27,13 @@ import reactor.core.publisher.Mono;
import java.io.IOException; import java.io.IOException;
import java.io.StringWriter; import java.io.StringWriter;
import java.net.URI;
import java.net.URISyntaxException;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.util.*; import java.util.*;
import java.util.concurrent.*; import java.util.concurrent.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/** /**
* @author OTTO * @author OTTO
@ -49,6 +53,8 @@ public class ThirdPartyToolServiceImpl implements ThirdPartyToolService {
public String portainerUsername; public String portainerUsername;
@Value("${thirdPartyTools.portainer.auth.password:}") @Value("${thirdPartyTools.portainer.auth.password:}")
public String portainerPassword; public String portainerPassword;
@Value("${thirdPartyTools.portainer.endpoints:}")
public Integer portainerEndpoints;
ThreadPoolExecutor threadPoolExecutor = CustomExecutorFactory.threadPoolExecutor; ThreadPoolExecutor threadPoolExecutor = CustomExecutorFactory.threadPoolExecutor;
@Lazy @Lazy
@Autowired @Autowired
@ -61,7 +67,8 @@ public class ThirdPartyToolServiceImpl implements ThirdPartyToolService {
*/ */
@Override @Override
public Mono<Void> handleRequestForThirdPartyTools(ServerWebExchange exchange, ServerHttpRequest request, ServerHttpRequest.Builder mutate) { public Mono<Void> handleRequestForThirdPartyTools(ServerWebExchange exchange, ServerHttpRequest request, ServerHttpRequest.Builder mutate) {
String lowerUrl = request.getURI().getPath().toLowerCase(); String url = request.getURI().getPath();
String lowerUrl = url.toLowerCase();
if (StringUtils.isEmpty(lowerUrl)) { if (StringUtils.isEmpty(lowerUrl)) {
return null; return null;
} }
@ -141,8 +148,32 @@ public class ThirdPartyToolServiceImpl implements ThirdPartyToolService {
// 处理portainer请求 // 处理portainer请求
if (lowerUrl.startsWith("/portainer")) { if (lowerUrl.startsWith("/portainer")) {
// 处理portainer指定endpoints的问题
if (lowerUrl.startsWith("/portainer/api/endpoints/")) {
String regex = "^/portainer/api/endpoints/\\d+/.*$";
if (Pattern.matches(regex, lowerUrl)) {
// 替换掉endpoints
regex = "(^/portainer/api/endpoints/)(\\d+)(/.*$)";
Pattern pattern = Pattern.compile(regex, Pattern.CASE_INSENSITIVE);
Matcher matcher = pattern.matcher(url);
if (matcher.find()) {
// 替换数字部分
url = matcher.replaceAll(matcher.group(1) + portainerEndpoints + matcher.group(3));
try {
mutate.uri(new URI(url));
} catch (URISyntaxException e) {
log.error("替换Portainer请求中Endpoints时发生异常{}", e.getMessage());
}
}
}
}
String portainerToken = null; String portainerToken = null;
String cookie = request.getHeaders().getFirst(TokenConstants.Cookie);
if (StringUtils.isNotEmpty(CookieUtil.getCookieValue(cookie, TokenConstants.Portainer_Token_Key))) {
cookie = CookieUtil.removeCookieKey(cookie, TokenConstants.Portainer_Token_Key);
}
if (redisService.hasKey(CacheConstants.PORTAINER_TOKEN)) { if (redisService.hasKey(CacheConstants.PORTAINER_TOKEN)) {
portainerToken = redisService.getCacheObject(CacheConstants.PORTAINER_TOKEN); portainerToken = redisService.getCacheObject(CacheConstants.PORTAINER_TOKEN);
} else { } else {
@ -181,7 +212,10 @@ public class ThirdPartyToolServiceImpl implements ThirdPartyToolService {
} }
} }
if (StringUtils.isNotEmpty(portainerToken)) { if (StringUtils.isNotEmpty(portainerToken)) {
ServletUtils.removeHeader(mutate, TokenConstants.Cookie);
ServletUtils.removeHeader(mutate, TokenConstants.AUTHENTICATION);
mutate.header(TokenConstants.AUTHENTICATION, TokenConstants.PREFIX + portainerToken); mutate.header(TokenConstants.AUTHENTICATION, TokenConstants.PREFIX + portainerToken);
mutate.header(TokenConstants.Cookie, String.format("%s;%s;", cookie, portainerToken));
} else { } else {
throw new ServiceException("Portainer服务获取Token失败"); throw new ServiceException("Portainer服务获取Token失败");
} }

View File

@ -1,4 +1,4 @@
package com.microservices.gateway; package com.microservices.gateway.utils;
import com.microservices.common.core.exception.ServiceException; import com.microservices.common.core.exception.ServiceException;
import com.microservices.common.core.threadPool.ThreadPoolExecutorWrap; import com.microservices.common.core.threadPool.ThreadPoolExecutorWrap;