apache httpclient 4.4: HostnameVerifier transition from 4.3.x

生来就可爱ヽ(ⅴ<●) 提交于 2020-05-25 06:12:20

问题


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

  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 DefaultHostnameVerifier is a direct replacement to STRICT_HOSTNAME_VERIFIER. Also the ALLOW_ALL__HOSTNAME_VERIFIER is easy to implement:

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_VERIFIER and BROWSER_COMPATIBLE_HOSTNAME_VERIFIER (from 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".

Do we have a readily available BROWSER_COMPATIBLE hostname verifier for httpclient 4.4?


回答1:


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




回答2:


You don't need a new implementation class for AllowAllHostnameVerifier and don't need another implementation for BrowserCompatHostnameVerifier, simply pass an instance to the new 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

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

Hope this helps.




回答3:


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




回答4:


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

I was using:

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


来源:https://stackoverflow.com/questions/29207694/apache-httpclient-4-4-hostnameverifier-transition-from-4-3-x

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!