Отсутствует цепочка сертификатов клиента при соединении со службой - PullRequest
0 голосов
/ 06 января 2020

Существует приложение с весенней загрузкой, которое подключается к службе на основе SOAP. Наше приложение имеет прослушиватель MQ, который получает сообщения из локальной очереди. После того как сообщение удалено из этой очереди, оно выполняет API-вызов к службе.

Вся связь с SOAP службой осуществляется через двухсторонний SSL.

Теперь мы столкнулся с проблемой при подключении к услуге SOAP. Отсутствует ошибка цепочки сертификатов клиента, полученная периодически на конце службы SOAP.

В нашем классе JmsConfig мы установили параллелизм на фабрике приемника на 10, как показано ниже для одновременного выполнения и параллельной обработки сообщений из очереди.

 @Bean
 public DefaultJmsListenerContainerFactory jmsListenerContainerFactory(){
   DefaultJmsListenerContainerFactory factory = new DefaultJmsListenerContainerFactory();
   try {
          factory.setConnectionFactory(cachingConnectionFactory(jmsConnectionFactoryX20()));
          factory.setConcurrency("10");
   } catch (JMSException e) {
          e.printStackTrace();
   }
   return factory;
 }

Когда мы дополнительно вызываем службу SOAP из приложения весенней загрузки после использования сообщений, в большинстве журналов службы SOAP появляется ошибка отсутствующей цепочки сертификатов клиента. При массовой загрузке 1k сообщений в очередь и при одновременном выполнении после этого около 850 сообщений завершилось с ошибкой в ​​SOAP конце службы и только 150 прошло.

Ошибка приходит только тогда, когда параллелизм устанавливается программно, как показано через приведенный выше фрагмент кода. Если я закомментирую вызов setConcurrency, все сообщения 1k обрабатываются на SOAP конце службы без какой-либо ошибки цепочки сертификатов.

Не могли бы вы взглянуть на нашу конфигурацию и поделиться некоторыми соображениями о том, почему параллелизм вызывает эта ошибка.

ApplicationWebServiceImpl. java (вызов метода callWebService () из метода прослушивателя JMS)

  import org.springframework.beans.factory.annotation.Autowired;
  import org.springframework.beans.factory.annotation.Value;
  import org.springframework.stereotype.Service;
  import org.springframework.util.StringUtils;
  import org.springframework.ws.client.core.WebServiceTemplate;
  import org.springframework.ws.soap.SoapMessage;

  @Service
  public class ApplicationWebServiceImpl implements ApplicationWebServices {

  @Autowired
  private WebServiceTemplate wsTemplate;

  @Value("${soap.clientEndpoint}")
  private String clientEndpoint;

  @Value("${soap.action}")
  private String soapAction;

  @Override
  public Object callWebService(Object request, String serviceName) throws ClientApplicationException {

      return wsTemplate.marshalSendAndReceive(clientEndpoint + serviceName, request, message -> {
          SoapMessage msg = (SoapMessage) message;
          msg.setSoapAction(soapAction + StringUtils.capitalize(serviceName));
      });
  }
}

ClientApplication (весенняя загрузка основной класс)

@SpringBootApplication
@ComponentScan("com.abc.ca")    
public class ClientApplication {

  @Value(value = "${cert.keyStoreFileName}")
  private String keyStoreFileName;

  @Value(value = "${cert.trustStoreFileName}")
  private String trustStoreFileName;

  @Value(value = "${cert.disabledAlgorithms}")
  private String disabledAlgorithms;

  @PostConstruct
  public void getKeyTrustStore() {
      Security.setProperty("jdk.certpath.disabledAlgorithms", disabledAlgorithms);
      String filePath = Thread.currentThread().getContextClassLoader().getResource(keyStoreFileName).getFile();

      System.setProperty("javax.net.ssl.keyStore", filePath);
      System.setProperty("javax.net.ssl.keyStorePassword", "changeme");
      filePath = Thread.currentThread().getContextClassLoader().getResource(trustStoreFileName).getFile();      

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

  public static void main(String[] args) {
      SpringApplication.run(ClientApplication.class, args);
  }
}

1 Ответ

0 голосов
/ 14 января 2020

Просто чтобы обновить, я решил вышеуказанную проблему, явно вызвав setMessageSender для wsTemplate и установив HttpsUrlConnectionMessageSender.

Спасибо @chughts за указатель.

Приветствия!

 wsTemplate.setMessageSender(httpsUrlConnectionMessageSender());

 @Bean 
 public HttpsUrlConnectionMessageSender httpsUrlConnectionMessageSender() throws Exception { 
     HttpsUrlConnectionMessageSender httpsUrlConnectionMessageSender = new 
                HttpsUrlConnectionMessageSender();

    httpsUrlConnectionMessageSender.setTrustManagers(
            loadDefaultTrustStore());

    httpsUrlConnectionMessageSender.setKeyManagers(
            loadKeyStore());

    httpsUrlConnectionMessageSender.setHostnameVerifier(new HostnameVerifier() { 
       @Override 
       public boolean verify(String hostname, javax.net.ssl.SSLSession sslSession) { 
          if ("localhost".equals(hostname)) { 
            return true; 
          } 
          return false; 
       } 
    });     
    return httpsUrlConnectionMessageSender; 
}

private KeyManager[] loadKeyStore() throws KeyStoreException,
     FileNotFoundException, IOException, NoSuchAlgorithmException,
     CertificateException, UnrecoverableKeyException {

     KeyStore keyStore = KeyStore.getInstance("jks");

     FileInputStream fileInputStreamKeyStore = new FileInputStream("/ca/appKeystore.jks");
     keyStore.load(fileInputStreamKeyStore,"changeme".toCharArray());

     KeyManagerFactory keyFactory = KeyManagerFactory.getInstance(KeyManagerFactory
            .getDefaultAlgorithm());        
     keyFactory.init(keyStore,"changeme".toCharArray());
     return keyFactory.getKeyManagers();
}

private TrustManager[] loadDefaultTrustStore() throws NoSuchAlgorithmException,
                KeyStoreException {
     TrustManagerFactory trustFactory = 
     TrustManagerFactory.getInstance(TrustManagerFactory
        .getDefaultAlgorithm());
     trustFactory.init((KeyStore)null);     
     return trustFactory.getTrustManagers();
}
...