gpt4 book ai didi

spring-boot - 启用 Spring webclient 以通过 HTTPS 与其他启用 TLS 的服务进行通信

转载 作者:行者123 更新时间:2023-12-04 15:21:14 25 4
gpt4 key购买 nike

我有 2 个服务 A 和 B,它们应该通过 HTTPS 相互通信。
我已经为这两个应用程序使用 Spring Boot 的 server.ssl.* 属性启用了 TLS。
我正在使用 WebClient 进行通信,其中服务 A 将使用 webclient 调用 B,而 B 会将响应发送回 A。
对于通过 TLS 进行的通信,我的理解是 Webclient 需要信任库数据,该数据将具有被调用服务的证书,即服务 B。

import java.io.FileInputStream;
import java.io.IOException;
import java.nio.file.Paths;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;

import javax.net.ssl.SSLException;
import javax.net.ssl.TrustManagerFactory;

import org.springframework.boot.web.server.Ssl;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.client.reactive.ReactorClientHttpConnector;
import org.springframework.web.reactive.function.client.WebClient;


import io.netty.handler.ssl.SslContext;
import io.netty.handler.ssl.SslContextBuilder;
import lombok.extern.slf4j.Slf4j;
import reactor.netty.http.client.HttpClient;


@Slf4j
@Configuration
public class WebClientConfig {

private final Ssl ssl;

public WebClientConfig(final Ssl ssl) {
this.ssl = ssl;
}

@Bean
public WebClient createWebClient() throws Exception {

if (ssl.isEnabled()) {

return buildSslEnabledWebClient();

}

return WebClient.builder().build();
}

private WebClient buildSslEnabledWebClient() throws Exception {

final String trustStorePath = ssl.getTrustStore();
final String trustStorePassword = ssl.getTrustStorePassword();
final KeyStore trustStore = createKeyStore(trustStorePath, trustStorePassword);

try {

final TrustManagerFactory trustManager = TrustManagerFactory
.getInstance(TrustManagerFactory.getDefaultAlgorithm());
trustManager.init(trustStore);

final SslContext sslContext = SslContextBuilder.forClient().trustManager(trustManager)
.build();

final HttpClient httpClient = HttpClient.create().secure(ssl -> {
ssl.sslContext(sslContext);
});

return WebClient.builder().clientConnector(new ReactorClientHttpConnector(httpClient)).build();

} catch (NoSuchAlgorithmException | KeyStoreException | SSLException e) {
log.error("Could not initialize Webclient with the trustore data", e);
throw e;
}
}

private static KeyStore createKeyStore(final String keyStoreLocation, final String keyStorePassword) {

try (FileInputStream fis = new FileInputStream(keyStoreLocation)) {

final KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());

ks.load(fis, keyStorePassword.toCharArray());

return ks;

} catch (KeyStoreException | NoSuchAlgorithmException | CertificateException | IOException e) {
throw new IllegalArgumentException(e);
}
}
}
我已经使用 keytool 创建了自签名证书,这似乎有效。我可以从 A 向 B 打一个电话,然后回复。
但是我不知何故觉得设置不完整,因此我的问题是:
  • 我错过了什么?
  • 这是正确的方法吗?
  • 这会在生产中使用真正的证书吗?

  • 更新:修复了代码,在阅读下面的答案后意识到了错误。我实际上正在使用更新的代码。

    最佳答案

    在我看来,您正在正确加载 keystore 文件并使用 keystore 对象正确初始化 trustmanagerfactory。
    但是,您没有使用 trustmanagerfactory 来配置您的 httpclient。取而代之的是,您再次从文件中加载 keystore ,同时将其作为对象传递给方法 SslContextBuilder.forClient().trustManager .但是,这将不起作用,因为此方法需要一个包含 PEM 格式的受信任证书列表的文件,而您正在传递一个 keystore 。 javadoc 包含以下文档:

    public SslContextBuilder trustManager(java.io.File trustCertCollectionFile)

    Trusted certificates for verifying the remote endpoint's certificate. The file should contain an X.509 certificate collection in PEM format. null uses the system default.
    如果您正在加载 PEM 格式的文件,那么您发布的示例将起作用。如果您正在加载 keystore 文件,我建议您使用以下代码段:
    final TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
    trustManagerFactory.init(trustStore);

    final SslContext sslContext = SslContextBuilder.forClient()
    .trustManager(trustManagerFactory)
    .build();

    final HttpClient httpClient = HttpClient.create()
    .secure(ssl -> {
    ssl.sslContext(sslContext);
    });

    关于spring-boot - 启用 Spring webclient 以通过 HTTPS 与其他启用 TLS 的服务进行通信,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63277211/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com