Wildfly: Verwendung von JAXWS-RI anstelle von Apache CXF (nur WebService-Client)

Meine Umgebung ist ein Maven-Projekt und Wildfly (8.2.1) als Anwendungsserver. Was ich brauche, ist eine Verbindung mit einem eingehenden REST-Aufruf zu einem Drittanbieter-Server unter Verwendung von SOAP. Ich benötige eine SSL-Client-Authentifizierung. Daher habe ich meinen eigenen KeyStore und TrustStore. Ich erstelle daher meinen eigenen SSLContext und muss den WebService diesen SSLContext verwenden lassen.

Alles sieht so aus:

// Build SSL context with own KeyManager / TrustManager
SSLContext sc = SSLContext.getInstance("TLS");

KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());

KeyStore ks = KeyStore.getInstance("JKS");
String password = "changeit";
ks.load(getClass().getResourceAsStream("/keystore"), password.toCharArray());

kmf.init(ks, password.toCharArray());

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

sc.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);

// Now build webservice client
MyWS_Service service = new MyWS_Service(null, new QName("http://...", "MyWS"));
MyWS port = service.getMyWSSOAP();

BindingProvider bindingProvider = (BindingProvider) port;

// set to use own SSLContext
bindingProvider.getRequestContext().put("com.sun.xml.internal.ws.transport.https.client.SSLSocketFactory", sc.getSocketFactory());
// set endpoint
bindingProvider.getRequestContext().put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, "https://hostname:443/.../...");

// perform request
respObj = port.myRequest(myRequestObj);

Wenn ich diesen Code aus einem JUnit-Test aufrufe, funktioniert alles einwandfrei. Es verwendet JAXWS-RI aus der JRE.

Wenn ich diesen Code von Wildfly aus aufrufe, d. H. Von meinem eingehenden REST-Aufruf, bei dem ich diese Anforderung endgültig auslösen muss, funktioniert er nicht, da der eigene SSLContext nicht verwendet wird. Es wird der Standard-SSLContext verwendet, der natürlich vom SOAP-Server eines Drittanbieters abgelehnt wird. Was ich sehe ist, dass es nicht JAXWS-RI verwendet, sondern Apache CXF als JAXWS-Implementierung. Also denke ich, dassbindingProvider.getRequestContext().put("com.sun.xml.internal.ws.transport.https.client.SSLSocketFactory", sc.getSocketFactory()); wird einfach ignoriert Warum] und hat keine Wirkung. (Ich habe auch versucht, den Eigenschaftsnamencom.sun.xml.ws.transport.https.client.SSLSocketFactory [ohneinternal] - auch ohne glück.)

Ich weiß, dass ich @ verwenden könnHttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory()) oder verwenden Sie sogar die JVM-Parameterjavax.net.ssl.trustStore, javax.net.ssl.keyStore (und die zugehörigen Passworteigenschaften). Da dies alle Verbindungen betrifft, kann diese Lösung nicht verwendet werden. aber mal schauen was passiert, wenn ich es trotzdem benutze:

JUnit Use Case: Es funktioniert auch

Wildfly-Anwendungsfall: Es scheint, dass JAXWS den SSLContext verwendet, aber es gibt eine SSL-Ausnahme (Warnung vom Server, dass die Zertifizierungsstelle unbekannt ist). Dies zeigt, dass es sogar Unterschiede beim Verbindungsaufbau gibt. Warum funktioniert es, wenn der Code mit JUnit ausgeführt wird? Dies beweist, dass der KeyStore / TrustStore korrekt mit den richtigen Zertifikaten eingerichtet ist. Ist es nicht?

Bearbeiten Es gibt noch einen Beweis dafür, dass das Problem in der von Wildfly verwendeten JAXWS-Implementierung liegt: Wenn ich nur eine einfache HttpsConnection durchführe, funktioniert dies sogar mit meinem eigenen KeyStore / TrustStore in Wildfly:

url = new URL("https://hostname:443/.../...");
HttpsURLConnection con = (HttpsURLConnection) url.openConnection();
con.setSSLSocketFactory(sc.getSocketFactory());
System.out.println(Utils.inputStreamToString(con.getInputStream()));

Also, was ist das Beste zu tun? -> Als Fragentitel möchte ich versuchen, Wildfly dazu zu bringen, JAXWS-RI anstelle von Apache CXF zu verwenden. Aber ich habe es bis jetzt nicht geschafft zu arbeiten. Ich habe versucht, die folgende Abhängigkeit in den pom zu setzen:

    <dependency>
        <groupId>com.sun.xml.ws</groupId>
        <artifactId>jaxws-rt</artifactId>
        <version>2.2.10</version>
    </dependency>

Aber dies gibt mir die folgende Ausnahme:

java.util.ServiceConfigurationError: javax.xml.ws.spi.Provider: Provider com.sun.xml.ws.spi.ProviderImpl could not be instantiated
    at java.util.ServiceLoader.fail(ServiceLoader.java:232) ~[?:1.8.0_92]

Was ist falsch? Wie kann ich Wildfly auf die gleiche Weise zum Laufen bringen, als würde der Code aus demselben Projekt ausgeführt, aber "als JUnit-Test"?

Bearbeiten Wenn Sie einen Tipp haben, wie Sie das Ziel (Senden von SOAP-Anfragen mit SSL mit Client-Authentifizierung unter Wildfly 8.2.1) auf andere Weise erreichen können (vorausgesetzt, es handelt sich um eine saubere Java EE-Lösung - dh Sie senden keine eigenen XML-Körper :-) und nicht mit zu alten Framworks wie Axis 1), es ist auch willkommen!Ich brauche bald eine Lösung - ich kämpfe schon seit Tagen ...

Antworten auf die Frage(6)

Ihre Antwort auf die Frage