忽略 Apache HttpClient 4.3 中的 SSL 证书
Posted
技术标签:
【中文标题】忽略 Apache HttpClient 4.3 中的 SSL 证书【英文标题】:Ignoring SSL certificate in Apache HttpClient 4.3 【发布时间】:2013-10-31 07:17:32 【问题描述】:如何忽略 Apache HttpClient 4.3 的 SSL 证书(全部信任)?
我在 SO 上找到的所有答案都处理以前的版本,并且 API 发生了变化。
相关:
How to ignore SSL certificate errors in Apache HttpClient 4.0 How to handle invalid SSL certificates with Apache HttpClient? Need to trust all the certificates during the development using Spring Ignore SSL Certificate Errors with Java编辑:
仅用于测试目的。孩子们,不要在家里(或在生产中)尝试【问题讨论】:
【参考方案1】:以下代码适用于信任自签名证书。创建客户端时必须使用TrustSelfSignedStrategy:
SSLContextBuilder builder = new SSLContextBuilder();
builder.loadTrustMaterial(null, new TrustSelfSignedStrategy());
SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(
builder.build());
CloseableHttpClient httpclient = HttpClients.custom().setSSLSocketFactory(
sslsf).build();
HttpGet httpGet = new HttpGet("https://some-server");
CloseableHttpResponse response = httpclient.execute(httpGet);
try
System.out.println(response.getStatusLine());
HttpEntity entity = response.getEntity();
EntityUtils.consume(entity);
finally
response.close();
我没有故意包含SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER
:重点是允许使用自签名证书进行测试,这样您就不必从证书颁发机构获得适当的证书。您可以使用正确的主机名轻松创建自签名证书,因此不要添加 SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER
标志。
【讨论】:
我必须在构造函数中添加参数 SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER 才能使其与 HttpClientBuilder 一起工作(如 holmis83 对 vasekt 的响应中所述)。 也可以参考httpclient网站上的例子hc.apache.org/httpcomponents-client-4.3.x/httpclient/examples/… 我还必须使用 ALLOW_ALL_HOSTNAME_VERIFIER:SSLConnectionSocketFactory(builder.build(), SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER); 这段代码适用于我没有使用带有参数SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER
的弃用构造函数@
我希望你已经指定了你正在使用的类的完整参考。 Idea 发现了多个名为SSLContextBuilder
的类。【参考方案2】:
作为对@mavroprovato 答案的补充,如果您想信任所有证书而不仅仅是自签名,您会这样做(以您的代码风格)
builder.loadTrustMaterial(null, new TrustStrategy()
public boolean isTrusted(X509Certificate[] chain, String authType)
throws CertificateException
return true;
);
或(从我自己的代码中直接复制粘贴):
import javax.net.ssl.SSLContext;
import org.apache.http.ssl.TrustStrategy;
import org.apache.http.ssl.SSLContexts;
// ...
SSLContext sslContext = SSLContexts
.custom()
//FIXME to contain real trust store
.loadTrustMaterial(new TrustStrategy()
@Override
public boolean isTrusted(X509Certificate[] chain,
String authType) throws CertificateException
return true;
)
.build();
如果你也想跳过主机名验证,你需要设置
CloseableHttpClient httpclient = HttpClients.custom().setSSLSocketFactory(
sslsf).setSSLHostnameVerifier( NoopHostnameVerifier.INSTANCE).build();
也是。 (ALLOW_ALL_HOSTNAME_VERIFIER 已弃用)。
强制性警告:您不应该这样做,接受所有证书是一件坏事。但是,您希望在一些罕见的用例中执行此操作。
作为前面给出的代码的注释,即使 httpclient.execute() 抛出异常,您也需要关闭响应
CloseableHttpResponse response = null;
try
response = httpclient.execute(httpGet);
System.out.println(response.getStatusLine());
HttpEntity entity = response.getEntity();
EntityUtils.consume(entity);
finally
if (response != null)
response.close();
上面的代码是用
测试的<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.3</version>
</dependency>
对于感兴趣的,这是我的完整测试集:
import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.conn.ssl.NoopHostnameVerifier;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.conn.ssl.TrustSelfSignedStrategy;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.ssl.SSLContextBuilder;
import org.apache.http.ssl.TrustStrategy;
import org.apache.http.util.EntityUtils;
import org.junit.Test;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLHandshakeException;
import javax.net.ssl.SSLPeerUnverifiedException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
public class TrustAllCertificatesTest
final String expiredCertSite = "https://expired.badssl.com/";
final String selfSignedCertSite = "https://self-signed.badssl.com/";
final String wrongHostCertSite = "https://wrong.host.badssl.com/";
static final TrustStrategy trustSelfSignedStrategy = new TrustSelfSignedStrategy();
static final TrustStrategy trustAllStrategy = new TrustStrategy()
public boolean isTrusted(X509Certificate[] chain, String authType)
throws CertificateException
return true;
;
@Test
public void testSelfSignedOnSelfSignedUsingCode() throws Exception
doGet(selfSignedCertSite, trustSelfSignedStrategy);
@Test(expected = SSLHandshakeException.class)
public void testExpiredOnSelfSignedUsingCode() throws Exception
doGet(expiredCertSite, trustSelfSignedStrategy);
@Test(expected = SSLPeerUnverifiedException.class)
public void testWrongHostOnSelfSignedUsingCode() throws Exception
doGet(wrongHostCertSite, trustSelfSignedStrategy);
@Test
public void testSelfSignedOnTrustAllUsingCode() throws Exception
doGet(selfSignedCertSite, trustAllStrategy);
@Test
public void testExpiredOnTrustAllUsingCode() throws Exception
doGet(expiredCertSite, trustAllStrategy);
@Test(expected = SSLPeerUnverifiedException.class)
public void testWrongHostOnTrustAllUsingCode() throws Exception
doGet(wrongHostCertSite, trustAllStrategy);
@Test
public void testSelfSignedOnAllowAllUsingCode() throws Exception
doGet(selfSignedCertSite, trustAllStrategy, NoopHostnameVerifier.INSTANCE);
@Test
public void testExpiredOnAllowAllUsingCode() throws Exception
doGet(expiredCertSite, trustAllStrategy, NoopHostnameVerifier.INSTANCE);
@Test
public void testWrongHostOnAllowAllUsingCode() throws Exception
doGet(expiredCertSite, trustAllStrategy, NoopHostnameVerifier.INSTANCE);
public void doGet(String url, TrustStrategy trustStrategy, HostnameVerifier hostnameVerifier) throws Exception
SSLContextBuilder builder = new SSLContextBuilder();
builder.loadTrustMaterial(trustStrategy);
SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(
builder.build());
CloseableHttpClient httpclient = HttpClients.custom().setSSLSocketFactory(
sslsf).setSSLHostnameVerifier(hostnameVerifier).build();
HttpGet httpGet = new HttpGet(url);
CloseableHttpResponse response = httpclient.execute(httpGet);
try
System.out.println(response.getStatusLine());
HttpEntity entity = response.getEntity();
EntityUtils.consume(entity);
finally
response.close();
public void doGet(String url, TrustStrategy trustStrategy) throws Exception
SSLContextBuilder builder = new SSLContextBuilder();
builder.loadTrustMaterial(trustStrategy);
SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(
builder.build());
CloseableHttpClient httpclient = HttpClients.custom().setSSLSocketFactory(
sslsf).build();
HttpGet httpGet = new HttpGet(url);
CloseableHttpResponse response = httpclient.execute(httpGet);
try
System.out.println(response.getStatusLine());
HttpEntity entity = response.getEntity();
EntityUtils.consume(entity);
finally
response.close();
(工作测试项目in github)
【讨论】:
HttpClient#execute 永远不会在出现异常的情况下返回空响应对象。此外,库存 HttpClient 实现将确保在请求执行期间发生异常时自动释放所有系统资源,例如租用的连接。 mavroprovato 使用的异常处理是完全足够的。 @oleg Closable interface 的意思是“关闭 [...] 流并释放与之关联的任何系统资源。如果流已经关闭,则调用此方法无效。”因此,即使不需要它,也最好使用它。另外,我不明白返回 null 响应的注释——当然它不会,如果它抛出异常,它不会返回任何东西? Apache HttpClient 从不ever 返回一个空值或部分初始化的响应对象。这与调用#close 的次数无关,而是在 finally 子句中完全不必要的 null 检查 @oleg 并且我给出的代码从来没有假设它会返回一个 null 或部分初始化的响应对象,甚至检查这种情况。我不知道你在说什么? [sigh] 这完全没有必要,因为 HttpResponse 永远不能为空,并且如果出现异常,#execute 方法将终止而不返回响应;-)【参考方案3】:如果您使用上面的 PoolingHttpClientConnectionManager 过程不起作用,自定义 SSLContext 将被忽略。创建 PoolingHttpClientConnectionManager 时必须在构造函数中传递 socketFactoryRegistry。
SSLContextBuilder builder = SSLContexts.custom();
builder.loadTrustMaterial(null, new TrustStrategy()
@Override
public boolean isTrusted(X509Certificate[] chain, String authType)
throws CertificateException
return true;
);
SSLContext sslContext = builder.build();
SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(
sslContext, new X509HostnameVerifier()
@Override
public void verify(String host, SSLSocket ssl)
throws IOException
@Override
public void verify(String host, X509Certificate cert)
throws SSLException
@Override
public void verify(String host, String[] cns,
String[] subjectAlts) throws SSLException
@Override
public boolean verify(String s, SSLSession sslSession)
return true;
);
Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder
.<ConnectionSocketFactory> create().register("https", sslsf)
.build();
PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager(
socketFactoryRegistry);
CloseableHttpClient httpclient = HttpClients.custom()
.setConnectionManager(cm).build();
【讨论】:
您可以使用 SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER,而不是构建自己的 X509HostnameVerifier。 正如下面@rich95 所标记的,HttpClients 的默认设置是为您提供一个 PoolingHttpClient,因此这经常是相关的。在发现我需要这个之前,我必须尝试很多这些答案。 试图在 WebSphere 上应用这个并得到“java.security.KeyStoreException: IBMTrustManager: Problem access trust store java.io.IOException: Invalid keystore format” 为了避免你需要通过 KeyStore trustStore = KeyStore.getInstance (KeyStore.getDefaultType());而不是 null 到 builder.loadTrustMaterial 实际上,使用 HttpClient 4.5,HttpClients.custom().setConnectionManager(cm).build()
和 HttpClients.custom().setSSLSocketFactory(connectionFactory).build()
都可以使用,因此您无需创建 PoolingHttpClientConnectionManager
创建后如何使用 PoolingHttpClientConnectionManager,我的代码正在运行,但我想知道连接池是否有效【参考方案4】:
vasekt 对答案的一个小补充:
提供的 SocketFactoryRegistry 解决方案在使用 PoolingHttpClientConnectionManager 时有效。
但是,通过普通 http 的连接不再起作用。您必须另外为 http 协议添加一个 PlainConnectionSocketFactory 才能使它们再次工作:
Registry<ConnectionSocketFactory> socketFactoryRegistry =
RegistryBuilder.<ConnectionSocketFactory> create()
.register("https", sslsf)
.register("http", new PlainConnectionSocketFactory()).build();
【讨论】:
我相信http
协议默认使用PlainConnectionSocketFactory
。我只注册了https
,而httpclient
仍然可以获得纯HTTP URL。所以我认为这一步没有必要。
@soulmachine 它不会用于PoolingHttpClientConnectionManager
谢谢@migo.. 我绝对需要两者,在 qa 我处理 http,在生产中,它是 https【参考方案5】:
(我会直接在 vasekt 的回答中添加评论,但我没有足够的声望点(不确定那里的逻辑)
无论如何...我想说的是,即使您没有明确创建/请求 PoolingConnection,也不意味着您没有得到一个。
我疯了,想弄清楚为什么原来的解决方案对我不起作用,但我忽略了 vasekt 的回答,因为它“不适用于我的情况”——错了!
我在低时盯着我的堆栈跟踪,发现我在它中间看到了一个 PoolingConnection。 Bang - 我厌倦了他的加入和成功! (我们的演示是明天,我快绝望了):-)
【讨论】:
【参考方案6】:在尝试了各种选项后,以下配置对 http 和 https 都有效:
SSLContextBuilder builder = new SSLContextBuilder();
builder.loadTrustMaterial(null, new TrustSelfSignedStrategy());
SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(
builder.build(), SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
Registry<ConnectionSocketFactory> registry = RegistryBuilder.
<ConnectionSocketFactory> create()
.register("http", new PlainConnectionSocketFactory())
.register("https", sslsf)
.build();
PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager(registry);
cm.setMaxTotal(2000);
CloseableHttpClient httpClient = HttpClients.custom()
.setSSLSocketFactory(sslsf)
.setConnectionManager(cm)
.build();
我正在使用 http-client 4.3.3:compile 'org.apache.httpcomponents:httpclient:4.3.3'
【讨论】:
感谢您提供全面、完整的示例!我在以前的解决方案中遇到了多个问题,这非常有帮助。还帮助您提供了导入语句,因为有多个具有相同名称的类,增加了混乱。【参考方案7】:class ApacheHttpClient
/***
* This is a https get request that bypasses certificate checking and hostname verifier.
* It uses basis authentication method.
* It is tested with Apache httpclient-4.4.
* It dumps the contents of a https page on the console output.
* It is very similar to http get request, but with the additional customization of
* - credential provider, and
* - SSLConnectionSocketFactory to bypass certification checking and hostname verifier.
* @param path String
* @param username String
* @param password String
* @throws IOException
*/
public void get(String path, String username, String password) throws IOException
final CloseableHttpClient httpClient = HttpClients.custom()
.setDefaultCredentialsProvider(createCredsProvider(username, password))
.setSSLSocketFactory(createGenerousSSLSocketFactory())
.build();
final CloseableHttpResponse response = httpClient.execute(new HttpGet(path));
try
HttpEntity entity = response.getEntity();
if (entity == null)
return;
System.out.println(EntityUtils.toString(entity));
finally
response.close();
httpClient.close();
private CredentialsProvider createCredsProvider(String username, String password)
CredentialsProvider credsProvider = new BasicCredentialsProvider();
credsProvider.setCredentials(
AuthScope.ANY,
new UsernamePasswordCredentials(username, password));
return credsProvider;
/***
*
* @return SSLConnectionSocketFactory that bypass certificate check and bypass HostnameVerifier
*/
private SSLConnectionSocketFactory createGenerousSSLSocketFactory()
SSLContext sslContext;
try
sslContext = SSLContext.getInstance("SSL");
sslContext.init(null, new TrustManager[]createGenerousTrustManager(), new SecureRandom());
catch (KeyManagementException | NoSuchAlgorithmException e)
e.printStackTrace();
return null;
return new SSLConnectionSocketFactory(sslContext, NoopHostnameVerifier.INSTANCE);
private X509TrustManager createGenerousTrustManager()
return new X509TrustManager()
@Override
public void checkClientTrusted(X509Certificate[] cert, String s) throws CertificateException
@Override
public void checkServerTrusted(X509Certificate[] cert, String s) throws CertificateException
@Override
public X509Certificate[] getAcceptedIssuers()
return null;
;
【讨论】:
【参考方案8】:更简单、更短的工作代码:
我们使用的是 HTTPClient 4.3.5,我们尝试了 *** 上几乎所有的解决方案,但没有, 经过思考和解决问题后,我们得出以下完美运行的代码, 只需在创建 HttpClient 实例之前添加它。
你用来发出post请求的一些方法...
SSLContextBuilder builder = new SSLContextBuilder();
builder.loadTrustMaterial(null, new TrustStrategy()
@Override
public boolean isTrusted(X509Certificate[] chain, String authType) throws CertificateException
return true;
);
SSLConnectionSocketFactory sslSF = new SSLConnectionSocketFactory(builder.build(),
SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
HttpClient httpClient = HttpClients.custom().setSSLSocketFactory(sslSF).build();
HttpPost postRequest = new HttpPost(url);
继续以正常形式调用和使用 HttpPost 实例
【讨论】:
我们如何在标题中发布数据?如果我们这样做了,那么请查看 HTTP/1.1 400 Bad Request 适用于 4.5,谢谢! (虽然使用了大量已弃用的东西 LOL)【参考方案9】:使用 http 客户端 4.5 时,我必须使用 javasx.net.ssl.HostnameVerifier 来允许任何主机名(用于测试目的)。这是我最终做的:
CloseableHttpClient httpClient = null;
try
SSLContextBuilder sslContextBuilder = new SSLContextBuilder();
sslContextBuilder.loadTrustMaterial(null, new TrustSelfSignedStrategy());
HostnameVerifier hostnameVerifierAllowAll = new HostnameVerifier()
public boolean verify(String hostname, SSLSession session)
return true;
;
SSLConnectionSocketFactory sslSocketFactory = new SSLConnectionSocketFactory(sslContextBuilder.build(), hostnameVerifierAllowAll);
CredentialsProvider credsProvider = new BasicCredentialsProvider();
credsProvider.setCredentials(
new AuthScope("192.168.30.34", 8443),
new UsernamePasswordCredentials("root", "password"));
httpClient = HttpClients.custom()
.setSSLSocketFactory(sslSocketFactory)
.setDefaultCredentialsProvider(credsProvider)
.build();
HttpGet httpGet = new HttpGet("https://192.168.30.34:8443/axis/services/getStuff?firstResult=0&maxResults=1000");
CloseableHttpResponse response = httpClient.execute(httpGet);
int httpStatus = response.getStatusLine().getStatusCode();
if (httpStatus >= 200 && httpStatus < 300) [...]
else
throw new ClientProtocolException("Unexpected response status: " + httpStatus);
catch (Exception ex)
ex.printStackTrace();
finally
try
httpClient.close();
catch (IOException ex)
logger.error("Error while closing the HTTP client: ", ex);
【讨论】:
HostnameVerifier 的实现解决了 HTTPClient 4.5 的问题。 喜欢lambdas (JDK1.8)的朋友,可以把SSLConnectionSocketFactory sslSocketFactory = new SSLConnectionSocketFactory(sslContextBuilder.build(), hostnameVerifierAllowAll);
换成SSLConnectionSocketFactory sslSocketFactory = new SSLConnectionSocketFactory(sslContextBuilder.build(), (hostName, sslSession) -> true);
。它避免了匿名类并使代码更具可读性。【参考方案10】:
信任 Apache HTTP 客户端中的所有证书
TrustManager[] trustAllCerts = new TrustManager[]
new X509TrustManager()
public java.security.cert.X509Certificate[] getAcceptedIssuers()
return null;
public void checkClientTrusted(
java.security.cert.X509Certificate[] certs, String authType)
public void checkServerTrusted(
java.security.cert.X509Certificate[] certs, String authType)
;
try
SSLContext sc = SSLContext.getInstance("SSL");
sc.init(null, trustAllCerts, new java.security.SecureRandom());
SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(
sc);
httpclient = HttpClients.custom().setSSLSocketFactory(
sslsf).build();
HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
【讨论】:
这适用于 httpclient 4.5.9 ,只需复制并粘贴整个内容即可。【参考方案11】:在PoolingHttpClientConnectionManager
和Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder.<ConnectionSocketFactory> create().register("https", sslFactory).build();
之上
如果你想要一个使用PoolingNHttpClientConnectionManager
的异步httpclient,代码应该类似于以下
SSLContextBuilder builder = SSLContexts.custom();
builder.loadTrustMaterial(null, new TrustStrategy()
@Override
public boolean isTrusted(X509Certificate[] chain, String authType)
throws CertificateException
return true;
);
SSLContext sslContext = builder.build();
SchemeiosessionStrategy sslioSessionStrategy = new SSLIOSessionStrategy(sslContext,
new HostnameVerifier()
@Override
public boolean verify(String hostname, SSLSession session)
return true;// TODO as of now allow all hostnames
);
Registry<SchemeIOSessionStrategy> sslioSessionRegistry = RegistryBuilder.<SchemeIOSessionStrategy>create().register("https", sslioSessionStrategy).build();
PoolingNHttpClientConnectionManager ncm = new PoolingNHttpClientConnectionManager(new DefaultConnectingIOReactor(),sslioSessionRegistry);
CloseableHttpAsyncClient asyncHttpClient = HttpAsyncClients.custom().setConnectionManager(ncm).build();
asyncHttpClient.start();
【讨论】:
【参考方案12】:这是对上述技术的一个有效提炼,相当于“curl --insecure”:
HttpClient getInsecureHttpClient() throws GeneralSecurityException
TrustStrategy trustStrategy = new TrustStrategy()
@Override
public boolean isTrusted(X509Certificate[] chain, String authType)
return true;
;
HostnameVerifier hostnameVerifier = new HostnameVerifier()
@Override
public boolean verify(String hostname, SSLSession session)
return true;
;
return HttpClients.custom()
.setSSLSocketFactory(new SSLConnectionSocketFactory(
new SSLContextBuilder().loadTrustMaterial(trustStrategy).build(),
hostnameVerifier))
.build();
【讨论】:
【参考方案13】:您可以使用以下代码 sn-p 获取 HttpClient 实例而无需检查 ssl 认证。
private HttpClient getSSLHttpClient() throws KeyStoreException, NoSuchAlgorithmException, KeyManagementException
LogLoader.serverLog.trace("In getSSLHttpClient()");
SSLContext context = SSLContext.getInstance("SSL");
TrustManager tm = new X509TrustManager()
public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException
public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException
public X509Certificate[] getAcceptedIssuers()
return null;
;
context.init(null, new TrustManager[] tm , null);
HttpClientBuilder builder = HttpClientBuilder.create();
SSLConnectionSocketFactory sslConnectionFactory = new SSLConnectionSocketFactory(context);
builder.setSSLSocketFactory(sslConnectionFactory);
PlainConnectionSocketFactory plainConnectionSocketFactory = new PlainConnectionSocketFactory();
Registry<ConnectionSocketFactory> registry = RegistryBuilder.<ConnectionSocketFactory>create()
.register("https", sslConnectionFactory).register("http", plainConnectionSocketFactory).build();
PoolingHttpClientConnectionManager ccm = new PoolingHttpClientConnectionManager(registry);
ccm.setMaxTotal(BaseConstant.CONNECTION_POOL_SIZE);
ccm.setDefaultMaxPerRoute(BaseConstant.CONNECTION_POOL_SIZE);
builder.setConnectionManager((HttpClientConnectionManager) ccm);
builder.disableRedirectHandling();
LogLoader.serverLog.trace("Out getSSLHttpClient()");
return builder.build();
【讨论】:
【参考方案14】:如果您使用的是 HttpClient 4.5.x
,您的代码可能类似于以下内容:
SSLContext sslContext = new SSLContextBuilder().loadTrustMaterial(null,
TrustSelfSignedStrategy.INSTANCE).build();
SSLConnectionSocketFactory sslSocketFactory = new SSLConnectionSocketFactory(
sslContext, NoopHostnameVerifier.INSTANCE);
HttpClient httpClient = HttpClients.custom()
.setDefaultCookieStore(new BasicCookieStore())
.setSSLSocketFactory(sslSocketFactory)
.build();
【讨论】:
对我不起作用。我正在使用 HttpClient:4.5.5。和 HttpCore 4.4.9【参考方案15】:对上面@divbyzero 的回答稍作调整,以修复声纳安全警告
CloseableHttpClient getInsecureHttpClient() throws GeneralSecurityException
TrustStrategy trustStrategy = (chain, authType) -> true;
HostnameVerifier hostnameVerifier = (hostname, session) -> hostname.equalsIgnoreCase(session.getPeerHost());
return HttpClients.custom()
.setSSLSocketFactory(new SSLConnectionSocketFactory(new SSLContextBuilder().loadTrustMaterial(trustStrategy).build(), hostnameVerifier))
.build();
【讨论】:
【参考方案16】:最初,我能够使用信任策略禁用 localhost,后来我添加了 NoopHostnameVerifier。现在它将适用于 localhost 和任何机器名称
SSLContext sslContext = SSLContextBuilder.create().loadTrustMaterial(null, new TrustStrategy()
@Override
public boolean isTrusted(X509Certificate[] chain, String authType) throws CertificateException
return true;
).build();
SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(
sslContext, NoopHostnameVerifier.INSTANCE);
CloseableHttpClient httpclient = HttpClients.custom().setSSLSocketFactory(sslsf).build();
【讨论】:
以上是关于忽略 Apache HttpClient 4.3 中的 SSL 证书的主要内容,如果未能解决你的问题,请参考以下文章
Apache HttpClient 4.3 - 设置连接空闲超时
如何使用 Apache HttpClient 4.3 处理 Cookie
Apache HttpClient 4.3 和 x509 客户端证书进行身份验证
如何忽略 Apache HttpComponents HttpClient 5.1 中的 SSL 证书错误