除了信任验证和客户端身份验证在SSL/TLS协议层进行之外,HttpClient可以有选择的验证目标主机名是否跟服务端存储在X.509认证里的一致,一旦连接已经建立,这种验证可以为服务器认证提供额外的保障,javax.net.ssl.HostnameVerifier 接口代表了主机名验证的一种策略,HttpClient附带了两中javax.net.ssl.HostnameVerifier的实现,注意:不要把主机名验证跟SSL信任验证混淆
DefaultHostnameVerifier: HttpClient使用的默认实现,与RFC2818兼容,主机名必须匹配证书指定的任何可替换的名称,或者没有可替换名称下证书主体中指定的具体的CN,CN和可替换名称中都可能有通配符。
NoopHostnameVerifier: 这个主机名验证器基本上就是把主机名验证关闭了,它接受任何有效的SSL会话来匹配目标主机。
默认HttpClient使用DefaultHostnameVerifier实现,如果有需要的话你可以指定一个不同的主机名验证器
SSLContext sslContext = SSLContexts.createSystemDefault();SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory( sslContext, NoopHostnameVerifier.INSTANCE);HttpClient4.4使用Mozilla基金会维护的公共后缀列表去确保SSL证书的通配符不会被多个通用顶级域名误用,HttpClient会附带一个该列表的最新的拷贝,最新的修正版在https://publicsuffix.org/list/,强烈建议从源数据每天更新一次并且保持一份本地拷贝。
PublicSuffixMatcher publicSuffixMatcher = PublicSuffixMatcherLoader.load( PublicSuffixMatcher.class.getResource("my-copy-effective_tld_names.dat"));DefaultHostnameVerifier hostnameVerifier = new DefaultHostnameVerifier(publicSuffixMatcher);你可以通过使用null匹配来关闭公共后缀列表验证
DefaultHostnameVerifier hostnameVerifier = new DefaultHostnameVerifier(null);