Tuesday, September 24, 2013

JAX WS SSL Configuration to solve wsdl certificate problems

Hi friends,

Back to you after a long time. This past 2 months , i had been crazy busy and hence, did  not  have enough time to discuss anything.

Today , i am going to discuss a very important topic. This is regarding the invocation of  a JAX-WS or JAX-RPC  service.

PROBLEM :
Some time back i was trying to invoke a JAX WS service from a stand alone java application (an application having a java class with the main method and having no application server at all). The problem was, every time i was trying to invoke any service operation, it was giving me a SSL CONFIGURATION EXCEPTION .

REASON :
Now the reason behind it was that, every service call requires to validated . So how is that done ? It's done with the help of certificates. So what i  did was that, i got a hold of those certificates(the service i was using needed 2 of them) and integrated them with my java environment to make the WSDL hoster realize that it was a valid invocation.

SOLUTION (THE JAVA WAY):
My certificate names were cert1.cer and cert2.cer . And this how i integrated them in my  java  environment(In use RAD-Rational Application Developer) :

1. Place the below cry certificates in the path "C:\Program Files\IBM\SDP\jdk\jre\lib\security"

   cert1.cer, cert2.cer 

2. cacerts is the trusStore file. It's present in :
   C:/Program Files/IBM/SDP/jdk/jre/lib/security/cacerts

3. In command prompt perform the below execution :
C:\Program Files\IBM\SDP\jdk\jre\lib\security>"C:\Program Files\IBM\SDP\jdk\jre\bin\keytool" -import -alias cert1 -file cert1.cer -keystore cacerts

4. If it asks keystore password, mention changeit, which is the default keystore password

Enter keystore password: changeit

Trust this certificate? [no]:  yes
Certificate was added to keystore

5. Peform the steps 3 and 4 for the second certificate(cert2.cer).

And , i thought that was the end of it, but apparently it was not to be so. It seems , you have to configure the
"javax.net.ssl"  in your program to make it work, and this is how you have got to do it :

System.setProperty("javax.net.ssl.trustStore", "C:\\Program Files\\IBM\\SDP\\jdk\\jre\\lib\\security\\cacerts");
System.setProperty("javax.net.ssl.trustStorePassword", "changeit");

Now,the problem will be that the above piece of code will configure only the truststore, but that's not all; you have got to configure  the keystore as well. So for this , you have gotta add the following lines of code :

System.setProperty("javax.net.ssl.keyStore", "C:\\Program Files\\IBM\\SDP\\jdk\\jre\\lib\\security\\cacerts");
System.setProperty("javax.net.ssl.keyStorePassword", "changeit");

And voila, everything will start working for you.
In case you are wondering how to add the certificates pro grammatically instead of adding them manually, then you can use this link : http://stackoverflow.com/questions/18764122/how-to-integrate-wsdl-certificates-to-the-cacerts-file-in-jdk-jre-security-folde

THE UNIX WAY( no--check--certificates) :

Now if you are writing a shell script and you are invoking a particular operation of the web service , then you can actually tell the host not to validate the invocation for any certificates.
In my case, i normally use the CURL  command to do my bidding  , though other times it's the WGET command. So for example , my invocation of a service operation using a schell script will look something like this :

#! /bin/sh
ENDPOINT="http://mathertel.de/AJAXEngine/S01_AsyncSamples/CalcService.asmx"
VALUE=1234567890
if [ -n "${1}" ]; then
    VALUE=${1}
fi

curl --silent \
     --data \
     @- \
     --header 'Content-Type: application/soap+xml; charset=utf-8' \
     --user-agent "" \
     ${ENDPOINT} <<EOF | xmllint --format -
<?xml version="1.0" encoding="utf-8"?>
<soap12:Envelope
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:xsd="http://www.w3.org/2001/XMLSchema"
    xmlns:soap12="http://www.w3.org/2003/05/soap-envelope">
  <soap12:Body>
    <CalcPrimeFactors xmlns="http://www.mathertel.de/S01_AsyncSamples/">
      <inputText>${VALUE}</inputText>
    </CalcPrimeFactors>
  </soap12:Body>
</soap12:Envelope>
EOF

DON'T BE AFRAID  or alarmed , this is not a complicated code. Curl's just a command(you have to have it installed though in your linux distro), where you pass the end point and the request structure . Once that is done , this will give an out put , which for brevity , we can parse it using XMLLINT,  which is a command that parses the response in XML format. In case, you do not want to be validated for certificates, you just need to add the option no--check--certificates to the command invocation and you will get the response without   any  certificate hassles .

In my case, the output looks like this :

RESPONSE FROM THE SERVICE :
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <soap:Body>
    <CalcPrimeFactorsResponse xmlns="http://www.mathertel.de/S01_AsyncSamples/">
      <CalcPrimeFactorsResult>2 3 3 5 3607 3803</CalcPrimeFactorsResult>
    </CalcPrimeFactorsResponse>
  </soap:Body>
</soap:Envelope>

Hope this will be  fun to know for you all as it was for me.
Good bye.

2 comments: