Не удалось заставить Webclient работать с SSL - PullRequest
1 голос
/ 19 июня 2020

Проблема, с которой я столкнулся, похожа на проблему # 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();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...