簡體   English   中英

Wildfly:如何使用JAXWS-RI而不是Apache CXF(僅限WebService客戶端)

[英]Wildfly: How to use JAXWS-RI instead of Apache CXF (WebService client only)

我的環境是Maven Project和Wildfly(8.2.1)作為Application Server。 我需要的是使用SOAP將傳入的REST調用連接到第三方服務器。 我需要SSL客戶端身份驗證; 因此,我有自己的KeyStore和TrustStore。 因此,我創建了自己的SSLContext,並且需要讓WebService使用此SSLContext。

所有看起來像這樣:

// 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);

如果我從JUnit測試中調用此代碼,一切正常。 它使用JRE中的JAXWS-RI。

如果我從Wildfly調用此代碼,即從我的傳入REST調用,我最終需要觸發此請求,它不起作用,因為它不使用自己的SSLContext。 它使用默認的SSLContext,當然這被第三方SOAP服務器拒絕。 我看到的是它不使用JAXWS-RI而是使用Apache CXF作為JAXWS實現。 所以我猜測bindingProvider.getRequestContext().put("com.sun.xml.internal.ws.transport.https.client.SSLSocketFactory", sc.getSocketFactory()); 簡直被忽略了[ 為什么? ]並沒有效果。 (我也嘗試過屬性名稱com.sun.xml.ws.transport.https.client.SSLSocketFactory [沒有internal ] - 也沒有運氣。)

我知道我可以使用HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory())甚至使用JVM參數javax.net.ssl.trustStorejavax.net.ssl.keyStore (及其相應的密碼屬性)。 由於這會影響所有連接,因此不再討論使用此解決方案; 但是,如果我仍然使用它,讓我們看看是什么?

  • JUnit用例:它也有效

  • Wildfly用例:似乎JAXWS采用SSLContext,但是存在SSL異常(來自服務器的警報,CA未知)。 這表明在如何建立連接方面甚至存在差異。 如果使用JUnit執行代碼,為什么它可以工作? 這證明KeyStore / TrustStore已使用正確的證書正確設置。 不是嗎?

編輯:還有一個證明,問題是Wildfly使用的JAXWS實現:如果我只是執行一個簡單的HttpsConnection,它甚至可以在Wildfly中使用我自己的KeyStore / TrustStore:

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

那么最好的做法是什么? - >作為問題標題,我想嘗試使Wildfly也使用JAXWS-RI而不是Apache CXF。 但是直到現在我才開始工作。 我試圖將以下依賴項放在pom中:

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

但這給了我以下例外:

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]

怎么了? 如何使Wildfly以相同的方式工作,就好像代碼是從同一個項目執行但“作為JUnit測試”?

編輯:如果您有一個提示如何以不同的方式達到目標(使用帶有客戶端身份驗證的SOAP在Wildfly 8.2.1上發送SOAP請求)(前提是它是一個干凈的Java EE解決方案 - 即不發送自己的XML主體: - )而不是像Axis 1那樣過於古老的framworks,也歡迎! 我確實需要一個解決方案 - 我已經好幾天了...

好吧,最后,我放棄了嘗試替換使用的JAX-WS實現。 我得到了正確設置Apache CXF。

https://stackoverflow.com/a/372​​68853/4106030

這解決了這個問題: https//stackoverflow.com/a/46894256/8190026 Wildfly將使用sun實現而不是apache.cxf

我覺得很難。 有一些關於此的評論。 順便說一句,我認為WildFly使用RESTEasy而不是CXF

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM