java apache httpclient 4.4:HostnameVerifier 从 4.3.x 过渡

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/29207694/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-02 14:52:18  来源:igfitidea点击:

apache httpclient 4.4: HostnameVerifier transition from 4.3.x

javaapache-httpclient-4.x

提问by Subhash Chandran

HttpClient 4.3 had three static variables in org.apache.http.conn.ssl.SSLConnectionSocketFactory:

HttpClient 4.3 在 中有三个静态变量org.apache.http.conn.ssl.SSLConnectionSocketFactory

  1. STRICT_HOSTNAME_VERIFIER
  2. BROWSER_COMPATIBLE_HOSTNAME_VERIFIER
  3. ALLOW_ALL__HOSTNAME_VERIFIER
  1. STRICT_HOSTNAME_VERIFIER
  2. BROWSER_COMPATIBLE_HOSTNAME_VERIFIER
  3. ALLOW_ALL__HOSTNAME_VERIFIER

When upgrading the dependency to version 4.4 of HttpClient, I see that all the above constants are deprecated. The deprecation note in JavaDoc mentioned to use org.apache.http.conn.ssl.DefaultHostnameVerifier. Reading the docs, I assume that DefaultHostnameVerifieris a direct replacement to STRICT_HOSTNAME_VERIFIER. Also the ALLOW_ALL__HOSTNAME_VERIFIERis easy to implement:

将依赖项升级到 HttpClient 4.4 版时,我看到上述所有常量都已弃用。JavaDoc 中的弃用说明提到使用org.apache.http.conn.ssl.DefaultHostnameVerifier. 阅读文档,我认为这DefaultHostnameVerifier是对STRICT_HOSTNAME_VERIFIER. 也ALLOW_ALL__HOSTNAME_VERIFIER很容易实现:

package org.wiztools.restclient.http;

import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLSession;

/**
 *
 * @author subwiz
 */
public class AllowAllHostnameVerifier implements HostnameVerifier {

    @Override
    public boolean verify(String string, SSLSession ssls) {
        return true;
    }

}

There is a subtle distinction between the STRICT_HOSTNAME_VERIFIERand BROWSER_COMPATIBLE_HOSTNAME_VERIFIER(from JavaDoc):

STRICT_HOSTNAME_VERIFIERBROWSER_COMPATIBLE_HOSTNAME_VERIFIER(来自JavaDoc)之间有一个微妙的区别:

The only difference between BROWSER_COMPATIBLE and STRICT is that a wildcard (such as "*.foo.com") with BROWSER_COMPATIBLE matches all subdomains, including "a.b.foo.com".

BROWSER_COMPATIBLE 和 STRICT 之间的唯一区别是带有 BROWSER_COMPATIBLE 的通配符(例如“*.foo.com”)匹配所有子域,包括“abfoo.com”。

Do we have a readily available BROWSER_COMPATIBLEhostname verifier for httpclient 4.4?

我们是否有适用BROWSER_COMPATIBLE于 httpclient 4.4的现成的主机名验证程序?

回答by lvaills

Actually, the javadoc of AllowAllHostnameVerifiergives a direct replacement for ALLOW_ALL__HOSTNAME_VERIFIER, which is NoopHostnameVerifier.

实际上,AllowAllHostnameVerifier的 javadoc直接替代了ALLOW_ALL__HOSTNAME_VERIFIER,即NoopH​​ostnameVerifier

回答by vzamanillo

You don't need a new implementation class for AllowAllHostnameVerifierand don't need another implementation for BrowserCompatHostnameVerifier, simply pass an instance to the new DefaultHostnameVerifier,

你不需要一个新的实现类,AllowAllHostnameVerifier也不需要另一个实现BrowserCompatHostnameVerifier,只需将一个实例传递给新的DefaultHostnameVerifier

SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslcontext, new DefaultHostnameVerifier());

this class the neccesary verification methods for both with the following method signatures

此类具有以下方法签名的两者的必要验证方法

public final boolean verify(String host, SSLSession session) (Override)

and

public final void verify(String host, X509Certificate cert) throws SSLException

in the second method the httpcomponents does a checking for matching subdomains

在第二种方法中,httpcomponents 会检查匹配的子域

public final void verify(String host, X509Certificate cert) throws SSLException {
    boolean ipv4 = InetAddressUtils.isIPv4Address(host);
    boolean ipv6 = InetAddressUtils.isIPv6Address(host);
    int subjectType = ((ipv4) || (ipv6)) ? 7 : 2;
    List subjectAlts = extractSubjectAlts(cert, subjectType);
    if ((subjectAlts != null) && (!(subjectAlts.isEmpty()))) {
        if (ipv4)
            matchIPAddress(host, subjectAlts);
        else if (ipv6)
            matchIPv6Address(host, subjectAlts);
        else {
            matchDNSName(host, subjectAlts, this.publicSuffixMatcher);
        }
    } else {
        X500Principal subjectPrincipal = cert.getSubjectX500Principal();
        String cn = extractCN(subjectPrincipal.getName("RFC2253"));
        if (cn == null) {
            throw new SSLException("Certificate subject for <" + host + "> doesn't contain " + "a common name and does not have alternative names");
        }

        matchCN(host, cn, this.publicSuffixMatcher);
    }
}

take a look at the source code for more clarification

查看源代码以获得更多说明

org.apache.http.conn.ssl.DefaultHostnameVerifier

org.apache.http.conn.ssl.DefaultHostnameVerifier

Hope this helps.

希望这可以帮助。

回答by ok2c

BrowserCompatHostnameVerifierwas essentially IE 5/6 compatible implementation. I am no sure if it is actually compatible with more modern browser applications. BrowserCompatHostnameVerifiershould have never existed in the first place and should not be used anymore.

BrowserCompatHostnameVerifier本质上是 IE 5/6 兼容的实现。我不确定它是否真的与更现代的浏览器应用程序兼容。BrowserCompatHostnameVerifier一开始就不应该存在,也不应该再使用。

回答by camposer

I read all this and nothing worked for me, here's what saved my day: https://stackoverflow.com/a/36507502/3090309

我阅读了所有这些,但对我没有任何帮助,这就是拯救我的一天:https: //stackoverflow.com/a/36507502/3090309

I was using:

我正在使用:

compile group: 'org.apache.httpcomponents', name: 'httpclient', version: '4.5.2'