Я настраиваю JAX-WS с помощью собственной фабрики SSL:
Map<String, Object> requestContext = ((BindingProvider) port).getRequestContext();
SSLSocketFactory sslSocketFactory = sslSocketFactoryGenerator.getSSLSocketFactory();
requestContext.put("com.sun.xml.internal.ws.transport.https.client.SSLSocketFactory",sslSocketFactory);
requestContext.put("com.sun.xml.ws.transport.https.client.SSLSocketFactory", sslSocketFactory);
Метод getSSLSocketFactory()
делает следующее:
SSLContext sslContext = SSLContext.getInstance("TLSv1.2");
sslContext.init(keyManagers, trustManagers, new SecureRandom());
return sslContext.getSocketFactory();
trustManagers
построен следующим образом:
TrustManagerFactory tmFact = TrustManagerFactory.getInstance(
TrustManagerFactory.getDefaultAlgorithm());
tmFact.init(getTrustStore());
return tmFact.getTrustManagers();
Метод getTrustStore()
:
KeyStore getKeyStore() throws KeyStoreException, NoSuchAlgorithmException, CertificateException, IOException
{
try(FileInputStream fis = new FileInputStream(trustStorePath))
{
KeyStore ks = KeyStore.getInstance("jks");
ks.load(fis, getTrustStorePass().toCharArray());
return ks;
}
}
Когда я сейчас выполняю запрос SOAP, я вижу следующий журнал отладки SSL:
trustStore is: /etc/pki/java/cacerts
trustStore type is : jks
trustStore provider is :
init truststore
Путь trustStore отличается от того, который я указал, предположительно, по умолчанию. Этот trustore не содержит сертификатов, которые мне нужны, поэтому мое соединение SSL не удается.
Когда я запускаю приложение с настройкой системных свойств SSL:
-Djavax.net.ssl.trustStore=/my/path/to/trustore
-Djavax.net.ssl.trustStorePassword=myPass
тогда все работает правильно.
Что я делаю не так? Нужно ли настраивать JAX-WS по-другому?
Я размещаю приложение в Tomcat 9, openjdk-1.8 в Amazon AMI linux.
UPDATE
Нашел решение для этого. На самом деле мы используем реализацию JAX-WS Apache CXF. Он в значительной степени игнорирует настройку JAX-WS com.sun.xml.ws.transport.https.client.SSLSocketFactory
. Я исправил это путем создания пользовательских свойств и передал его контексту:
TLSClientParameters tlsParams = new TLSClientParameters();
tlsParams.setUseHttpsURLConnectionDefaultSslSocketFactory(false);
tlsParams.setSSLSocketFactory(sslSocketFactory);
requestContext.put(TLSClientParameters.class.getName(), tlsParams);
Та же проблема обсуждалась здесь:
Реализация JAXWS в Wildfly, похоже, игнорирует свойство bindingProvider com.sun.xml.ws.transport.https.client.SSLSocketFactory