Skip to main content

Jersey Client - How to skip SSL certificates validation?



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


<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


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>


After adding the above dependency in pom.xml, run the program. Now the following exception will be thrown

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 :)


Comments

  1. It's totally helpful, thanks you

    ReplyDelete
  2. First of all, thank you for your post it's so helpful.
    I 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?

    ReplyDelete

Post a Comment

Popular posts from this blog

Eclipse - Server Tomcat v8.5 Server at localhost failed to start.

When I try to launch the tomcat from Eclipse, I encountered the following error Server Tomcat v8.5 Server at localhost failed to start. Solution Step 1  Delete the .snap file located at the following location     eclipse workspace Path\ .metadata\.plugins\org.eclipse.core.resources Step 2 Delete the  tmp0  folder from the following path      eclipse workspace Path \.metadata\.plugins\org.eclipse.wst.server.core Step 3  Delete the server from servers list Step 4  Remove already added Tomcat Server      i)  Click on Define a new Server     ii)  Select Server Runtime Environments     iii) Select the Tomcat Server and remove it as follows Remove Selected Server Step 5 Make sure that correct version of Server is configured in Project Properties Step 6 Restart the Eclipse IDE.

Intellij : How to add @author comment to every new class

 Introduction In this tutorial, we will learn how to add @author comments to every new class that we create. We can achieve it using either of the following two solutions Solution 1:  Automatically add @author comments to every new class using Files and Code Templates Open File -> Settings -> Editor -> File and Code Templates -> Includes Click on Includes . Under File Header , enter the following comments text /**  * @author ${USER}  * @Date ${DATE}   */ Intellij - add @author comments Solution 2: Autocompletion of @author Open File  ->  Settings  ->  Editor  -> Live Templates Select Java and then click on + button In Abbreviation, enter @a In template text , enter the following comments           /**             * @author ${USER}             * @Date ${DATE}            */ In option , Expands with select SPACE Intellij - Autocompletion @author You can simply add the @author comments by typing @a and then click SPACE

hibernate-release-5.4.4.Final - Required Jars

Introduction Hibernate (Object Relational Mapping framework) is an implementation of Java Persistence API (JPA) specification.   Required Jars for Hibernate 5.4.4 Following Jars resided inside the required folder are the mandatory jars required for Hibernate 5.4.4 antlr-2.7.7.jar byte-buddy-1.9.11.jar classmate-1.3.4.jar dom4j-2.1.1.jar FastInfoset-1.2.15.jar hibernate-commons-annotations-5.1.0.Final.jar hibernate-core-5.4.4.Final.jar istack-commons-runtime-3.0.7.jar jandex-2.0.5.Final.jar javassist-3.24.0-GA.jar javax.activation-api-1.2.0.jar javax.persistence-api-2.2.jar jaxb-api-2.3.1.jar jaxb-runtime-2.3.1.jar jboss-logging-3.3.2.Final.jar jboss-transaction-api_1.2_spec-1.1.1.Final.jar stax-ex-1.8.jar txw2-2.3.1.jar Hibernate 5.4.4 release is compatible with  Java 8 or 11  JPA 2.2 References https://hibernate.org/orm/releases/5.4/