Мое приложение — 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
Когда я создаю экземпляр 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;
}
}
Однако некоторые из серверы, с которыми мне нужно взаимодействовать, имеют либо старую/другую версию JDK, либо включен TLSv1.2 (у меня нет этих сторонних API).
Потому что я получаю:
Код: Выделить всё
io.netty.handler.codec.DecoderException: javax.net.ssl.SSLHandshakeException: extension (5) should not be presented in certificate_request
Код: Выделить всё
@SpringBootApplication
public class MyApplication {
public static void main(String[] args) {
System.setProperty("jdk.tls.client.protocols", "TLSv1.2");
SpringApplication.run(MyApplication.class);
}
Мой вопрос: вместо установки системного свойства могу ли я просто добиться то же самое с веб-клиентом на уровне кода, пожалуйста?
Спасибо
Подробнее здесь: https://stackoverflow.com/questions/662 ... er-tlsv1-2
Мобильная версия