Доступ к службе HTTPS RESTful с помощью веб-клиента в Spring Boot 2.0 - PullRequest
2 голосов
/ 22 апреля 2020

Мне нужно получить доступ к одной веб-службе отдыха https (https://example.com), для которой клиент предоставил сертификат, содержащий 2 файла .cer.

Я создал keystore.jks и truststore.jks файлы и imported the .cer files to jks file. с помощью приведенной ниже команды

keytool -genkeypair -alias abcd -keyalg RSA -sigalg garegar -keysize 2048 -storetype jks -keystore keystore.jks -validity 365 -storepass changeit

keytool -import -alias abcd -trustcacerts -file free/ca_bundle.cer -keystore keystore.jksccessfull

я добавил все свойства в application.yml

   truststore-location: 
   keystore-location: 
   truststore-password: 
   keystore-password: 
   key-alias:

Создание компонента в классе конфигурации для получения объекта webclient.

@Data
@NoArgsConstructor
@AllArgsConstructor
@Configuration
public class WebServiceRestConfig {

    @Value(value = "${wcc.rest.endpoint}")
    private String url;

    @Value(value = "${wcc.dam.username}")
    private String username;

    @Value(value = "${wcc.dam.password}")
    private String password;

    @Value(value = "${ssl.truststore-location}")
    private String trustStore;

    @Value(value = "${ssl.keystore-location}")
    private String keyStore;

    @Value(value = "${ssl.truststore-password}")
    private String trustStorePassword;

    @Value(value = "${ssl.keystore-password}")
    private String keyStorePassword;

    @Value(value = "${ssl.key-alias}")
    private String keyAlias;




    @Bean
    WebClientCustomizer configureWebclient() {

        return (WebClient.Builder webClientBuilder) -> {
            SslContext sslContext;
            final PrivateKey privateKey;
            final X509Certificate[] certificates;
            try {
                final KeyStore trustStore;
                final KeyStore keyStore;
                trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
                trustStore.load(new FileInputStream(ResourceUtils.getFile(getTrustStore())),
                        trustStorePassword.toCharArray());
                keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
                keyStore.load(new FileInputStream(ResourceUtils.getFile(getKeyStore())), keyStorePassword.toCharArray());
                List<Certificate> certificateList = 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());
                certificates = certificateList.toArray(new X509Certificate[certificateList.size()]);
                privateKey = (PrivateKey) keyStore.getKey(keyAlias, keyStorePassword.toCharArray());
                Certificate[] certChain = keyStore.getCertificateChain(keyAlias);
                X509Certificate[] x509CertificateChain = Arrays.stream(certChain)
                        .map(certificate -> (X509Certificate) certificate).collect(Collectors.toList())
                        .toArray(new X509Certificate[certChain.length]);
                sslContext = SslContextBuilder.forClient().keyManager(privateKey, keyStorePassword, x509CertificateChain)
                        .trustManager(certificates).build();

                HttpClient httpClient = HttpClient.create()
                        .secure(sslContextSpec -> sslContextSpec.sslContext(sslContext));
                ClientHttpConnector connector = new ReactorClientHttpConnector(httpClient);
                webClientBuilder.clientConnector(connector).baseUrl(getUrl()).build();

            } catch (KeyStoreException e) {
                throw new RuntimeException(e);
            }catch(CertificateException e) {
                throw new RuntimeException(e);
            }catch(NoSuchAlgorithmException e) {
                throw new RuntimeException(e);
            }catch(IOException e) {
                throw new RuntimeException(e);
            }catch(UnrecoverableKeyException e) {
                throw new RuntimeException(e);
            }
        };
    }

}

Но когда я запускаю приложение, я получаю исключение ниже

SEVERE: Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is reactor.core.Exceptions$ReactiveException: javax.net.ssl.SSLHandshakeException: General SSLEngine problem] with root cause
sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
    at sun.security.provider.certpath.SunCertPathBuilder.build(SunCertPathBuilder.java:145)
    at sun.security.provider.certpath.SunCertPathBuilder.engineBuild(SunCertPathBuilder.java:131)
    at java.security.cert.CertPathBuilder.build(CertPathBuilder.java:280)
    at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:382)
    at sun.security.validator.PKIXValidator.engineValidate(PKIXValidator.java:292)
    at sun.security.validator.Validator.validate(Validator.java:260)
    at sun.security.ssl.X509TrustManagerImpl.validate(X509TrustManagerImpl.java:324)
    at sun.security.ssl.X509TrustManagerImpl.checkTrusted(X509TrustManagerImpl.java:281)
    at sun.security.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:136)
    at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1465)
    at sun.security.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:212)
    at sun.security.ssl.Handshaker.processLoop(Handshaker.java:969)

Прямо сейчас я совершенно не понимаю, что делать и как решить эту проблему. Мне нужно добавить что-нибудь в папку ресурсов или я здесь чего-то не хватает?

...