Apache http客户端默认设置不适用于sni [英] Apache http client defaults don't work with sni

查看:182
本文介绍了Apache http客户端默认设置不适用于sni的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

主要问题

PRIMARY QUESTION

是否存在我不知道的错误使用最新的4.x apache http客户端?
或我缺少让sni工作的设置?

Is there a bug I'm not aware of with the latest 4.x apache http client? or a setting that I'm missing to get sni to work?

在同一个jvm中开/关(在此case 1.7.0_45)。

On/in the same jvm (in this case 1.7.0_45).

我运行以下两段代码来提取一个需要SNI才能正确连接的https网址。第一段代码使用java内置的java.net。*方法,第二段代码使用org.apache.http。*(版本4.5)方法。

I run the following two pieces of code to pull an https url that requires SNI for it to connect correctly. The 1st piece of code uses java's built in java.net.* approach, and the 2nd piece of code uses org.apache.http.* (version 4.5) approach.

接近java.net。*

public final class JavaNetHitApi extends BaseHitApi {

    @Override
    public JSONObject hitAPI(final String url) throws IOException {
        URL toUse = new URL(url);
        URLConnection conn = toUse.openConnection();
        final String result = readToString(conn.getInputStream());
        JSONObject toReturn = new JSONObject(result);
        return toReturn;
    }

}

与组织接近。 apache.http。*

public final class ApacheHttpHitApi extends BaseHitApi {

    @Override
    public JSONObject hitAPI(final String url) throws IOException {
        final HttpGet httpGet = new HttpGet(url);
        try (final CloseableHttpClient httpclient = HttpClients.createDefault();
                final CloseableHttpResponse response = httpclient.execute(httpGet)) {
            String result = readToString(response.getEntity().getContent());
            JSONObject toReturn = new JSONObject(result);
            return toReturn;
        }
    }
}






对于第一种情况(java.net。*),它工作正常,返回没有问题。


For the 1st case (java.net.*), it works fine, and returns with no problems.

对于第二种情况(org.apache) .http。*),它会抛出以下错误:

For the 2nd case (org.apache.http.*), it throws the following error:


javax.net.ssl.SSLHandshakeException:收到致命警报:
handshake_failure

javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure

请记住,这是在同一个JVM上运行,具有相同的sni启用设置等。
唯一解释我通过搜索所有关于从java 1.6-> 1.7或1.7-> 1.8,或在系统上启用sni等的讨论来遇到。
在这种情况下,所有这些变量都被消除了,因为两段代码的基础系统设置相同。

Keep in mind this is running on the same JVM, with the same sni enabled settings, etc. The only explanations I've come across through searching all talk about going from java 1.6->1.7, or 1.7->1.8, or enabling sni on the system, etc. In this case, all those variables are eliminated, since the underlying system settings are the same for both pieces of code.

主要问题回收

PRIMARY QUESTION RECAP

我是否有最新的4.x apache http客户端无法识别的错误?
或我缺少让sni工作的设置?

Is there a bug I'm not aware of with the latest 4.x apache http client? or a setting that I'm missing to get sni to work?

使用


- Djavax.net.debug = all

"-Djavax.net.debug=all"

标志,我可以看到这两种方法的不同之处,即java.net。*方法吐出的行:

flag, I can see where the two approaches differ, namely that the java.net.* approach spits out the line:


Extension server_name,server_name:[host_name:
obfuscatedsubdomain.execute-api.us-west-2.amazonaws.com]

Extension server_name, server_name: [host_name: obfuscatedsubdomain.execute-api.us-west-2.amazonaws.com]

并且apache http客户端没有。

And the apache http client does not.

下面包含输出片段以供参考。

The output snippets are included below for reference.

java.net。*输出

Allow unsafe renegotiation: false
Allow legacy hello messages: true
Is initial handshake: true
Is secure renegotiation: false
main, setSoTimeout(0) called
%% No cached client session
*** ClientHello, TLSv1
RandomCookie:  GMT: 1424292809 bytes = { 117, 134, 25, 51, 251, 228, 170, 18, 240, 70, 32, 245, 131, 90, 128, 105, 26, 220, 234, 92, 81, 47, 129, 195, 17, 137, 210, 125 }
Session ID:  {}
Cipher Suites: [TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, TLS_RSA_WITH_AES_128_CBC_SHA, TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA, TLS_ECDH_RSA_WITH_AES_128_CBC_SHA, TLS_DHE_RSA_WITH_AES_128_CBC_SHA, TLS_DHE_DSS_WITH_AES_128_CBC_SHA, TLS_ECDHE_ECDSA_WITH_RC4_128_SHA, TLS_ECDHE_RSA_WITH_RC4_128_SHA, SSL_RSA_WITH_RC4_128_SHA, TLS_ECDH_ECDSA_WITH_RC4_128_SHA, TLS_ECDH_RSA_WITH_RC4_128_SHA, TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA, TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, SSL_RSA_WITH_3DES_EDE_CBC_SHA, TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA, TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA, SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA, SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA, SSL_RSA_WITH_RC4_128_MD5, TLS_EMPTY_RENEGOTIATION_INFO_SCSV]
Compression Methods:  { 0 }
Extension elliptic_curves, curve names: {secp256r1, sect163k1, sect163r2, secp192r1, secp224r1, sect233k1, sect233r1, sect283k1, sect283r1, secp384r1, sect409k1, sect409r1, secp521r1, sect571k1, sect571r1, secp160k1, secp160r1, secp160r2, sect163r1, secp192k1, sect193r1, sect193r2, secp224k1, sect239k1, secp256k1}
Extension ec_point_formats, formats: [uncompressed]
Extension server_name, server_name: [host_name: obfuscatedsubdomain.execute-api.us-west-2.amazonaws.com]
***

apache.org.http。*输出

main, setSoTimeout(0) called
Allow unsafe renegotiation: false
Allow legacy hello messages: true
Is initial handshake: true
Is secure renegotiation: false
%% No cached client session
*** ClientHello, TLSv1
RandomCookie:  GMT: 1424293231 bytes = { 222, 180, 202, 14, 219, 36, 94, 157, 23, 55, 5, 98, 165, 33, 227, 160, 201, 191, 122, 194, 241, 154, 216, 137, 159, 81, 208, 143 }
Session ID:  {}
Cipher Suites: [TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, TLS_RSA_WITH_AES_128_CBC_SHA, TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA, TLS_ECDH_RSA_WITH_AES_128_CBC_SHA, TLS_DHE_RSA_WITH_AES_128_CBC_SHA, TLS_DHE_DSS_WITH_AES_128_CBC_SHA, TLS_ECDHE_ECDSA_WITH_RC4_128_SHA, TLS_ECDHE_RSA_WITH_RC4_128_SHA, SSL_RSA_WITH_RC4_128_SHA, TLS_ECDH_ECDSA_WITH_RC4_128_SHA, TLS_ECDH_RSA_WITH_RC4_128_SHA, TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA, TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, SSL_RSA_WITH_3DES_EDE_CBC_SHA, TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA, TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA, SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA, SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA, SSL_RSA_WITH_RC4_128_MD5, TLS_EMPTY_RENEGOTIATION_INFO_SCSV]
Compression Methods:  { 0 }
Extension elliptic_curves, curve names: {secp256r1, sect163k1, sect163r2, secp192r1, secp224r1, sect233k1, sect233r1, sect283k1, sect283r1, secp384r1, sect409k1, sect409r1, secp521r1, sect571k1, sect571r1, secp160k1, secp160r1, secp160r2, sect163r1, secp192k1, sect193r1, sect193r2, secp224k1, sect239k1, secp256k1}
Extension ec_point_formats, formats: [uncompressed]
***


推荐答案

问题最终是另一个依赖项不仅使用了不同版本的httpclient,而且还将其打包到jar中,而不将其列为传递依赖项。 (意思是,当你去检查pom依赖层次结构时它没有出现,因此它不能被标记为使用的版本)。

The issue ended up being that another dependency was not only using a different version of the httpclient, BUT was also packaging it into its jar without listing it as a transitive dependency. (meaning, that it doesn't show up when you go to inspect the pom dependency hierarchy, so it can't be flagged out as the "used version").

有问题的依赖是:

<dependency>
    <groupId>com.google.gwt</groupId>
    <artifactId>gwt-dev</artifactId>
    <version>2.7.0</version>
</dependency>

它的jar中包含apache http的代码,并且在其pom中未列出。
它引用的版本是4.3.1,它表现出这个问题。 (4.3.2及以后不要)。

It has the code for apache http included in its jar, and unlisted in its pom. And the version it references is 4.3.1, which exhibits this problem. (4.3.2 and onward do not).

有两种解决方法:



  1. pom.xml中的列表中包含http客户端依赖 1st

从pom.xml中删除gwt-dev依赖项

Remove the gwt-dev dependency from the pom.xml

这篇关于Apache http客户端默认设置不适用于sni的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆