问题
HttpClient 4.3 had three static variables in org.apache.http.conn.ssl.SSLConnectionSocketFactory
:
- STRICT_HOSTNAME_VERIFIER
- BROWSER_COMPATIBLE_HOSTNAME_VERIFIER
- 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