【问题标题】:Apache CXF Exception in SSL communication: SocketTimeOutSSL 通信中的 Apache CXF 异常:SocketTimeOut
【发布时间】:2011-10-04 13:22:09
【问题描述】:

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

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

Allow unsafe renegotiation: false
Allow legacy hello messages: true
Is initial handshake: false
Is secure renegotiation: false
*** HelloRequest (empty)
main, SEND TLSv1 ALERT:  warning, description = no_renegotiation
Padded plaintext before ENCRYPTION:  len = 24
0000: 01 64 01 FD 5B 38 03 A6   70 41 57 58 6D 75 60 F7  .d..[8..pAWXmu`.
0010: 93 1F 02 F3 C4 46 01 01                            .....F..
main, WRITE: TLSv1 Alert, length = 24
[Raw write]: length = 29
0000: 15 03 01 00 18 0C 9B DF   1B 60 AB 12 EE C7 CF C9  .........`......
0010: 62 97 A5 5D 5F 14 48 E1   9F AD 8A 08 05           b..]_.H......
main, handling exception: java.net.SocketTimeoutException: Read timed out
main, called close()
main, called closeInternal(true)
main, SEND TLSv1 ALERT:  warning, description = close_notify
Padded plaintext before ENCRYPTION:  len = 24
0000: 01 00 BD 99 7A 7C 72 1F   BB 11 2D AB 3F 53 C9 CD  ....z.r...-.?S..

... continuing on

现在,如果我使用curl 或类似的东西,我可以在不到一秒的时间内得到响应,所以我知道网络服务没有问题。下面是创建服务端口所需的全部代码,包括使用 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();
}

编辑:

我已经修改了一些客户端设置,例如更改是否为 AutoRedirectAllowChunking 等,没有任何区别,所以我认为这不会导致错误.

编辑2:

我没有收到来自网络服务的响应。 如何排查和修复导致 CXF 超时而不是收到响应的原因?

【问题讨论】:

  • 如果它抛出异常,你不会认为我不希望这种情况发生吗?
  • "..你不会假设吗" 他们付给我的钱不够我做假设。很好地澄清这个问题。 :-)
  • 非常感谢这个伟大而完整的例子。我终于能够从独立客户端通过 CXF 连接到安全的 WS。

标签: java ssl proxy cxf


【解决方案1】:

天哪!我想通了。

于是我在互联网上闲逛,发现了这个小宝石:

How to configure SoapUI with client certificate authentication

它引用了 Oracle/Sun 的一个非常重要的说明:

Transport Layer Security (TLS) Renegotiation Issue Readme

收到对等方重新协商请求的应用程序将 根据现有的连接类型做出响应:

TLSv1:“no_renegotiation(100)”类型的警告警报消息将是 发送到对等方,连接将保持打开状态。

然后,再往下:

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

  1. 命令行:

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

  2. Java 控制面板(Java 插件/Java Web Start)- 运行时环境。

  3. 在应用程序内:

    java.lang.System.setProperty("sun.security.ssl.allowUnsafeRenegotiation", true);

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

那么长和短呢? System.setProperty("sun.security.ssl.allowUnsafeRenegotiation", "true");

还有东西。只是。工作。

【讨论】:

  • 太棒了..你为我节省了很多搜索时间
猜你喜欢
  • 2019-08-10
  • 1970-01-01
  • 2016-01-27
  • 2019-03-19
  • 1970-01-01
  • 2016-03-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多