Apache httpclient 4.4: Переключение HostnameVerifier из 4.3.x

HttpClient 4.3 имел три статические переменные в org.apache.http.conn.ssl.SSLConnectionSocketFactory:

  • STRICT_HOSTNAME_VERIFIER
  • BROWSER_COMPATIBLE_HOSTNAME_VERIFIER
  • ALLOW_ALL__HOSTNAME_VERIFIER

При обновлении зависимости от версии 4.4 HttpClient я вижу, что все вышеперечисленные константы устарели. В примечании к устареванию в 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;
    }

}

Существует тонкое различие между STRICT_HOSTNAME_VERIFIER и BROWSER_COMPATIBLE_HOSTNAME_VERIFIER (из JavaDoc):

Единственная разница между BROWSER_COMPATIBLE и STRICT заключается в том, что подстановочный знак (например, "*.foo.com" ) с BROWSER_COMPATIBLE соответствует всем поддоменам, включая "a.b.foo.com".

У нас есть легкодоступный верификатор хоста BROWSER_COMPATIBLE для httpclient 4.4?

Ответ 2

Вам не нужен новый класс реализации для AllowAllHostnameVerifier и не нужна другая реализация для BrowserCompatHostnameVerifier, просто передайте экземпляр новой DefaultHostnameVerifier,

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

этот класс - необходимые методы проверки для обоих со следующими сигналами метода

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

и

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

во втором методе 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);
    }
}

взгляните на исходный код, чтобы узнать больше.

org.apache.http.conn.ssl.DefaultHostnameVerifier

Надеюсь, что это поможет.

Ответ 3

BrowserCompatHostnameVerifier был по существу совместимым с IE 5/6. Я не уверен, действительно ли он совместим с более современными приложениями для браузеров. BrowserCompatHostnameVerifier никогда не должен существовать в первую очередь и больше не должен использоваться.

Ответ 4

Я прочитал все это, и ничего не сработало для меня, вот что спасло мой день: fooobar.com/info/168304/...

Я использовал:

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