Introduction
In this tutorial, we will explore to skip SSL certificates validation using the Jersy Client.
We will use jersey Framework to consume the restful web services. It is very easy to consume the web services hosted on HTTP protocol. Challange is consuming the web services hosted on HTTPS with SSL certificates enabled.
Maven Dependencies
Jersey Client
In this tutorial, we will explore to skip SSL certificates validation using the Jersy Client.
We will use jersey Framework to consume the restful web services. It is very easy to consume the web services hosted on HTTP protocol. Challange is consuming the web services hosted on HTTPS with SSL certificates enabled.
Maven Dependencies
<dependency>
<groupId>org.glassfish.jersey.core</groupId>
<artifactId>jersey-client</artifactId>
<version>2.29</version>
</dependency>
Jersey Client
Jersy is the reference implementation of JAX-RS. JAX-RS makes it very easy for Java developers to develop and consume RESTFul web services.
Client Code
When you will run this program, the following exception will be thrown
Solution
We have forgotten to add the following dependency
After adding the above dependency in pom.xml, run the program. Now the following exception will be thrown
Exception 1
Exception 2
Solution
We will need the instances of following classes to resolve these exceptions
Complete Code
import java.security.cert.X509Certificate;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import javax.ws.rs.client.Client;
import javax.ws.rs.client.ClientBuilder;
import javax.ws.rs.client.Invocation;
import javax.ws.rs.client.WebTarget;
import javax.ws.rs.core.Response;
public class SkipSSLCertificateClient {
public static String GET_HTTPS_URL = "Path of API";
public static void main(String[] args) throws Exception{
TrustManager[] selfTrustManager = new TrustManager[] {
new X509TrustManager() {
public X509Certificate[] getAcceptedIssuers() {
// TODO Auto-generated method stub
return null;
}
public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
// TODO Auto-generated method stub
}
public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
// TODO Auto-generated method stub
}
}
};
HostnameVerifier hostnameVerifier = new HostnameVerifier() {
public boolean verify(String arg0, SSLSession arg1) {
// TODO Auto-generated method stub
return true;
}
};
SSLContext sslContext = SSLContext.getInstance("ssl");
sslContext.init(null, selfTrustManager, null );
Client client = ClientBuilder.newBuilder().hostnameVerifier(hostnameVerifier).sslContext(sslContext).build();
WebTarget webTarget = client.target(GET_HTTPS_URL).path("");
Invocation.Builder builder = webTarget.request();
Response response = builder.get();
System.out.println(response.toString());
}
}
Client Code
import javax.ws.rs.client.Client;
import javax.ws.rs.client.ClientBuilder;
import javax.ws.rs.client.Invocation;
import javax.ws.rs.client.WebTarget;
import javax.ws.rs.core.Response;
public class SkipSSLCertificateClient {
public static String GET_HTTPS_URL = "Path of selft signed SSL Certificates API";
public static void main(String[] args) {
Client client = ClientBuilder.newClient();
WebTarget webTarget = client.target(GET_HTTPS_URL).path("");
Invocation.Builder builder = webTarget.request();
Response response = builder.get();
}
}
When you will run this program, the following exception will be thrown
Exception in thread "main" java.lang.IllegalStateException: InjectionManagerFactory not found.
at org.glassfish.jersey.internal.inject.Injections.lambda$lookupInjectionManagerFactory$0(Injections.java:74)
at java.util.Optional.orElseThrow(Optional.java:290)
Solution
We have forgotten to add the following dependency
<dependency>
<groupId>org.glassfish.jersey.inject</groupId>
<artifactId>jersey-hk2</artifactId>
<version>2.29</version>
</dependency>
Exception 1
Exception in thread "main" javax.ws.rs.ProcessingException: javax.net.ssl.SSLHandshakeException: java.security.cert.CertificateException: No subject alternative names matching IP address found
at org.glassfish.jersey.client.internal.HttpUrlConnector.apply(HttpUrlConnector.java:260)
at org.glassfish.jersey.client.ClientRuntime.invoke(ClientRuntime.java:254)
at org.glassfish.jersey.client.JerseyInvocation.lambda$invoke$0(JerseyInvocation.java:729)
at org.glassfish.jersey.internal.Errors.process(Errors.java:292)
at org.glassfish.jersey.internal.Errors.process(Errors.java:274)
at org.glassfish.jersey.internal.Errors.process(Errors.java:205)
Exception 2
javax.ws.rs.ProcessingException: 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
at org.glassfish.jersey.client.internal.HttpUrlConnector.apply(HttpUrlConnector.java:284)
at org.glassfish.jersey.client.ClientRuntime.invoke(ClientRuntime.java:278)
This is the case when a web services provider has used the self-signed SSL certificates. Solution
We will need the instances of following classes to resolve these exceptions
- X509TrustManager
TrustManager[] selfTrustManager = new TrustManager[] {
new X509TrustManager() {
public X509Certificate[] getAcceptedIssuers() {
// TODO Auto-generated method stub
return null;
}
public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
// TODO Auto-generated method stub
}
public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
// TODO Auto-generated method stub
}
}
};
- HostnameVerifier
HostnameVerifier hostnameVerifier = new HostnameVerifier() {
public boolean verify(String arg0, SSLSession arg1) {
// TODO Auto-generated method stub
return true;}
};
- SSLContext
SSLContext sslContext = SSLContext.getInstance("ssl");
sslContext.init(null, selfTrustManager, null );
Complete Code
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import javax.ws.rs.client.Client;
import javax.ws.rs.client.ClientBuilder;
import javax.ws.rs.client.Invocation;
import javax.ws.rs.client.WebTarget;
import javax.ws.rs.core.Response;
public class SkipSSLCertificateClient {
public static String GET_HTTPS_URL = "Path of API";
public static void main(String[] args) throws Exception{
TrustManager[] selfTrustManager = new TrustManager[] {
new X509TrustManager() {
public X509Certificate[] getAcceptedIssuers() {
// TODO Auto-generated method stub
return null;
}
public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
// TODO Auto-generated method stub
}
public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
// TODO Auto-generated method stub
}
}
};
HostnameVerifier hostnameVerifier = new HostnameVerifier() {
public boolean verify(String arg0, SSLSession arg1) {
// TODO Auto-generated method stub
return true;
}
};
SSLContext sslContext = SSLContext.getInstance("ssl");
sslContext.init(null, selfTrustManager, null );
Client client = ClientBuilder.newBuilder().hostnameVerifier(hostnameVerifier).sslContext(sslContext).build();
WebTarget webTarget = client.target(GET_HTTPS_URL).path("");
Invocation.Builder builder = webTarget.request();
Response response = builder.get();
System.out.println(response.toString());
}
}
Conclusion
In this tutorial, we learn how to skip the SSL Certificates validation using the Jersey client. Please leave your comments if you still have any query regarding this topic, I will respond to your queries. Happy coding :)
It's totally helpful, thanks you
ReplyDeleteFirst of all, thank you for your post it's so helpful.
ReplyDeleteI implemented in java 8 and java 6 (version 1.6.0_45), and it work well, but in java 6 version 1.6.0 I got the following error:
javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure at org.glassfish.jersey.client.HttpUrlConnector.apply(HttpUrlConnector.java:229) at org.glassfish.jersey.client.ClientRuntime.invoke(ClientRuntime.java:225) at org.glassfish.jersey.client.JerseyInvocation$1.call(JerseyInvocation.java:655) at org.glassfish.jersey.client.JerseyInvocation$1.call(JerseyInvocation.java:652) at org.glassfish.jersey.internal.Errors.process(Errors.java:315) at org.glassfish.jersey.internal.Errors.process(Errors.java:297) at org.glassfish.jersey.internal.Errors.process(Errors.java:228) at org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:423) at org.glassfish.jersey.client.JerseyInvocation.invoke(JerseyInvocation.java:652) at org.glassfish.jersey.client.JerseyInvocation$Builder.method(JerseyInvocation.java:387) at org.glassfish.jersey.client.JerseyInvocation$Builder.get(JerseyInvocation.java:291)
You know if I need to add some configuration?