Конфигурирование HostnameVerifier с сетью реакторов для Spring-webflux WebClient

Я пытаюсь настроить Spring-webflux WebClient (с сетью реакторов под капотом) с помощью проверки ssl и клиента. Мне предоставляется javax.net.ssl.SSLContext, HostnameVerifier и список доверенных имен хостов (в виде списка строк).

Пока я настроил WebClient с моим SSLContext, но не могу найти способ настройки проверки имени хоста.

Чтобы указать мою проблему: у меня есть набор имен имен доверенных сервисов (список строк) и HostnameVerifier. Я хочу настроить его с помощью WebClient.

Есть ли возможность сделать это с помощью javax.net.ssl.HostnameVerifier? Существует ли альтернативный подход в нетрезводимости реактора?

Это то, что у меня есть до сих пор:

WebClient.builder()
  .clientConnector(
    new ReactorClientHttpConnector(
      opt -> opt.sslContext(new JdkSslContext(mySSLContext, 
                      true, ClientAuth.OPTIONAL))))
  .build();

Ответ 1

Вы должны предоставить действительный сертификат центра сертификации (trustManager()) и, при необходимости, пользовательский сертификат с секретным ключом и паролем закрытого ключа для авторизации (keyManager()). Ваш сертификат SSL службы должен быть подписан тем же CA, который вы определили в trustManager().

Имена хостов автоматически проверяются с помощью имени хоста сервиса. Если нет совпадения с java.security.cert.CertificateException: No subject alternative names present не будут java.security.cert.CertificateException: No subject alternative names present. На самом деле я не могу найти способ пропустить проверку имен хостов (не пропуская проверку всего сертификата SSL с помощью .trustManager(InsecureTrustManagerFactory.INSTANCE)).

Я проверил это решение локально. Мой веб-сервис работает на моем локальном компьютере, но его сертификат SSL содержит только DNS-имя, а не IP-адрес. Поэтому для целей отладки я добавил запись в файл hosts и сопоставил IP-адрес службы с правильным DNS-именем.

SslContext sslContext = SslContextBuilder
        .forClient()
        .trustManager(new FileInputStream(caPath))
        .keyManager(
                new FileInputStream(userCertPath),
                new FileInputStream(userPrivateKeyPath),
                userPrivateKeyPassword
        )
        .build();

HttpClient httpClient = HttpClient.create()
        .secure(t -> t.sslContext(sslContext));

WebClient webClient = WebClient.builder()
        .clientConnector(new ReactorClientHttpConnector(httpClient))
        .build();