Как программно установить SSLContext клиента JAX-WS?
====================================================

Я работаю на сервере в распределенном приложении, которое имеет браузерные клиенты, а также участвует в межсерверной связи с третьей стороной.
У моего сервера есть сертификат, подписанный ЦС, который позволяет моим клиентам подключаться по протоколу TLS (SSL) с использованием HTTP / S и XMPP (безопасный). Это все работает нормально.

Теперь мне нужно безопасно подключиться к стороннему серверу, используя JAX-WS через HTTPS / SSL. В этом сообщении мой сервер действует как клиент в взаимодействии JAX-WS, а я - клиентский сертификат, подписанный третьей стороной.

Я попытался добавить новое хранилище ключей через стандартную конфигурацию системы (`-Djavax.net.ssl.keyStore=xyz`) но другие мои компоненты явно затронуты этим. Хотя мои другие компоненты используют выделенные параметры для их конфигурации SSL (`my.xmpp.keystore=xxx, my.xmpp.truststore=xxy, ...`), кажется, что они в конечном итоге используют глобальный`SSLContext`, (Пространство имен конфигурации`my.xmpp.` казалось, указывает на разделение, но это не так)

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

Я думаю, что мой единственный оставшийся вариант - программно подключиться к конфигурации HTTPS JAX-WS для настройки хранилища ключей и доверенных сертификатов для взаимодействия клиента JAX-WS.

Любые идеи / указатели о том, как это сделать? Вся информация, которую я нахожу, либо использует`javax.net.ssl.keyStore` метод или установка глобального`SSLContext` что, я думаю, все закончится тем же конфликтом. Самым близким, что я получил к чему-то полезному, был этот старый отчет об ошибках, который запрашивает нужную мне функцию:[Добавить поддержку для передачи SSLContext в среду выполнения клиента JAX-WS](http://bugs.sun.com/view_bug.do;jsessionid=329a8cda29e5d3927a6a32edadeb?bug_id=6384251)

Любой берет?

Чтобы решить эту проблему, потребовалось`KeyManager` и`SSLSocketFactory` который использует этот обычай`KeyManager` чтобы получить доступ к разделенным`KeyStore`.
I found the base code for this `KeyStore` а также`SSLFactory` на этой отличной записи в блоге:
[как к динамически выбрать-а-сертификат псевдоним, когда-вызывающий-веб-служб](https://alesaudate.wordpress.com/2010/08/09/how-to-dynamically-select-a-certificate-alias-when-invoking-web-services/)

Затем специализированные`SSLSocketFactory` необходимо вставить в контекст WebService:

Где`getCustomSocketFactory()` возвращает`SSLSocketFactory` создан с использованием метода, упомянутого выше. Это будет работать только для JAX-WS RI из встроенного в JDK пакета Sun-Oracle, учитывая, что строка, указывающая`SSLSocketFactory` собственность является частной собственностью для этой реализации.

На этом этапе связь службы JAX-WS защищена через SSL, но если вы загружаете WSDL с того же защищенного сервера (), то у вас возникнет проблема с загрузкой, так как HTTPS-запрос на сбор WSDL не будет использоваться те же учетные данные, что и веб-службы. Я обошел эту проблему, сделав WSDL локально доступным (file: /// ...) и динамически изменив конечную точку веб-службы: (можно найти хорошее обсуждение того, зачем это нужно)[на этом форуме](http://cxf.547215.n5.nabble.com/Why-does-a-JAX-WS-client-use-the-WSDL-at-run-time-tp548595p548596.html))

Теперь WebService загружается и может обмениваться данными через SSL с аналогом сервера, используя именованный (псевдоним) Client-Certificate и взаимную аутентификацию. & # X220E;



Но другая собственность работала как шарм:

Остальная часть кода была взята из первого ответа.



 если ваш WSDL не доступен и с https: //.

Вот мой обходной путь для этого:

Установите SSLSocketFactory по умолчанию:

Для Apache CXF, который я использую, вам также необходимо добавить эти строки в ваш конфиг:



ботчик мыла

Это мой пример, делай все сетевые операции

Он использует UrlConnection, вы можете использовать любую библиотеку, которую вы хотите в обработчике.
Повеселись!



 кто пытается и до сих пор не работает, это было сделано для меня с Wildfly 8, используя динамический`Dispatcher`:

`bindingProvider.getRequestContext().put("com.sun.xml.ws.transport.https.client.SSLSocketFactory", yourSslSocketFactory);`

Обратите внимание, что`internal` часть от Ключа собственности пропала здесь.



[http://jyotirbhandari.blogspot.com/2011/09/java-error-invalidalgorithmparameterexc.html](https://jyotirbhandari.blogspot.com/2011/09/java-error-invalidalgorithmparameterexc.html)

И это решило проблему. Я сделал несколько небольших изменений - я установил два параметра, используя System.getProperty ...



[эта почта](https://stackoverflow.com/questions/6810634/how-to-make-simple-ssl-thru-web-services) с некоторыми незначительными изменениями. Это решение не требует создания каких-либо дополнительных классов.



 вы можете получить доступ к WSDL за https:



йке диспетчера доверия. Я использовал конструктор SSLContexts из apache httpclient для создания пользовательских`SSLSocketFactory`

и проходя в`new TrustSelfSignedStrategy()` в качестве аргумента в`loadTrustMaterial` метод.