Tag Archives: Java

Consuming a SOAP Webservice over HTTPS

In the previous post, we talked about producing and consuming a SOAP web service here. This post will be a sequel to that post since recently I faced a similar issue during my project. In this post, we will talk about how to consume a SOAP Webservice over HTTPS. Since this will be a small post, we will not be posting any code on GitHub.

Problem –

While consuming a SOAP web service which is behind SSL, if you don’t handle SSL certificates, you will run into the following error


sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:387)
at sun.security.validator.PKIXValidator.engineValidate(PKIXValidator.java:292)
at sun.security.validator.Validator.validate(Validator.java:260)
at sun.security.ssl.X509TrustManagerImpl.validate(X509TrustManagerImpl.java:324)
at sun.security.ssl.X509TrustManagerImpl.checkTrusted(X509TrustManagerImpl.java:229)
at sun.security.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:124)
at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1351)
at sun.security.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:156)
at sun.security.ssl.Handshaker.processLoop(Handshaker.java:925)
at sun.security.ssl.Handshaker.process_record(Handshaker.java:860)
at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1043)
at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1343)
at sun.security.ssl.SSLSocketImpl.writeRecord(SSLSocketImpl.java:728)
at sun.security.ssl.AppOutputStream.write(AppOutputStream.java:123)
at sun.security.ssl.AppOutputStream.write(AppOutputStream.java:138)
at SSLPoke.main(SSLPoke.java:31)
Caused by: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
at sun.security.provider.certpath.SunCertPathBuilder.build(SunCertPathBuilder.java:145)
at sun.security.provider.certpath.SunCertPathBuilder.engineBuild(SunCertPathBuilder.java:131)
at java.security.cert.CertPathBuilder.build(CertPathBuilder.java:280)
at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:382)
... 15 more

 

Solution –

Basically this error is happening if your SOAP web service is on SSL and the client is trying to connect to web service, web service doesn’t recognize the client and throws this error.

To resolve this error, you can download an SSL certificate from the server where you are hosting the SOAP web service and import that certificate on your client machine’s Keystore. In a production environment, you should have a way to access this Keystore when a call is made to the web service.

Let’s assume that our web service from the post is on SSL, like https://localhost:8943/benefits/endpoints/users.wsdl. If you access this URL in the browser, you will be able to see the SSL certificate. Export this SSL certificate in base 64 format file, example sslcertificate.crt. Import this certificate in

keytool -import -alias sslcertificateofserver -keystore truststore.jks -storepass changeit -file sslcertificate.crt

Now, we will change the configuration class we wrote to configure web service components.


package com.betterjavacode.benefits.views;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.oxm.jaxb.Jaxb2Marshaller;

@Configuration
public class ClientAppConfig
{
   private Resource getKeyStore()
   {
     Environment.getProperty("betterjavacode.com.keystore");
   }

   private String getKeystorePassword()
   {
     Environment.getProperty("betterjavacode.com.keyStorePassword");
   }

   @Bean
   public Jaxb2Marshaller marshaller()
   {
     Jaxb2Marshaller marshaller = new Jaxb2Marshaller();
     marshaller.setContextPath("com.betterjavacode.benefits.soap");
     return marshaller;
   }

   @Bean
   public UserClient userClient(Jaxb2Marshaller marshaller) 
   {
     // WSDL URL - http://localhost:8080/benefits/endpoints/users.wsdl
     UserClient uc = new UserClient();
     uc.setDefaultUri("http://localhost:8080/benefits/endpoints/users.wsdl");
     uc.setMarshaller(marshaller);
     uc.setUnmarshaller(marshaller);

     FileInputStream fis = new FileInputStream(getKeyStore());
     KeyStore ks = KeyStore.getInstance("JKS");
     ks.load(fis, getKeyStorePassword().toCharArray());

     try 
     {
       fis.close();
     } 
     catch (IOException e) 
     {
     }
     KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
     keyManagerFactory.init(ks, keyStorePassword.toCharArray());

     FileInputStream fisTS = new FileInputStream(getKeyStore());
     KeyStore ts = KeyStore.getInstance("JKS");
     ts.load(fisTS, trustStorePassword.toCharArray());

     try 
     {
       fisTS.close();
     } 
     catch(IOException e) 
     {
     }
     TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
     trustManagerFactory.init(ts);

     HttpsUrlConnectionMessageSender messageSender = new HttpsUrlConnectionMessageSender();
     messageSender.setKeyManagers(keyManagerFactory.getKeyManagers());
     messageSender.setTrustManagers(trustManagerFactory.getTrustManagers());

     HostNameVerifier hv = new HostNameVerifier(){
        @Override
        public boolean verify( String hostname, SSLSession session)
        {
          return true;
        }
     }
     messageSender.setHostnameVerifier(hv);
     uc.setMessageSender(messageSender);
     return uc;
  } 
}

This change should fix the error about PKIX path building failed.

Conclusion –

In conclusion, we showed how to consume a SOAP Webservice over HTTPS by adding Keystore and Truststore check during runtime.

References

Swagger Documentation for Spring Boot REST API – Part II

In this post, we will show how to add swagger documentation to Spring Boot rest API. We learned how to create a Spring Boot REST API. In Microservices’ world, these days documenting your API is a standard norm. Swagger provides a handy interface and a simple way to build these documentations that any client can test at any moment. They don’t need to have all the services in their environment.

What is Swagger?

Swagger was intended to provide a standard, language-agnostic interface to REST APIs which allow anyone to understand the capabilities of a service without any source code, documentation of source code. You can find more details about Swagger here.

How to add swagger documentation?

In our previous post, we added Spring boot REST API. We will add swagger to the same REST API.

  1. Add Maven dependencies

To start with, let’s add maven dependencies for swagger jars.

<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.6.1</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.6.1</version>
<scope>compile</scope>
</dependency>

2. Add Swagger bean in configuration

In our main starting Application class, we will add a few configurations for setting up a bean that will handle swagger. In the below code, I show what I have added in Application.java the file. Basically, we have created a new bean of the type Docket which takes care of the swagger configuration.

@EnableSwagger2
@SpringBootApplication(scanBasePackages = { "com.betterjavacode.benefits" })
public class Application {

public static void main(String[] args) {
 SpringApplication.run(Application.class, args);

}

@Bean
 public Docket benefitsApi() {
 return new Docket(DocumentationType.SWAGGER_2).groupName("Benefits")
 .apiInfo(apiInfo())
 .select()
 .apis(RequestHandlerSelectors.any())
 .paths(PathSelectors.any())
 .build()
 .pathMapping("/");

}

private ApiInfo apiInfo() {
 return new ApiInfoBuilder().title("Benefits REST Service")
 .description(" A simple REST service for Benefits software ")
 .contact(new Contact("Yogesh Mali", "https://betterjavacode.com/", ""))
 .version("1.0")
 .build();
 }
}

3. Show Swagger documentation

Now once we have added the configuration, we can build our project with maven clean install. After a successful build, run the project from eclipse as a Java application. We will access swagger documentation from URL http://localhost:8080/swagger-ui.html. This will look like below :

Swagger Spring Boot Microservice

Source code for this post is available at Spring-boot-rest-api-with-swagger.

Conclusion

In this post, I showed how you can add Swagger Documentation for your Spring Boot based REST API .

Avoid common mistakes when handling exceptions

During vulnerability scanning, we figured out there were a lot of exceptions handled through the print statement. That’s not a very efficient way of handling exceptions.

Print statements are still better than not writing anything to handle. That’s known as swallowing an exception. A good approach to handle exceptions is to write some way to log those exceptions or throw those exceptions with stack trace during runtime. In this post, I showed some ways of handling exceptions.

What are the exceptions?

Exceptions are error events. These events happen during the runtime of a program. This generally disrupts the flow of the program.

There are three components to exception handlers – try, catch, and finally.

try – This part of exception handling contains code that will be executed during every flow.

catch – If code in try part throws a runtime exception, that will be caught in catch part.

finally – This contains the code you want to execute after trying part of the execution is done. This ensures that finally block is executed even when unexpected exceptions occur. It is mostly used to clean up resources.

Types of Exceptions 

  • Unchecked Exceptions – Exception types that are direct or indirect subclasses of a class RuntimeException , those are the unchecked exceptions.
  • Checked Exceptions – Exceptions that inherit Exception class are known as checked exceptions. RuntimeException are also extended from Exception , but client code doesn’t have to handle them, while Checked exceptions have to be handled by catch or throws clause.

How to handle Exceptions

What exceptions to use? Checked or Unchecked?

In case the code doesn’t know what to do if an exception is thrown, it should be an unchecked exception. If code using an exception knows what to do to recover from that exception along with logging that information, that should be checked exception.

Preserve encapsulation

Don’t propagate an exception from the data access layer to the business object layer.
Example – SQLException is a RuntimeException. If the data access layer throws this exception in the following manner, the catch block will not do anything but will suppress it.

public void dataAccessCode()
{
    try
    {

    }
    catch (SQLException ex)
    {
        ex.printStacktrace();
     }
}

On the other hand, to preserve encapsulation, the same runtime exception can be converted into another unchecked exception like below

public void dataAccessCode()
{
    try
   {

   }
   catch (SQLException ex)
   {
      throw new RuntimeException(ex);
    }
}

Best practices for Exceptions

1) Use finally block for cleaning the code
2) Do not ignore or suppress an exception
3) Log exceptions once
4) Do not use exceptions for flow control

References

  1. Best Practices for Exceptions
  2. Checked Vs Unchecked Exceptions

 

Thread-safe code

Yes, just like every other programmer, I have been asked “Is this code thread safe?” and many times I have pondered in my head , what that actually means. Honestly I am not competent enough in multi-threading programming and even answering this question. But then there comes a time when you learn about this and say “Yes, the code is thread safe and it will execute correctly in case of simultaneous execution by multiple threads.”

Wikipedia says about thread-safety

“A piece of code is thread-safe if it only manipulates shared data structures in a manner that guarantees safe execution by multiple threads at the same time “

Most of the problems arise in multi-threaded environment when accessing shared data.

Here is an example of the code which can be safe in a single-threaded environment, but not in multi-threaded.

public class Counter
{
   private static int count = 0;
   public static int incrementCount()
   {
      return count++;
   }
}

count is a shared integer variable here. In a multi-threaded environment, it can lose the right value during the update operation. Increment operation for count performs read, add, and update. In case if two threads are accessing incrementCount method and not synchronized, they can cause the wrong value of count.

How to make this code thread-safe

public class Counter
{
   private static int count = 0;
   public static synchronized int incrementCount()
   {
      return count++;
   }
}

synchronized adds that mutual exclusion between threads while accessing incrementCount method. So at one time, only one thread can access the method. Instead of making the whole method synchronized, only part of the code can also be made synchronized.

Conclusion

I showed how we can write thread safe programming. If you enjoyed this post, subscribe to my blog. If you want to learn more about thread safety, read this post.