apache httpclient 4.4:HostnameVerifier从4.3.x过渡

Sub*_*ran 15 java apache-httpclient-4.x

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

  1. STRICT_HOSTNAME_VERIFIER
  2. BROWSER_COMPATIBLE_HOSTNAME_VERIFIER
  3. ALLOW_ALL__HOSTNAME_VERIFIER

将依赖项升级到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;
    }

}
Run Code Online (Sandbox Code Playgroud)

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

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

我们是否有一个现成BROWSER_COMPATIBLE的httpclient 4.4主机名验证程序?

lva*_*lls 9

其实,对Javadoc AllowAllHostnameVerifier给出了一个直接替换ALLOW_ALL__HOSTNAME_VERIFIER,这是NoopH​​ostnameVerifier.


vza*_*llo 7

您不需要新的实现类,AllowAllHostnameVerifier也不需要其他实现BrowserCompatHostnameVerifier,只需将实例传递给新的DefaultHostnameVerifier,

SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslcontext, new DefaultHostnameVerifier());
Run Code Online (Sandbox Code Playgroud)

本类使用以下方法签名的必要验证方法

public final boolean verify(String host, SSLSession session) (Override)
Run Code Online (Sandbox Code Playgroud)

public final void verify(String host, X509Certificate cert) throws SSLException
Run Code Online (Sandbox Code Playgroud)

在第二种方法中,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);
    }
}
Run Code Online (Sandbox Code Playgroud)

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

org.apache.http.conn.ssl.DefaultHostnameVerifier

希望这可以帮助.


ok2*_*k2c 1

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