Весна 5 WebClient с использованием ssl


Я пытаюсь найти примеры использования WebClient. Моя цель-использовать Spring 5 WebClient для запроса Службы REST с использованием https и самозаверяющего сертификата

Какой-нибудь пример ?

2 5

2 ответа:

Смотрите пример использованиянебезопасного TrustManagerFactory , который доверяет всем сертификатам X. 509 (включая самозаверяющие) без какой-либо проверки. Важное примечание из документации:

Никогда не используйте этот TrustManagerFactory в производстве. Он предназначен исключительно для тестирования, и поэтому он очень ненадежен.

@Bean
public WebClient createWebClient() throws SSLException {
    SslContext sslContext = SslContextBuilder
            .forClient()
            .trustManager(InsecureTrustManagerFactory.INSTANCE)
            .build();

    ClientHttpConnector httpConnector = new ReactorClientHttpConnector(opt -> opt.sslContext(sslContext));
    return WebClient.builder().clientConnector(httpConnector).build();
}

Другой способ, если вы хотите запрограммировать производственный код, - это создать spring bean, подобный такому, который изменяет введенный webclient, используя настройки с сервера spring-boot для того, где находятся truststore и keystore. В клиенте вам нужно только дать хранилище ключей, если вы используете 2-way-ssl. Не уверен, почему ssl-материал не предварительно настроен и легко вводится, подобно действительно крутым настройкам сервера spring-boot.

import io.netty.handler.ssl.SslContext;
import io.netty.handler.ssl.SslContextBuilder;
.
.
.

  @Bean
  WebClientCustomizer configureWebclient(@Value("${server.ssl.trust-store}") String trustStorePath, @Value("${server.ssl.trust-store-password}") String trustStorePass,
      @Value("${server.ssl.key-store}") String keyStorePath, @Value("${server.ssl.key-store-password}") String keyStorePass, @Value("${server.ssl.key-alias}") String keyAlias) {

    return new WebClientCustomizer() {

      @Override
      public void customize(Builder webClientBuilder) {
        SslContext sslContext;
        try {
          KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
          trustStore.load(new FileInputStream(ResourceUtils.getFile(trustStorePath)), trustStorePass.toCharArray());

          List<Certificate> certificateCollcetion = Collections.list(trustStore.aliases()).stream().filter(t -> {
            try {
              return trustStore.isCertificateEntry(t);
            } catch (KeyStoreException e1) {
              throw new RuntimeException("Error reading truststore", e1);
            }
          }).map(t -> {
            try {
              return trustStore.getCertificate(t);
            } catch (KeyStoreException e2) {
              throw new RuntimeException("Error reading truststore", e2);
            }
          }).collect(Collectors.toList());

          KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
          keyStore.load(new FileInputStream(ResourceUtils.getFile(keyStorePath)), keyStorePass.toCharArray());
          sslContext = SslContextBuilder.forClient()
              .keyManager((PrivateKey) keyStore.getKey(keyAlias, keyStorePass.toCharArray()))
              .trustManager((X509Certificate[]) certificateCollcetion.toArray(new X509Certificate[certificateCollcetion.size()]))
              .build();
        } catch (Exception e) {
          log.error("Error creating web client", e);
          throw new RuntimeException(e);
        }
        ClientHttpConnector connector = new ReactorClientHttpConnector((opt) -> {
          opt.sslContext(sslContext);
        });
        webClientBuilder.clientConnector(connector);
      }
    };
  }

Здесь часть, где вы используете Webclient: импортная организация.весенняя рамка.сеть.реактивный.функция.клиент.WebClient;

@Component
public class ClientComponent {

  public ClientComponent(WebClient.Builder webClientBuilder, @Value("${url}") String url) {
    this.client = webClientBuilder.baseUrl(solrUrl).build();
  }
}