с помощью JAX WS мне удалось разработать клиент веб-службы, который отвечает за отправку записей.
Соединению с сервером доверяют по SSL, поэтому я использовал приведенный ниже код, чтобы сообщить клиенту, как управлять рукопожатием с сервером.
Но теперь мне нужно иметь возможность динамически указывать клиенту, что нужно выбрать хранилище доверия следующим образом:
если я позвоню клиенту с параметром, я буду использовать cacerts1
если я вызову второго клиента с другим параметром, я буду использовать cacerts2
если я вызываю третьего клиента с другим параметром, я не хочу использовать хранилище доверенных сертификатов
Другой сценарий таков:
Client1 ---> use Certificate1 ----> Server1
Client2 ---> use Certificate2 ----> Server1
Сервер1 использует некоторую информацию внутри сертификата 1 и 2 для пересылки сообщения, отправленного client1 и client2, в расположении 2 diff: store1 и store2.
import java.net.URL;
import javax.xml.namespace.QName;
import javax.xml.ws.Service;
import javax.xml.ws.WebEndpoint;
import javax.xml.ws.WebServiceClient;
import javax.xml.ws.WebServiceException;
import javax.xml.ws.WebServiceFeature;
public class MyProxy extend Service {
private static final EndOfDayService SERVICE = new EndOfDayService();
// Web service port to call services
private final MyPort port;
public MyProxy(String baseurl, SSLSocketFactory sslFactory, boolean compression) {
port = super.getPort(...);
Map<String, Object> context = ((BindingProvider) port).getRequestContext();
if (baseurl != null) {
context.put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, baseurl);
}
System.setProperty("javax.net.ssl.keyStoreType", "pkcs12");
System.setProperty("javax.net.ssl.trustStoreType", "pkcs12");
System.setProperty("javax.net.ssl.keyStore", "C:\\path\\to\\my\\cacerts");
System.setProperty("javax.net.ssl.trustStore", "C:\\path\\to\\my\\cacerts");
System.setProperty("javax.net.debug", "SSL");
System.setProperty("javax.net.ssl.keyStorePassword", "mypwd");
System.setProperty("javax.net.ssl.trustStorePassword","mypwd");
sslFactory = (SSLSocketFactory) SSLSocketFactory.getDefault();
if (sslFactory != null) {
context.put(JAXWSProperties.SSL_SOCKET_FACTORY, sslFactory);
}
// For debugging only: don't check host name in server certificate when pointing to localhost
context.put(JAXWSProperties.HOSTNAME_VERIFIER, new HostnameVerifier() {
@Override
public boolean verify(String hostName, SSLSession session) {
if (hostName.equals("localhost")) {
return true;
}
return false;
}
});
}
}
public String record(List<EndOfDayInstance> records) throws SystemFaultException, UserFaultException {
return port.sendrecord(records);
}
}
используя этот код, я установил хранилище cacerts для всего процесса, поэтому другие параллельные клиенты (например, как в случае с Client1 и Client2 ранее) в том же процессе будут использовать этот параметр.
Но что, если один из других клиентов в том же процессе хочет получить доступ к другому хранилищу доверенных сертификатов?
Как можно динамически изменить хранилище доверия только для одного экземпляра клиента веб-службы, чтобы не влиять на другие? а также изменить его время выполнения?
Или
Как мне иметь только одно хранилище и указать, что client1 должен использовать сертификат1, а клиент2 должен использовать сертификат2 для рукопожатия?