![](/img/trans.png)
[英]Spring Webflux WebClient - Specify the TLS version (between TLSv1.2 and TLSv1.3) used when sending outbound request
[英]Spring Webflux - WebClient over TLSv1.2
关于 Spring Webflux WebClient 的小问题,尤其是如何配置一个使用 TLSv1.2 发送出站请求。
我的应用是 Spring Webflux 2.4.2,其中启用了 HTTP/2、SSL、mTLS 和 TLSv1.3。
server.ssl.enabled-protocols=TLSv1.3
server.http2.enabled=true
server.ssl.client-auth=need
server.ssl.enabled=true
server.ssl.key-alias=alias
server.ssl.key-password=
server.ssl.key-store-password=
server.ssl.key-store-provider=SUN
server.ssl.key-store-type=JKS
server.ssl.key-store=/keystore.p12
server.ssl.trust-store-password=
server.ssl.trust-store-provider=SUN
server.ssl.trust-store-type=JKS
server.ssl.trust-store=/truststore.p12
请注意,它是 TLSv1.3,而不是设置上的 TLSv1,2。
当我创建 WebClient 的实例时:
getWebClient().mutate().baseUrl("https://some-server.com").build().post().uri("/some/route").retrieve().bodyToMono(String.class);
@Bean
@Primary
public WebClient getWebClient() {
return WebClient.create().mutate().defaultHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE, HttpHeaders.ACCEPT, MediaType.APPLICATION_JSON_VALUE).clientConnector(new ReactorClientHttpConnector(HttpClient.create().secure(sslContextSpec -> sslContextSpec.sslContext(getSslContextBuilder())))).build();
}
public SslContextBuilder getSslContextBuilder() {
try {
final KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
try (InputStream file = new FileInputStream(keyStorePath)) {
final KeyStore keyStore = KeyStore.getInstance(keyStoreType);
keyStore.load(file, keyStorePassPhrase.toCharArray());
keyManagerFactory.init(keyStore, keyPassPhrase.toCharArray());
}
final TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
try (InputStream trustStoreFile = new FileInputStream(trustStorePath)) {
final KeyStore trustStore = KeyStore.getInstance(trustStoreType);
trustStore.load(trustStoreFile, trustStorePassPhrase.toCharArray());
trustManagerFactory.init(trustStore);
}
final ApplicationProtocolConfig applicationProtocolConfig = new ApplicationProtocolConfig(ApplicationProtocolConfig.Protocol.ALPN, ApplicationProtocolConfig.SelectorFailureBehavior.NO_ADVERTISE, ApplicationProtocolConfig.SelectedListenerFailureBehavior.ACCEPT, ApplicationProtocolNames.HTTP_2, ApplicationProtocolNames.HTTP_1_1);
return SslContextBuilder.forClient().applicationProtocolConfig(applicationProtocolConfig).keyManager(keyManagerFactory).trustManager(InsecureTrustManagerFactory.INSTANCE);
} catch (CertificateException | NoSuchAlgorithmException | IOException | KeyStoreException | UnrecoverableKeyException e) {
return null;
}
}
并使用它向启用了 TLSv1.3 的服务器发送请求,它工作正常,非常高兴。
但是,我需要与之交互的一些服务器要么具有旧的/不同的 JDK 版本,要么启用了 TLSv1.2(我不拥有那些第三方 API)。
因为我得到:
io.netty.handler.codec.DecoderException: javax.net.ssl.SSLHandshakeException: extension (5) should not be presented in certificate_request
在 SO 中研究后,我发现我可以配置这样的。
@SpringBootApplication
public class MyApplication {
public static void main(String[] args) {
System.setProperty("jdk.tls.client.protocols", "TLSv1.2");
SpringApplication.run(MyApplication.class);
}
令人惊讶的是,问题已解决(不知道为什么)。
我的问题是:我可以简单地在代码级别上使用 WebClient 实现相同的功能,而不是设置系统属性吗?
谢谢
截至今天, System.setProperty("jdk.tls.client.protocols", "TLSv1.2");
是解决方案
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.