Apache HttpClient 4.0에서 유효하지 않은 SSL 인증서 오류를 어떻게 우회 합니까?
답변
자신의 TrustManager를 사용하여 SSLContext를 작성하고이 컨텍스트를 사용하여 HTTPS 체계를 작성해야합니다. 코드는 다음과 같습니다.
SSLContext sslContext = SSLContext.getInstance("SSL");
// set up a TrustManager that trusts everything
sslContext.init(null, new TrustManager[] { new X509TrustManager() {
public X509Certificate[] getAcceptedIssuers() {
System.out.println("getAcceptedIssuers =============");
return null;
}
public void checkClientTrusted(X509Certificate[] certs,
String authType) {
System.out.println("checkClientTrusted =============");
}
public void checkServerTrusted(X509Certificate[] certs,
String authType) {
System.out.println("checkServerTrusted =============");
}
} }, new SecureRandom());
SSLSocketFactory sf = new SSLSocketFactory(sslContext);
Scheme httpsScheme = new Scheme("https", 443, sf);
SchemeRegistry schemeRegistry = new SchemeRegistry();
schemeRegistry.register(httpsScheme);
// apache HttpClient version >4.2 should use BasicClientConnectionManager
ClientConnectionManager cm = new SingleClientConnManager(schemeRegistry);
HttpClient httpClient = new DefaultHttpClient(cm);
답변
다른 모든 답변은 더 이상 사용되지 않거나 HttpClient 4.3에서 작동하지 않았습니다.
http 클라이언트를 빌드 할 때 모든 호스트 이름을 허용하는 방법은 다음과 같습니다.
CloseableHttpClient httpClient = HttpClients
.custom()
.setHostnameVerifier(AllowAllHostnameVerifier.INSTANCE)
.build();
또는 버전 4.4 이상을 사용중인 경우 업데이트 된 호출은 다음과 같습니다.
CloseableHttpClient httpClient = HttpClients
.custom()
.setSSLHostnameVerifier(NoopHostnameVerifier.INSTANCE)
.build();
답변
최신 HttpClient 4.5 로이 작업을 수행해야 했으며 4.4 이후 몇 가지를 더 이상 사용하지 않는 것처럼 보이므로 여기에 나와 가장 최근의 API를 사용하는 스 니펫이 있습니다.
final SSLContext sslContext = new SSLContextBuilder()
.loadTrustMaterial(null, (x509CertChain, authType) -> true)
.build();
return HttpClientBuilder.create()
.setSSLContext(sslContext)
.setConnectionManager(
new PoolingHttpClientConnectionManager(
RegistryBuilder.<ConnectionSocketFactory>create()
.register("http", PlainConnectionSocketFactory.INSTANCE)
.register("https", new SSLConnectionSocketFactory(sslContext,
NoopHostnameVerifier.INSTANCE))
.build()
))
.build();
답변
레코드의 경우 HttpClient 4.1을 사용하여 훨씬 간단하게 수행 할 수 있습니다
SSLSocketFactory sslsf = new SSLSocketFactory(new TrustStrategy() {
public boolean isTrusted(
final X509Certificate[] chain, String authType) throws CertificateException {
// Oh, I am easy...
return true;
}
});
답변
아파치 HttpClient 4.5.5
HttpClient httpClient = HttpClients
.custom()
.setSSLContext(new SSLContextBuilder().loadTrustMaterial(null, TrustAllStrategy.INSTANCE).build())
.setSSLHostnameVerifier(NoopHostnameVerifier.INSTANCE)
.build();
더 이상 사용되지 않는 API가 사용되지 않았습니다.
검증 가능한 간단한 테스트 사례 :
package org.apache.http.client.test;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.conn.ssl.NoopHostnameVerifier;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.ssl.SSLContextBuilder;
import org.junit.Before;
import org.junit.Test;
import java.io.IOException;
import java.security.KeyManagementException;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
public class ApacheHttpClientTest {
private HttpClient httpClient;
@Before
public void initClient() throws NoSuchAlgorithmException, KeyManagementException, KeyStoreException {
httpClient = HttpClients
.custom()
.setSSLContext(new SSLContextBuilder().loadTrustMaterial(null, TrustAllStrategy.INSTANCE).build())
.setSSLHostnameVerifier(NoopHostnameVerifier.INSTANCE)
.build();
}
@Test
public void apacheHttpClient455Test() throws IOException {
executeRequestAndVerifyStatusIsOk("https://expired.badssl.com");
executeRequestAndVerifyStatusIsOk("https://wrong.host.badssl.com");
executeRequestAndVerifyStatusIsOk("https://self-signed.badssl.com");
executeRequestAndVerifyStatusIsOk("https://untrusted-root.badssl.com");
executeRequestAndVerifyStatusIsOk("https://revoked.badssl.com");
executeRequestAndVerifyStatusIsOk("https://pinning-test.badssl.com");
executeRequestAndVerifyStatusIsOk("https://sha1-intermediate.badssl.com");
}
private void executeRequestAndVerifyStatusIsOk(String url) throws IOException {
HttpUriRequest request = new HttpGet(url);
HttpResponse response = httpClient.execute(request);
int statusCode = response.getStatusLine().getStatusCode();
assert statusCode == 200;
}
}
답변
기록을 위해 httpclient 4.3.6으로 테스트했으며 유창한 API의 Executor와 호환됩니다.
CloseableHttpClient httpClient = HttpClients.custom().
setHostnameVerifier(new AllowAllHostnameVerifier()).
setSslcontext(new SSLContextBuilder().loadTrustMaterial(null, new TrustStrategy()
{
public boolean isTrusted(X509Certificate[] arg0, String arg1) throws CertificateException
{
return true;
}
}).build()).build();
답변
Apache HttpClient 4.4의 경우 :
HttpClientBuilder b = HttpClientBuilder.create();
SSLContext sslContext = new SSLContextBuilder().loadTrustMaterial(null, new TrustStrategy() {
public boolean isTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {
return true;
}
}).build();
b.setSslcontext( sslContext);
// or SSLConnectionSocketFactory.getDefaultHostnameVerifier(), if you don't want to weaken
HostnameVerifier hostnameVerifier = SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER;
SSLConnectionSocketFactory sslSocketFactory = new SSLConnectionSocketFactory(sslContext, hostnameVerifier);
Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder.<ConnectionSocketFactory>create()
.register("http", PlainConnectionSocketFactory.getSocketFactory())
.register("https", sslSocketFactory)
.build();
// allows multi-threaded use
PoolingHttpClientConnectionManager connMgr = new PoolingHttpClientConnectionManager( socketFactoryRegistry);
b.setConnectionManager( connMgr);
HttpClient client = b.build();
이것은 실제 작업 구현에서 추출됩니다.
다른 답변은 인기가 있지만 HttpClient 4.4의 경우 작동하지 않습니다. 나는 시간을 소비하고 가능성을 소진했지만 4.4에서 API 변경 및 재배치가 극도로 큰 것으로 보입니다.
http://literatejava.com/networks/ignore-ssl-certificate-errors-apache-httpclient-4-4/ 에서 약간 더 자세한 설명을 참조하십시오.
희망이 도움이됩니다!