Проблема, с которой я столкнулся, похожа на проблему # 640 на GitHub Reaction-netty, и я использовал код, который @violetagg использовал с аргументами JVM для всех параметров хранилища ключей и доверенных сертификатов, а также noOpenSsl = true, но я всегда получаю неверную ошибку сертификата. Я обнаружил точку останова в строке 861 файла sun.security.ssl.ClientHandshaker в методе serverHelloDone, что sslContext.getX509KeyManager () возвращает DummyX509KeyManager, таким образом, не возвращая никаких сертификатов и давая предупреждение: не найден подходящий сертификат - продолжение без проверка подлинности клиента »при сетевой отладке SSL. Вызов того же сервера с помощью AsyncRestTemplate или FeignClient возвращает диспетчер ключей и данные с сервера. Код ClientHandshaker находится в openjdk для версии 1.8. Любые идеи? Я использую:
Reactor Netty версии 0.9.7.RELEASE
Версия JVM (например, java -версия) openjdk версия "1.8.0_252" OpenJDK Runtime Environment (сборка 1.8.0_252 -8u252-b09-1 ~ 18.04-b09) 64-разрядная серверная виртуальная машина OpenJDK (сборка 25.252-b09, смешанный режим)
версия ОС (например, uname -a) Linux m2 4.15.3-041503- generi c # 201802120730 SMP Mon Feb 12 07:31:14 UT C 2018 x86_64 x86_64 x86_64 GNU / Linux
Я использую https. Вот код, который вызывает сервер, созданный из примера, по адресу:
https://www.baeldung.com/x-509-authentication-in-spring-security
String block = WebClient.builder()
.clientConnector(new ReactorClientHttpConnector(
HttpClient.create()
.secure(spec -> spec.sslContext(SslContextBuilder.forClient()))))
.build()
.get()
.uri("https://localhost:8443/user")
.retrieve()
.bodyToMono(String.class)
.block();
У меня установлен сертификат для localhost. Я установил сертификат из информации по адресу: https://www.baeldung.com/x-509-authentication-in-spring-security в хранилище доверенных сертификатов java. Если бы я этого не сделал, я не думаю, что мог бы, чтобы сервер возвращал данные, и все работало, вызывая тот же сервер с помощью AsyncRestTemplate. Следующий код работает для меня, а приведенный выше - нет:
AsyncRestTemplate a = new AsyncRestTemplate();
ListenableFuture<ResponseEntity<String>> exchange = a.exchange("https://localhost:8443/user",
HttpMethod.GET, RequestEntity.EMPTY, String.class);
ResponseEntity<String> block = exchange.get();
Я пытаюсь получить доступ к сайту с помощью клиентского сертификата. Похоже, что делегирование создания SSLContext Netty загружает хранилище доверенных сертификатов, но не хранилище ключей. Если я загружу и добавлю хранилище ключей, все заработает:
String keyStoreLocation = System.getProperty("javax.net.ssl.keyStore");
String keyStorePassword = System.getProperty("javax.net.ssl.keyStorePassword");
KeyStore keyStore = KeyStore.getInstance("JKS");
keyStore.load(new FileInputStream(ResourceUtils.getFile(keyStoreLocation)), keyStorePassword.toCharArray());
// Set up key manager factory to use our key store
KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
keyManagerFactory.init(keyStore, keyStorePassword.toCharArray());
String block = WebClient.builder()
.clientConnector(new ReactorClientHttpConnector(
HttpClient.create()
.secure(spec -> spec.sslContext(SslContextBuilder.forClient()
.keyManager(keyManagerFactory)))))
.build()
.get()
.uri("https://localhost:8443/user")
.retrieve()
.bodyToMono(String.class)
.block();