栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Spring Cloud Gateway中路由到https后端

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Spring Cloud Gateway中路由到https后端

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

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

实现方案

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

方案一

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

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

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

方案二

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

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

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

方案三

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

具体实现:

@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 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://docs.spring.io/spring-cloud-gateway/docs/current/reference/html/#tls-and-ssl

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/885791.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号