Spring Cloud Gateway中路由到https后端

Spring Cloud Gateway中路由到https后端
背景

在进行zuul切换到gateway时,由于我们的微服务都是https的,所以需要在网关进行路由时支持https的调用。
实现方案

参考部分官方文档和技术文章,大概罗列出三种可以实施的方案。
方案一

第一种方案,可以在网关进行路由时,进行如下配置信任所有的下游证书:

不过这种方案不安全,不适合正式的生产环境部署。不适用于我们的产品。

spring:
  cloud:
    gateway:
      httpclient:
        ssl:
          useInsecureTrustManager: true # 信任所有证书


方案二

第二种方案,gateway中提供了证书相关的配置,可以使用如下的配置信任证书:

这种方案需要提供pem格式的证书,但是我们的信任库证书都是JKS格式的,需要进行格式转换,这边比较麻烦,也不适合我们的产品。

spring:
  cloud:
    gateway:
      httpclient:
        ssl:
          trustedX509Certificates:
          - cert1.pem
          - cert2.pem


方案三

参照之前很多定制化修改的实现,我们可以覆盖gateway路由到下游的客户端配置,通过阅读源码发现,gateway启动时会装载一个HttpClientFactory类型的bean,这个factory会创建gateway的httpclient。

具体实现:

/**
 * 覆盖gateway默认的httpClient配置 支持jks格式的证书
 * 
 * @author yuanzhihao
 * @since 2022/5/12
 */
@Configuration
@Slf4j
public class GatewayHttpClientConfig {
    @Value("${server.ssl.trust-store}")
    private String trustStore;

    @Value("${server.ssl.trust-store-password}")
    private String trustStorePassword;

    @Value("${server.ssl.trust-store-type}")
    private String trustStoreType;

    @Bean
    @ConditionalOnMissingBean({ HttpClient.class, HttpClientFactory.class })
    public HttpClientFactory gatewayHttpClientFactory(HttpClientProperties properties, ServerProperties serverProperties) {
        TrustManagerFactory trustManagerFactory = getTrustManagerFactory();
        return new CustomHttpClientFactory(properties, serverProperties, Collections.emptyList(), trustManagerFactory);
    }

    // 加载信任库证书
    private TrustManagerFactory getTrustManagerFactory() {
        TrustManagerFactory trustManagerFactory = null;
        try {
            KeyStore keyStore = KeyStore.getInstance(trustStoreType);
            try (FileInputStream inStream = new FileInputStream(ResourceUtils.getFile(trustStore))) {
                keyStore.load(inStream, trustStorePassword.toCharArray());
            }
            trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
            trustManagerFactory.init(keyStore);
        } catch (Exception e) {
            log.error("Init TrustManagerFactory Failed", e);
        }
        return trustManagerFactory;
    }

    private static class CustomHttpClientFactory extends HttpClientFactory {
        private final TrustManagerFactory trustManagerFactory;

        public CustomHttpClientFactory(HttpClientProperties properties, ServerProperties serverProperties,
                                       List<HttpClientCustomizer> customizers, TrustManagerFactory trustManagerFactory) {
            super(properties, serverProperties, customizers);
            this.trustManagerFactory = trustManagerFactory;
        }

        @SneakyThrows
        protected HttpClient configureSsl(HttpClient httpClient) {
            HttpClientProperties.Ssl ssl = properties.getSsl();
            SslContextBuilder sslContextBuilder = SslContextBuilder.forClient();
            // 设置信任证书
            sslContextBuilder.trustManager(trustManagerFactory);
            SslProvider sslProvider = SslProvider.builder()
                    .sslContext(sslContextBuilder.build())
                    .handshakeTimeout(ssl.getHandshakeTimeout())
                    .closeNotifyFlushTimeout(ssl.getCloseNotifyFlushTimeout())
                    .closeNotifyReadTimeout(ssl.getCloseNotifyReadTimeout())
                    .build();
            httpClient = httpClient.secure(sslProvider);
            return httpClient;
        }
    }
}

结语

对于spring cloud中很多的组件,我们可以通过覆盖他提供的默认的bean来定制我们的功能。
原文链接:https://blog.csdn.net/qq_32238611/article/details/124743138

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Spring Cloud Gateway路由配置是通过配置文件或者代码的方式来定义的。下面分别介绍这两种方式。 **配置文件方式** 在 Spring Cloud Gateway 路由配置保存在 application.yml 或者 application.properties 文件。下面是一个简单的路由配置示例: ```yaml spring: cloud: gateway: routes: - id: service1 # 路由 ID uri: http://localhost:8081 # 目标服务地址 predicates: - Path=/service1/** # 匹配的请求路径 - id: service2 uri: http://localhost:8082 predicates: - Path=/service2/** ``` 这个配置文件定义了两个路由规则,分别将 /service1/** 和 /service2/** 路径的请求转发到对应的服务地址。 **代码方式** 除了配置文件,您还可以使用代码的方式来定义路由规则。下面是一个简单的代码示例: ```java @Configuration public class GatewayConfig { @Bean public RouteLocator customRouteLocator(RouteLocatorBuilder builder) { return builder.routes() .route("service1", r -> r.path("/service1/**") .uri("http://localhost:8081")) .route("service2", r -> r.path("/service2/**") .uri("http://localhost:8082")) .build(); } } ``` 这个代码片段定义了两个路由规则,和配置文件的效果是一样的。 无论是使用配置文件还是代码方式,都可以实现灵活的路由配置。除了基于路径的路由规则,Spring Cloud Gateway 还支持基于请求头、请求参数、请求方法等方式的路由匹配。您可以根据具体的需求来选择相应的路由规则。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值