Java >> Java Tutorial >  >> Tag >> HTTP

Nutzung eines SOAP-Webservice über HTTPS

Im vorherigen Beitrag haben wir hier über das Erstellen und Nutzen eines SOAP-Webdienstes gesprochen. Dieser Beitrag wird eine Fortsetzung dieses Beitrags sein, da ich kürzlich während meines Projekts mit einem ähnlichen Problem konfrontiert war. In diesem Beitrag werden wir darüber sprechen, wie man einen SOAP-Webservice über HTTPS nutzt. Da dies ein kleiner Post sein wird, werden wir keinen Code auf GitHub posten.

Problem –

Während Sie einen SOAP-Webdienst nutzen, der hinter SSL steht, werden Sie, wenn Sie keine SSL-Zertifikate handhaben, auf den folgenden Fehler stoßen


sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:387)
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:229)
at sun.security.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:124)
at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1351)
at sun.security.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:156)
at sun.security.ssl.Handshaker.processLoop(Handshaker.java:925)
at sun.security.ssl.Handshaker.process_record(Handshaker.java:860)
at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1043)
at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1343)
at sun.security.ssl.SSLSocketImpl.writeRecord(SSLSocketImpl.java:728)
at sun.security.ssl.AppOutputStream.write(AppOutputStream.java:123)
at sun.security.ssl.AppOutputStream.write(AppOutputStream.java:138)
at SSLPoke.main(SSLPoke.java:31)
Caused by: 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)
... 15 more

Lösung –

Im Grunde tritt dieser Fehler auf, wenn Ihr SOAP-Webdienst auf SSL läuft und der Client versucht, sich mit dem Webdienst zu verbinden, der Webdienst den Client nicht erkennt und diesen Fehler ausgibt.

Um diesen Fehler zu beheben, können Sie ein SSL-Zertifikat von dem Server herunterladen, auf dem Sie den SOAP-Webdienst hosten, und dieses Zertifikat in den Schlüsselspeicher Ihres Clientcomputers importieren. In einer Produktionsumgebung sollten Sie eine Möglichkeit haben, auf diesen Schlüsselspeicher zuzugreifen, wenn ein Aufruf an den Webdienst erfolgt.

Nehmen wir an, dass unser Webdienst von der Post auf SSL läuft, wie https://localhost:8943/benefits/endpoints/users.wsdl . Wenn Sie im Browser auf diese URL zugreifen, können Sie das SSL-Zertifikat sehen. Exportieren Sie dieses SSL-Zertifikat in eine Datei im Base-64-Format, Beispiel sslcertificate.crt . Importieren Sie dieses Zertifikat in

keytool -import -alias sslcertificateofserver -keystore truststore.jks -storepass changeit -file sslcertificate.crt

Nun ändern wir die Konfigurationsklasse, die wir geschrieben haben, um Webservice-Komponenten zu konfigurieren.


package com.betterjavacode.benefits.views;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.oxm.jaxb.Jaxb2Marshaller;

@Configuration
public class ClientAppConfig
{
   private Resource getKeyStore()
   {
     Environment.getProperty("betterjavacode.com.keystore");
   }

   private String getKeystorePassword()
   {
     Environment.getProperty("betterjavacode.com.keyStorePassword");
   }

   @Bean
   public Jaxb2Marshaller marshaller()
   {
     Jaxb2Marshaller marshaller = new Jaxb2Marshaller();
     marshaller.setContextPath("com.betterjavacode.benefits.soap");
     return marshaller;
   }

   @Bean
   public UserClient userClient(Jaxb2Marshaller marshaller) 
   {
     // WSDL URL - http://localhost:8080/benefits/endpoints/users.wsdl
     UserClient uc = new UserClient();
     uc.setDefaultUri("http://localhost:8080/benefits/endpoints/users.wsdl");
     uc.setMarshaller(marshaller);
     uc.setUnmarshaller(marshaller);

     FileInputStream fis = new FileInputStream(getKeyStore());
     KeyStore ks = KeyStore.getInstance("JKS");
     ks.load(fis, getKeyStorePassword().toCharArray());

     try 
     {
       fis.close();
     } 
     catch (IOException e) 
     {
     }
     KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
     keyManagerFactory.init(ks, keyStorePassword.toCharArray());

     FileInputStream fisTS = new FileInputStream(getKeyStore());
     KeyStore ts = KeyStore.getInstance("JKS");
     ts.load(fisTS, trustStorePassword.toCharArray());

     try 
     {
       fisTS.close();
     } 
     catch(IOException e) 
     {
     }
     TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
     trustManagerFactory.init(ts);

     HttpsUrlConnectionMessageSender messageSender = new HttpsUrlConnectionMessageSender();
     messageSender.setKeyManagers(keyManagerFactory.getKeyManagers());
     messageSender.setTrustManagers(trustManagerFactory.getTrustManagers());

     HostNameVerifier hv = new HostNameVerifier(){
        @Override
        public boolean verify( String hostname, SSLSession session)
        {
          return true;
        }
     }
     messageSender.setHostnameVerifier(hv);
     uc.setMessageSender(messageSender);
     return uc;
  } 
}

Diese Änderung sollte den Fehler PKIX-Pfadaufbau fehlgeschlagen beheben .

Schlussfolgerung –

Abschließend haben wir gezeigt, wie man einen SOAP-Webservice über HTTPS nutzt, indem man Keystore- und Truststore-Prüfung während der Laufzeit hinzufügt.

Referenzen

  • Nutzung eines SOAP-Webdienstes – Spring Boot

Java-Tag