How to Ignore Certificate Errors in Apache HttpClient 4.5
Typically, a developer will use self-signed certificates on his local machine or in development stage of the project. HttpClient (and web browsers) will not accept untrusted connections, by default. However, we can configure the HttpClient to allow untrusted self-signed certificates.
Note: this is a possible major security risk, when you put this in production, because you’ll basically disable all certification checks, which makes you vulnerable to a man in the middle attack.
In this example we demonstrates how to ignore SSL/TLS Certificate errors in Apache HttpClient 4.5.
Self Signed Certificate Error
When you try to make a request to a server which uses a self signed certificate and the certificate isn’t known by the client, you’ll receive the following exception.
Caused by:
javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException:
PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException:
unable to find valid certification path to requested target
Maven dependencies
We use maven to manage our dependencies and are using Apache HttpClient version 4.5. Add the following dependency to your project.
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.memorynotfound.apache.httpclient.certificate</groupId>
<artifactId>get-server-certificate</artifactId>
<version>1.0.0-SNAPSHOT</version>
<url>https://memorynotfound.com</url>
<name>httpclient - ${project.artifactId}</name>
<dependencies>
<!-- Apache HttpClient -->
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.2</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.5.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>
</project>
Accept Self Signed Certificates
We configure a custom HttpClient
. We begin by setting up an SSLContext
using the SSLContextBuilder
and use the TrustSelfSignedStrategy
class to allow self signed certificates. Using the NoopHostnameVerifier
essentially turns hostname verification off. Create the SSLConnectionSocketFactory
and pass in the SSLContext
and the HostNameVerifier
and build the HttpClient
using the factory methods.
package com.memorynotfound.httpclient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.conn.ssl.*;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.ssl.SSLContextBuilder;
import javax.net.ssl.*;
import java.io.IOException;
import java.security.KeyManagementException;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
/**
* This example demonstrates how to ignore certificate errors.
* These errors include self signed certificate errors and hostname verification errors.
*/
public class HttpClientAcceptSelfSignedCertificate {
public static void main(String... args) {
try (CloseableHttpClient httpclient = createAcceptSelfSignedCertificateClient()) {
HttpGet httpget = new HttpGet("https://example.com");
System.out.println("Executing request " + httpget.getRequestLine());
httpclient.execute(httpget);
System.out.println("----------------------------------------");
} catch (NoSuchAlgorithmException | KeyStoreException | KeyManagementException | IOException e) {
throw new RuntimeException(e);
}
}
private static CloseableHttpClient createAcceptSelfSignedCertificateClient()
throws KeyManagementException, NoSuchAlgorithmException, KeyStoreException {
// use the TrustSelfSignedStrategy to allow Self Signed Certificates
SSLContext sslContext = SSLContextBuilder
.create()
.loadTrustMaterial(new TrustSelfSignedStrategy())
.build();
// we can optionally disable hostname verification.
// if you don't want to further weaken the security, you don't have to include this.
HostnameVerifier allowAllHosts = new NoopHostnameVerifier();
// create an SSL Socket Factory to use the SSLContext with the trust self signed certificate strategy
// and allow all hosts verifier.
SSLConnectionSocketFactory connectionFactory = new SSLConnectionSocketFactory(sslContext, allowAllHosts);
// finally create the HttpClient using HttpClient factory methods and assign the ssl socket factory
return HttpClients
.custom()
.setSSLSocketFactory(connectionFactory)
.build();
}
}
Output
The previous application prints the following messages to the console.
Executing request GET https://example.com HTTP/1.1
----------------------------------------
References
- Apache HttpClient Doc
- TrustSelfSignedStrategy JavaDoc
- NoopHostnameVerifier JavaDoc
- SSLConnectionSocketFactory JavaDoc
- SSLContext JavaDoc
Worked like a charm. Thank you :)
Its really working for me.
Thanks for your post :)
It was useful for me. thank you