Java SSL通信中的Apache CXF异常:SocketTimeOut

Java SSL通信中的Apache CXF异常:SocketTimeOut,java,ssl,proxy,cxf,Java,Ssl,Proxy,Cxf,这就是交易。我有一个web服务WSDL,我需要对公司网络外部进行SOAP调用。webservice是HTTPS SOAP,需要客户端证书。我已经从wsdl2java生成了Java客户机代码,事情似乎进展得很顺利 我现在不能做的是通过CXF接收来自web服务的响应。SSL握手似乎非常顺利,甚至到了CXF尝试执行HTTP POST,但等待响应超时的地步(如下所示): 现在,如果我使用curl或类似的东西,我可以在不到一秒钟内得到响应,因此我知道web服务没有问题。下面是创建服务端口所需的全部代码,包

这就是交易。我有一个web服务WSDL,我需要对公司网络外部进行SOAP调用。webservice是HTTPS SOAP,需要客户端证书。我已经从
wsdl2java
生成了Java客户机代码,事情似乎进展得很顺利

我现在不能做的是通过CXF接收来自web服务的响应。SSL握手似乎非常顺利,甚至到了CXF尝试执行HTTP POST,但等待响应超时的地步(如下所示):

现在,如果我使用
curl
或类似的东西,我可以在不到一秒钟内得到响应,因此我知道web服务没有问题。下面是创建服务端口所需的全部代码,包括使用TLS和HTTP代理的设置。我还有一个非常简单的JUnit测试来创建和运行它:

public static MYPORT setupTLS(MYPORT port) throws IOException,
        GeneralSecurityException {

    HTTPConduit httpConduit = (HTTPConduit) ClientProxy.getClient(port)
            .getConduit();


    String keyPassword = "password";
    KeyStore keyStore = KeyStore.getInstance("pkcs12");
    URL pkcs12_file = MECTPortFactory.class.getResource(System
            .getProperty("pkcs12.keyFile"));
    InputStream keyFile = pkcs12_file.openStream();
    keyStore.load(keyFile, keyPassword.toCharArray());
    KeyManager[] myKeyManagers = getKeyManagers(keyStore, keyPassword);

    TLSClientParameters tlsCP = new TLSClientParameters();
    tlsCP.setKeyManagers(myKeyManagers);
    tlsCP.setDisableCNCheck(true);
    FiltersType cipher_suite_filter = new FiltersType();
    cipher_suite_filter.getInclude().add("SSL_RSA_WITH_3DES_EDE_CBC_SHA");
    cipher_suite_filter.getExclude().add(".*_DH_anon_.*");
    tlsCP.setCipherSuitesFilter(cipher_suite_filter);
    httpConduit.setTlsClientParameters(tlsCP);
    httpConduit.setClient(getHttpClient());

    return port;
}

private static HTTPClientPolicy getHttpClient() {
    HTTPClientPolicy client_policy = new HTTPClientPolicy();
    client_policy.setProxyServer("PROXY_SERVER_ADDRESS");
    client_policy.setProxyServerPort(8080);
    client_policy.setAutoRedirect(true);
    client_policy.setConnection(ConnectionType.KEEP_ALIVE);
    client_policy.setAllowChunking(true);
    client_policy.setReceiveTimeout(10000);
    return client_policy;
}

private static KeyManager[] getKeyManagers(KeyStore keyStore,
        String keyPassword) throws GeneralSecurityException, IOException {
    String alg = KeyManagerFactory.getDefaultAlgorithm();
    char[] keyPass = keyPassword != null ? keyPassword.toCharArray() : null;
    KeyManagerFactory fac = KeyManagerFactory.getInstance(alg);
    fac.init(keyStore, keyPass);
    return fac.getKeyManagers();
}
编辑: 我对一些客户端设置进行了修改,例如更改是否为自动编辑允许搜索,没有任何区别,因此我认为这不会导致错误

编辑2:
我没有收到来自web服务的响应我如何排除故障并修复导致CXF超时而不是接收响应的原因?

天哪!我想出来了

所以我在互联网络中找到了这颗小宝石:

它引用了Oracle/Sun的一个非常重要的注释:

从对等方接收重新协商请求的应用程序将 根据现场连接类型进行响应:

TLSv1:将显示“无重新协商(100)”类型的警告消息 发送到对等方,连接将保持打开状态

然后,再往下看:

在初始化JSSE库之前,可以通过将新的系统属性
sun.security.ssl.AllowUnsaferNegotiation
设置为
true
来重新启用需要重新协商的应用程序。有几种方法可以设置此属性:

  • 命令行:

    %java-Dsun.security.ssl.allowUnsafeRenegotiation=true Main

  • Java控制面板(Java插件/JavaWebStart)-运行时环境

  • 在应用程序中:

    java.lang.System.setProperty(“sun.security.ssl.allowUnsafeRenegotiation”,true)

  • 请注意,TLS/SSL重新协商不会发生,除非两者都发生 客户端和服务器已启用重新协商

    那么它的长短呢
    System.setProperty(“sun.security.ssl.allowUnsaference”、“true”)


    等等。只是工作。

    如果它抛出了一个异常,你不会认为我不希望这种情况发生吗?…你不会认为“他们没有给我足够的钱来做假设。”。很好地澄清了这个问题。:-)非常感谢这个伟大而完整的例子。我终于能够从独立客户端通过CXF连接到安全的WS。太棒了。你帮我节省了很多搜索时间
    public static MYPORT setupTLS(MYPORT port) throws IOException,
            GeneralSecurityException {
    
        HTTPConduit httpConduit = (HTTPConduit) ClientProxy.getClient(port)
                .getConduit();
    
    
        String keyPassword = "password";
        KeyStore keyStore = KeyStore.getInstance("pkcs12");
        URL pkcs12_file = MECTPortFactory.class.getResource(System
                .getProperty("pkcs12.keyFile"));
        InputStream keyFile = pkcs12_file.openStream();
        keyStore.load(keyFile, keyPassword.toCharArray());
        KeyManager[] myKeyManagers = getKeyManagers(keyStore, keyPassword);
    
        TLSClientParameters tlsCP = new TLSClientParameters();
        tlsCP.setKeyManagers(myKeyManagers);
        tlsCP.setDisableCNCheck(true);
        FiltersType cipher_suite_filter = new FiltersType();
        cipher_suite_filter.getInclude().add("SSL_RSA_WITH_3DES_EDE_CBC_SHA");
        cipher_suite_filter.getExclude().add(".*_DH_anon_.*");
        tlsCP.setCipherSuitesFilter(cipher_suite_filter);
        httpConduit.setTlsClientParameters(tlsCP);
        httpConduit.setClient(getHttpClient());
    
        return port;
    }
    
    private static HTTPClientPolicy getHttpClient() {
        HTTPClientPolicy client_policy = new HTTPClientPolicy();
        client_policy.setProxyServer("PROXY_SERVER_ADDRESS");
        client_policy.setProxyServerPort(8080);
        client_policy.setAutoRedirect(true);
        client_policy.setConnection(ConnectionType.KEEP_ALIVE);
        client_policy.setAllowChunking(true);
        client_policy.setReceiveTimeout(10000);
        return client_policy;
    }
    
    private static KeyManager[] getKeyManagers(KeyStore keyStore,
            String keyPassword) throws GeneralSecurityException, IOException {
        String alg = KeyManagerFactory.getDefaultAlgorithm();
        char[] keyPass = keyPassword != null ? keyPassword.toCharArray() : null;
        KeyManagerFactory fac = KeyManagerFactory.getInstance(alg);
        fac.init(keyStore, keyPass);
        return fac.getKeyManagers();
    }