Overview
One of the biggest headaches I have to deal with are web services with self signed SSL certificates for web services. This is a common issue for applications in development because development and preview environments rarely have properly signed certificates. So in order to debug and develop you have to get around this.
Get the Certificate
Perhaps this is the lazy way of getting a certificate for a self signed web service but it does work and it's fairly easy. You simply use your browser (Chrome or Firefox).
- Navigate to your WSDL
- Click the lock icon in the navigation bar to the left of the URL
- If you're using Chrome (See the screen shot below for an example):
- Click the Connection Tab
- Click the Certificate Information
- Click Details
- Click Export
- If you're using Firefox:
- Click More Information
- Click View Certificate
- Click Details
- Click Export
- Select a location you can easily access and click Save
Exporting a SSL certificate in Chrome |
Add the certificate to your Keystore
- Open a terminal and navigate to where you saved the certificate and execute the following command:
- keytool -import -trustcacerts -alias myAlias -file mycert.ca --keystore mykeystore.jks. There are several things to note here:
- -trustcacerts will probably not help but its a nice to have. Basically if the root certificate is already in your cacerts file located at jdk/jre/lib/security/cacerts you wont be pestered about accepting this certificate via a yes/no prompt.
- -alias this is a unique name that identifies the certificate. Usually the domain name the certificate belongs to is a good choice here.
- -file this is the certificate file you downloaded via your browser
- --keystore (optional) this is the keystore you're going to store the certificate in. If it doesn't already exist it will be created. If this option is left out the user's keystore will be used.
- You will be prompted for the keystore password. By default this is changeit if you left the --keystore option off. If you're creating a new keystore this will be its password.
- If asked about importing the certificate type "yes" and hit enter.
Using a non-default keystore in Java
This is done by including 3 JVM options when running your java application:
- Dsun.security.ssl.allowUnsafeRenegotiation=true
- Djavax.net.ssl.trustStore=/path/to/your/keystore
- Djavax.net.ssl.trustStorePassword=changeit
For example executing an application with a custom keystore would look like this:
java -Dsun.security.ssl.allowUnsafeRenegotiation=true -Djavax.net.ssl.trustStore=/home/bradley/liferay-preview-keystore -Djavax.net.ssl.trustStorePassword=changeit -jar myapp.jar
A Trick When Working with Multiple Environments
Since it's better to develop and debug with an environment that mimics your preview and production environments I've taken to copying the java keystore in our preview environments, which is managed by our middle ware team and/or application admins, to my local machine and have my local environments/applications use it instead of importing certificates manually. This file is located at <JDK>/jre/lib/security/cacerts (In my case the full path is: /usr/lib/jvm/java-7-oracle/jre/lib/security/cacerts). What this accomplishes is guaranteeing that my environment has the same certificates as our preview instance. Couple this with setting up an SSH tunnel to our preview instance for the application running locally and development and migration between dev and preview environments for applications that consume a web service becomes trivial.
A Tool For Working with Web Services
A critical tool for debugging and setting up a web service/client is SoapUI. This application allows you to load a WSDL, either remotely or locally, and it will generate a SOAP envelope that you can use to query the web service. The results of the query are then returned and displayed in SoapUI.
A word of caution: I've had a lot of trouble getting SoapUI to use keystores I've set up via the GUI. If you're running into this problem you can use the instructions in the "Using a non-default keystore in Java" section and add the JVM options to SoapUI/bin/soapui.sh. Once I did this my SSL certificates were recognized (even though the exact same keystore was set up in SoapUI's preferences and my project) and everything worked perfectly.