2017-10-19 2 views
0

J'ai une application client SOAP simple qui fonctionne parfaitement. Mais quand je mets son morceau de code dans un autre projet web (Tomcat 8.5), ça ne marche pas. Il émet une exception:Erreur avec les demandes de savon sur tomcat

19-Oct-2017 11: 10: 48,019 GRAVES [http-nio-8080-exec-10] com.sun.xml.messaging.saaj.client.p2p.HttpSOAPConnection. post SAAJ0008: Mauvaise réponse; Interdit Ошибка при отправке сообщения SOAP-серверу: com.sun.xml.messaging.saaj.SOAPExceptionImpl: com.sun.xml.messaging.saaj.SOAPExceptionImpl: Bad réponse: (403Forbidden à com.sun.xml. messaging.saaj.client.p2p.HttpSOAPConnection.call (HttpSOAPConnection.java:164) à ls.common.objects.SOAPMessageSender.callSoapWebService (SOAPMessageSender.java:72) à ls.webSite.common.servlets.cli_GetMKBClientByIIN. processRequests (cli_GetMKBClientByIIN.java:49) at common.servlets.prototypes.AbstractServlet.processRequest (AbstractServlet.java:369) at on.servlets.prototypes.AbstractServlet.doPost (AbstractServlet.java:503) à javax.servlet.http.HttpServlet.service (HttpServlet.java:661) à javax.servlet.http.HttpServlet.service (HttpServlet.java: 742) à org.apache.catalina.core.ApplicationFilterChain.internalDoFilter (ApplicationFilterChain.java:231) à org.apache.catalina.core.ApplicationFilterChain.doFilter (ApplicationFilterChain.java:166) à org.apache. tomcat.websocket.server.WsFilter.doFilter (WsFilter.java:52) à org.apache.catalina.core.ApplicationFilterChain.internalDoFilter (ApplicationFilterChain.java:193) à org.apache.catalina.core.ApplicationFilterChain. DoFilter (ApplicationFi lterChain.java:166) à org.apache.catalina.core.StandardWrapperValve.invoke (StandardWrapperValve.java:198) à org.apache.catalina.core.StandardContextValve.invoke (StandardContextValve.java:96) à org.apache.catalina.authenticator.AuthenticatorBase.invoke (AuthenticatorBase.java:478) à org.apache.catalina.core.StandardHostValve.invoke (StandardHostValve.java:140) à org.apache.catalina.valves .ErrorReportValve.invoke (ErrorReportValve.java:80) à org.apache.catalina.valves.AbstractAccessLogValve.invoke (AbstractAccessLogValve.java:650) à org.a pache.catalina.core.StandardEngineValve.invoke (StandardEngineValve.java:87) à org.apache.catalina.connector.CoyoteAdapter.service (CoyoteAdapter.java:342) à org.apache.coyote.http11.Http11Processor. Service (Http11Processor.java:799) à org.apache.coyote.AbstractProcessorLight.process (AbstractProcessorLight.java:66) à org.apache.coyote.AbstractProtocol $ ConnectionHandler.process (AbstractProtocol.java:868) à org.apache.tomcat.util.net.NioEndpoint $ SocketProcessor.doRun (NioEndpoint.java:1457) à org.apache.tomcat.util.net.SocketProcessorBase.run (SocketProcessorBase.java:49) à java.util.concurrent.ThreadPoolExecutor.runWorker (ThreadPoolExecutor.java:1149) à java.util.concurrent.ThreadPoolExecutor $ Worker.run (ThreadPoolExecutor.java: 624) à org.apache.tomcat.util.threads.TaskThread $ WrappingRunnable.run (TaskThread.java:61) à java.lang.Thread.run (Thread.java:748) Causé par: com .sun.xml.messaging.saaj.SOAPExceptionImpl: Bad réponse: (403Forbidden à com.sun.xml.messaging.saaj.client.p2p.HttpSOAPConnection.post (HttpSOAPConnection.java:276) à com.sun. xml.messaging.saaj.client.p2p.HttpSOAPConnection.call (HttpSOAPConnection.java:160) ... 28 plus

Pourquoi cela ne fonctionne pas sur le projet web? Est-il un problème keystore? ici je s exemple de mon code:

public class InsuranceSOAPMessageCreator { 

    public static SOAPMessage createSOAPMessageFromXML(String soapActionFull, String sourceXmlFile, Map<String, String> params) 
      throws IOException, SOAPException { 

     Path path = Paths.get(sourceXmlFile); 
     String xml = new String(Files.readAllBytes(path)); 

     MessageFactory mf = MessageFactory.newInstance(); 

     if(params != null){ 
      for(Map.Entry entry : params.entrySet()){ 
       xml = xml.replace("##$[" + entry.getKey().toString() + "]$##", entry.getValue().toString()); 
      } 
     } 

     SOAPMessage msg = mf.createMessage(new MimeHeaders(), 
       new ByteArrayInputStream(xml.getBytes(Charset.forName("UTF-8")))); 

     msg.getMimeHeaders().addHeader("SOAPAction", soapActionFull); 

     return msg; 
    } 


} 

public class SOAPMessageSender { 

     private String nameSpaceURI; 
     private String endpointUrl; 
     private String trustStore; 
     private String trustStorePassword; 
     private String keyStore; 
     private String keyStorePassword; 
     private SOAPMessage soapResponse; 

     public SOAPMessageSender(){ 
     } 

     public SOAPMessageSender(String endpointUrl, String nameSpaceURI, String trustStore, String trustStorePassword, 
           String keyStore, String keyStorePassword){ 

      this.nameSpaceURI = nameSpaceURI; 
      this.keyStorePassword = keyStorePassword; 
      this.keyStore = keyStore; 
      this.trustStorePassword = trustStorePassword; 
      this.trustStore = trustStore; 
      this.endpointUrl = endpointUrl; 
      setSystemProperties(); 
     } 

     public void setSystemProperties(){ 
      System.setProperty("java.protocol.handler.pkgs", "com.sun.net.ssl.internal.www.protocol"); 
      System.setProperty("com.ibm.ssl.performURLHostNameVerification", "true"); 

      System.setProperty("javax.net.ssl.trustStore", trustStore); 
      System.setProperty("javax.net.ssl.trustStorePassword", trustStorePassword); 

      System.setProperty("javax.net.ssl.keyStore", keyStore); 
      System.setProperty("javax.net.ssl.keyStorePassword",keyStorePassword); 
      System.setProperty("javax.net.ssl.keyStoreType", "jks"); 
     } 

     public String callSoapWebService(String soapAction, String sourceXml, Map<String, String> params) { 

      try { 

       SOAPConnectionFactory scf = SOAPConnectionFactory.newInstance(); 
       SOAPConnection sc = scf.createConnection(); 
       /*SOAPMessage requestMsg = createSOAPMessageFromXML(nameSpaceURI + "/" + soapAction, 
         sourceXml, params);*/ 
       //doTrustToCertificates(); 
       soapResponse = sc.call(InsuranceSOAPMessageCreator.createSOAPMessageFromXML(soapAction, 
         sourceXml, params), endpointUrl); 

       ByteArrayOutputStream out = new ByteArrayOutputStream(); 
       soapResponse.writeTo(out); 

       sc.close(); 

       return out.toString(); 

      } catch (Exception e) { 
       System.err.println("Ошибка при отправке сообщения SOAP-серверу:" + endpointUrl); 
       e.printStackTrace(); 
      } 

      return null; 
     } 

     ... 

     public static void main(String[] args){ 
      //works fine here (on local run main method) 
      Map <String, String> authenticationData = new HashMap<>(); 
      authenticationData.put("login", "user"); 
      authenticationData.put("password", "pass"); 

      SOAPMessageSender me = new SOAPMessageSender("https://somehost/someservice.asmx", 
        "https://someuri", 
        "/usr/lib/jvm/java-8-oracle/jre/lib/security/cacerts", 
        "password", 
        "/path/to/mykey.jks", 
        "password"); 
      String resultXml = me.callSoapWebService("someaction", 
        "/path/to/AuthenticateUser.xml", authenticationData); 
      System.out.println(resultXml); 
     } 
    } 

Répondre

0

problème est résolu. Tomcat n'a tout simplement pas pu obtenir le fichier jks spécifié dans System.setProperty() et je l'ai résolu en utilisant l'objet java.security.KeyStore. Voici ma méthode ajoutée:

public void loadKeyStoreAndDoTrustToCertificates(String ksFile, String ksPass, String tsAlgo) throws Exception { 
     FileInputStream ksCert = new FileInputStream(ksFile); 

     KeyStore ks = KeyStore.getInstance(keyStoreType); 
     ks.load(ksCert, ksPass.toCharArray()); 
     KeyManagerFactory kmf = KeyManagerFactory.getInstance(tsAlgo); 
     kmf.init(ks, ksPass.toCharArray()); 

     TrustManagerFactory tmf = TrustManagerFactory.getInstance(tsAlgo); 
     tmf.init(ks); 

     Security.addProvider(new com.sun.net.ssl.internal.ssl.Provider()); 

     SSLContext sc = SSLContext.getInstance("SSL"); 
     sc.init(kmf.getKeyManagers(), null, new SecureRandom()); 

     HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory()); 
     HostnameVerifier hv = new HostnameVerifier() { 
      public boolean verify(String urlHostName, SSLSession session) { 
       if (!urlHostName.equalsIgnoreCase(session.getPeerHost())) { 
        System.out.println("Ошибка: URL хост '" + urlHostName + "' отличается SSL хоста'" + session.getPeerHost() + "'."); 
       } 
       return true; 
      } 
     }; 
     HttpsURLConnection.setDefaultHostnameVerifier(hv); 
    }