gpt4 book ai didi

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

转载 作者:塔克拉玛干 更新时间:2023-11-02 08:38:41 26 4
gpt4 key购买 nike

我的环境是一个 Maven 项目和 Wildfly (8.2.1) 作为应用程序服务器。我需要的是使用 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()); 只是被忽略了[ Why? ] 并且没有效果。 (我还尝试了属性名称 com.sun.xml.ws.transport.https.client.SSLSocketFactory [没有 internal] - 也没有运气。)

我知道我可以使用 HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory()) 甚至可以使用 JVM 参数 javax.net.ssl.trustStore, javax.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 测试”一样?

编辑:如果您知道如何以不同的方式达到目标(在 Wildfly 8.2.1 上使用带有客户端身份验证的 SSL 发送 SOAP 请求)(前提是它是一个干净的 Java EE 解决方案 - 即不发送自己的 XML 主体 :-) 和不要使用像 Axis 1 这样的太旧的框架),它也很受欢迎! 我很快就需要一个解决方案 - 我已经奋斗了好几天......

最佳答案

OK,最后,我放弃尝试替换使用的JAX-WS实现。我得到它以正确设置 Apache CXF。

https://stackoverflow.com/a/37268853/4106030

关于java - Wildfly:如何使用 JAXWS-RI 而不是 Apache CXF(仅限 WebService 客户端),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37158821/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com