简体   繁体   English

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

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

My environment is a Maven Project and Wildfly (8.2.1) as Application Server. 我的环境是Maven Project和Wildfly(8.2.1)作为Application Server。 What I need is to connect wihin a incoming REST call to a third party server using SOAP. 我需要的是使用SOAP将传入的REST调用连接到第三方服务器。 I need SSL Client Authentication; 我需要SSL客户端身份验证; therefore, I have my own KeyStore and TrustStore. 因此,我有自己的KeyStore和TrustStore。 I create therefore my own SSLContext and need to let the WebService use this SSLContext. 因此,我创建了自己的SSLContext,并且需要让WebService使用此SSLContext。

All looks like this: 所有看起来像这样:

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

If I call this code from a JUnit test, all works fine. 如果我从JUnit测试中调用此代码,一切正常。 It uses JAXWS-RI from the JRE. 它使用JRE中的JAXWS-RI。

If I call this code from Wildfly, ie from my incoming REST call, where I finally need to fire this request, it does not work because it does not use the own SSLContext. 如果我从Wildfly调用此代码,即从我的传入REST调用,我最终需要触发此请求,它不起作用,因为它不使用自己的SSLContext。 It uses the default SSLContext, which of course is rejected by the third party SOAP server. 它使用默认的SSLContext,当然这被第三方SOAP服务器拒绝。 What I see is that it does not use JAXWS-RI but Apache CXF as JAXWS implementation. 我看到的是它不使用JAXWS-RI而是使用Apache CXF作为JAXWS实现。 So I do guess that bindingProvider.getRequestContext().put("com.sun.xml.internal.ws.transport.https.client.SSLSocketFactory", sc.getSocketFactory()); 所以我猜测bindingProvider.getRequestContext().put("com.sun.xml.internal.ws.transport.https.client.SSLSocketFactory", sc.getSocketFactory()); is simply ignored [ Why? 简直被忽略了[ 为什么? ] and has no effect. ]并没有效果。 (I also tried the property name com.sun.xml.ws.transport.https.client.SSLSocketFactory [without internal ] - also with no luck.) (我也尝试过属性名称com.sun.xml.ws.transport.https.client.SSLSocketFactory [没有internal ] - 也没有运气。)

I know that I could use HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory()) or even use the JVM parameters javax.net.ssl.trustStore , javax.net.ssl.keyStore (and their corresponding password properties). 我知道我可以使用HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory())甚至使用JVM参数javax.net.ssl.trustStorejavax.net.ssl.keyStore (及其相应的密码属性)。 Since this affects all connections, it is out of discussion to use this solution; 由于这会影响所有连接,因此不再讨论使用此解决方案; however, lets look what hapens, if I use it anyway: 但是,如果我仍然使用它,让我们看看是什么?

  • JUnit use case: It also works JUnit用例:它也有效

  • Wildfly use case: It seems that JAXWS takes the SSLContext, but there is a SSL exception (alert from Server that CA is unknown). Wildfly用例:似乎JAXWS采用SSLContext,但是存在SSL异常(来自服务器的警报,CA未知)。 This shows that there is even a difference in how to establish the connection. 这表明在如何建立连接方面甚至存在差异。 Why is it working, if the code is executed with JUnit? 如果使用JUnit执行代码,为什么它可以工作? This proofes that the KeyStore / TrustStore is correctly set up with the correct certificates. 这证明KeyStore / TrustStore已使用正确的证书正确设置。 Isn't it? 不是吗?

Edit: There is one more proof, that the problem is the JAXWS implementation Wildfly uses: If I just perform a simple HttpsConnection, it even works with my own KeyStore / TrustStore in Wildfly: 编辑:还有一个证明,问题是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()));

So what is the best to do? 那么最好的做法是什么? -> As the question titles, I would like to try to bring Wildfly to also use JAXWS-RI rather than Apache CXF. - >作为问题标题,我想尝试使Wildfly也使用JAXWS-RI而不是Apache CXF。 But I got it not to work until now. 但是直到现在我才开始工作。 I tried to put the following dependency in the pom: 我试图将以下依赖项放在pom中:

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

But this gives me the following exception: 但这给了我以下例外:

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]

What is wrong? 怎么了? How can I bring Wildfly to work the same way, as if the code is executed from the same project but "as a JUnit Test"? 如何使Wildfly以相同的方式工作,就好像代码是从同一个项目执行但“作为JUnit测试”?

Edit: If you have a tip how to reach the goal (sending SOAP requests using SSL with client auth on Wildfly 8.2.1) in a different way (provided that it is a clean Java EE solution - ie not sending own XML bodies :-) and not with too old framworks like Axis 1), it is also welcome! 编辑:如果您有一个提示如何以不同的方式达到目标(使用带有客户端身份验证的SOAP在Wildfly 8.2.1上发送SOAP请求)(前提是它是一个干净的Java EE解决方案 - 即不发送自己的XML主体: - )而不是像Axis 1那样过于古老的framworks,也欢迎! I do need a solution soon - I am fighting for days already... 我确实需要一个解决方案 - 我已经好几天了...

OK, finally, I gave up to try to replace the JAX-WS implementation used. 好吧,最后,我放弃了尝试替换使用的JAX-WS实现。 I got it to correctly setup Apache CXF. 我得到了正确设置Apache CXF。

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

This solve the problem: https://stackoverflow.com/a/46894256/8190026 . 这解决了这个问题: https//stackoverflow.com/a/46894256/8190026 Wildfly will use the sun implementation instead of apache.cxf Wildfly将使用sun实现而不是apache.cxf

I think it is difficult. 我觉得很难。 There were some comments somewhere about this. 有一些关于此的评论。 By the way, I think WildFly uses RESTEasy, not CXF 顺便说一句,我认为WildFly使用RESTEasy而不是CXF

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM