java - 无法使用 cxf http-conduit 连接 SSL 网络服务

标签 java cxf pkcs#12 http-conduit

我正在尝试连接到 SOAP 网络服务并且需要提供证书以进行身份​​验证。我目前正在使用 cxf http 管道来查找我的证书。我从我想调用的服务中收到了一个 p12 文件。我已经将 p12 导入到 jks 中。我将 jks 与我的 cxf.xml 页面一起放在类路径中。我修改了我的 web.xml 以包含上下文参数和监听器类,但我仍然从服务器获取日志,说没有提供证书。我到处寻找解决方案,但到目前为止没有任何效果。非常感谢任何帮助

CXF.XML

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:sec="http://cxf.apache.org/configuration/security"
       xmlns:http="http://cxf.apache.org/transports/http/configuration"
       xmlns:jaxws="http://java.sun.com/xml/ns/jaxws"
       xsi:schemaLocation="
      http://cxf.apache.org/configuration/security
      http://cxf.apache.org/schemas/configuration/security.xsd
      http://cxf.apache.org/transports/http/configuration
      http://cxf.apache.org/schemas/configuration/http-conf.xsd
      http://www.springframework.org/schema/beans
      http://www.springframework.org/schema/beans/spring-beans-2.0.xsd">

    <http:conduit name="*.http-conduit">

        <http:tlsClientParameters>
            <sec:keyManagers keyPassword="changeit">
                <sec:keyStore type="JKS" password="changeit"
                              resource="myKeystore.jks"
                             />
            </sec:keyManagers>
            <sec:trustManagers>
                <sec:keyStore type="JKS" password="changeit"
                              resource="myKeystore.jks"/>
            </sec:trustManagers>
            <sec:cipherSuitesFilter>
                <!-- these filters ensure that a ciphersuite with
                     export-suitable or null encryption is used,
                     but exclude anonymous Diffie-Hellman key change as
                     this is vulnerable to man-in-the-middle attacks -->
                <sec:include>.*_EXPORT_.*</sec:include>
                <sec:include>.*_EXPORT1024_.*</sec:include>
                <sec:include>.*_WITH_DES_.*</sec:include>
                <sec:include>.*_WITH_AES_.*</sec:include>
                <sec:include>.*_WITH_NULL_.*</sec:include>
                <sec:exclude>.*_DH_anon_.*</sec:exclude>
            </sec:cipherSuitesFilter>
        </http:tlsClientParameters>

        <http:client AutoRedirect="true" Connection="Keep-Alive"/>

    </http:conduit>

</beans>

WEB.XML

     <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:cxf.xml</param-value>
    </context-param>
     <listener>
     <listener-class>
        org.springframework.web.context.ContextLoaderListener
     </listener-class>
  </listener>

最佳答案

我同意@hooknc 最后的评论。确保您的 keystore 包含私钥条目。此外,将私钥密码设置为等于 keystore 密码。您可以使用下面列出的代码测试您的服务。我为 cxf 版本 3.0.0-milestone2 编写它,因为我需要多个签名,但我认为代码也应该适用于稳定分支 2.x

private PaymentService_Service service = null;
private PaymentService iface = null;

@Before
public void setUp() throws Exception {
    System.setProperty("com.sun.xml.ws.transport.http.client.HttpTransportPipe.dump", "true");
    System.setProperty("javax.net.debug", "ssl");
    service = new PaymentService_Service();
    iface = service.getPaymentServiceImplPort();
    Client client = ClientProxy.getClient(iface);
    HTTPConduit http = (HTTPConduit) client.getConduit();
    TLSClientParameters parameters = new TLSClientParameters();
    parameters.setSSLSocketFactory(createSSLContext().getSocketFactory());
    http.setTlsClientParameters(parameters);
    HTTPClientPolicy httpClientPolicy = new HTTPClientPolicy();
    httpClientPolicy.setConnectionTimeout(36000);
    httpClientPolicy.setAllowChunking(false);
    httpClientPolicy.setReceiveTimeout(32000);
    http.setClient(httpClientPolicy);
}

private SSLContext createSSLContext() throws Exception{
    KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
    trustStore.load(new FileInputStream("/home/user/dev/project/key/http.jks"), "changeit".toCharArray());

    KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
    keyStore.load(new FileInputStream("/home/user/dev/project/key/client.jks"), "changeit".toCharArray());


    TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509");
    tmf.init(trustStore);

    KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
    kmf.init(keyStore, "changeit".toCharArray());

    SSLContext sslContext = SSLContext.getInstance("SSL");
    sslContext.init(kmf.getKeyManagers() , tmf.getTrustManagers(), new SecureRandom());
    return sslContext;
}

@Test
public void testSomeMethod() throws Exception {
    Client client = ClientProxy.getClient(iface);
    client.getInInterceptors().add(new LoggingInInterceptor());
    client.getOutInterceptors().add(new LoggingOutInterceptor());
    String res = iface.doSomeMethod();
}

关于java - 无法使用 cxf http-conduit 连接 SSL 网络服务,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24042784/

相关文章:

java - 从更新的 SQL 数据库刷新 JavaFX 场景?

apache - 如何解决缺少的需求[308.0] osgi.wiring.package; (osgi.wiring.package=org.apache.cxf.binding.corba) 在 FUSE 6.3.0 中

java - 带有内容过滤或屏蔽 soap 字段的 CXF 日志记录请求和响应

java - 将 HttpClient 与 SSL 和证书结合使用

java - Maven 资源过滤不适用于其中包含 @ 的行

java - 专注于Java swing

ssl - 从 RSA key 生成 PKCS#12 key 的问题

java - 可以将加密凭证存储在 PKCS12 keystore 中吗?

java - 在 libgdx 中渲染 box2d

ssl - Mule cxf :outbound-endpoint (client) and HTTPS/SSL 问题