Wednesday, July 25, 2012

Enabling SSL for Axis2 web services

I have always had the trouble of setting up SSL based communication for my web services. I searched internet and finally nailed down the correct solution. I presume that you have a Axis2 web service running on Apache Tomcat server.

Here is what I have used:
  • JDK and JRE 1.6
  • Apache Tomcat 7.0.8
  • Axis2 WAR distribution 1.6.2 (or Axis2 stand alone distribution)
Step#1: Generate server keystore and certificate
/root/my_workspace> vi gencerts.sh

#!/bin/sh

KEYTOOL=$JAVA_HOME/bin/keytool
echo Generating the Server KeyStore in file server.keystore
# The value of CN should be the IP address or host name on which web application will be deployed. Avoid specifying 'localhost'
$KEYTOOL -genkey -alias tomcat-sv -dname "CN=localhost, OU=X, O=Y, L=Z, S=XY, C=YZ" -keyalg RSA -keypass changeit -storepass changeit -keystore server.keystore

echo Exporting the certificate from keystore to an external file server.cer

$KEYTOOL -export -alias tomcat-sv -storepass changeit -file server.cer -keystore server.keystore

echo Generating the Client KeyStore in file client.keystore

$KEYTOOL -genkey -alias tomcat-cl -dname "CN=Client, OU=X, O=Y, L=Z, S=XY, C=YZ" -keyalg RSA -keypass changeit -storepass changeit -keystore client.keystore

echo Exporting the certificate from keystore to external file client.cer

$KEYTOOL -export -alias tomcat-cl -storepass changeit -file client.cer -keystore client.keystore

echo Importing Client's certificate into Server's keystore

$KEYTOOL -import -v -trustcacerts -alias tomcat -file server.cer -keystore client.keystore -keypass changeit -storepass changeit

echo Importing Server's certificate into Client's keystore

$KEYTOOL -import -v -trustcacerts -alias tomcat -file client.cer -keystore server.keystore -keypass changeit -storepass changeit

/root/my_workspace> chmod +x gencerts.sh
/root/my_workspace> ./gencerts.sh
Note:
  • You can also write the above script in a BAT file for Windows OS. You require client keystore if you want to write a java client to interact with the web service

  • The certificates generated by the script above is for testing purposes only. The browser will report "The certificate cannot be trusted" since they are not certified trusted by a certification authority like Verisign. Free trusted certificates are provided by CAcert and StartSSL on registration
Step#2: Modify Tomcat server's default configuration
The value of environment variable CATALINA_HOME will be the Tomcat server installation directory. Edit  server.xml under $CATALINA_HOME/conf/ and make the below changes: 

<Connector port="8443" protocol="HTTP/1.1" SSLEnabled="true"
    maxThreads="150" scheme="https" secure="true"
    clientAuth="false" sslProtocol="TLS"
    keystoreFile="/root/my_workspace/server.keystore"              keystorePass="changeit"/>

You can also add attributes with values for truststoreFiletruststoreType, truststorePass, keyAlias to the above tag.

Step#3: Modify web service's axis configuration
My web service WAR file is myws.war. When I deploy this file by placing it under $CATALINA_HOME/webapps/ directory, and start the server, I find axis2.xml is under $CATALINA_HOME/wepapps/myws/WEB-INF/conf/ directory. Edit this file as per instructions below:
  1. Comment the existing default xml tag entry for http transportReceiver 
  2. Add two entries as shown here:
    <transportReceiver name="http" class= "org.apache.axis2.transport.http.AxisServletListener" 
       <parameter name="port">8080</parameter>

    </transportReceiver>
    <transportReceiver name="https" class= "org.apache.axis2.transport.http.AxisServletListener"
     
       <parameter name="port">8443</parameter>

    </transportReceiver>
    Note:
    • By default the port parameter is 8080 for transport receiver. If you want to have two transport receivers (e.g. http and https), then make sure to add ports in both tags as shown above

    • Without making changes to axis2.xml, if you try to access the web service using HTTPS, Internal Server Error is thrown in the browser. This is a common problem which me and many others faced. Arrgh!
  3. Restart Tomcat server
  4. Now my web service is accessible on URLs:
    https://<host-ip>:8443/myws/services/myService
    http://<host-ip>:8080/myws/services/myService
And there you go, everything is set. Let me know if you face anything unusual after following these steps.  So then, until next time, happy programming!

Further reading:
Apache Tomcat 7: SSL Configuration HOW-TO