SummaryBy Pankaj Kumar. Revision: 0.81, Date: Apr. 2, 2002.
This HOWTO guide explains steps involved in (i) deploying SSL accessible Java Web Services in Servlet based SOAP platforms such as Apache Axis or HP Web Services Platform ( HP-WSP ); and (ii) running Java client programs that access these Web Services with https protocol. The guide accompanies scripts and sources for a simple application consisting of a simple Web Service ( Hello World variety ) and a client to illustrate the setup steps.
This guide is for you if
Apache Axis is an opensource software and can be downloaded from http://xml.apache.org/axis. Evaluation copy of HP-WSP can be downloaded from http://www.hpmiddleware.com. This guide and the supplied example scripts and sources are based on Apache Axis Alpha3 and March 2002 release of HP-WSP.
A Servlet based SOAP platform is usually not aware of SSL. It is the Servlet container who takes care of all the encryption, decryption and verification stuff. In this respect, use of SSL is transparent to the SOAP platform or the Web Service. So, what is needed is the steps to setup the servlet container for SSL. In addition, the WSDL description of the Web Service must specify the appropriate URL to access the service.
This guide includes the steps for Apache Jakarta Tomcat 4.0.1 and HP-AS 8.0, a full-fledged J2EE AppServer free for commercial use. You can download HP-AS 8.0 from http://www.hpmiddleware.com. It is noteworthy that HP-AS 8.0 supports certificate based client authentication whereas my preliminary investigation on Tomcat 4.0.1 leads me to beleive that Tomcat doesn't support this capability. However, I don't track Tomcat development very closely and I could be wrong here. Let me know if I this is so.
Certain steps mentioned in this guide require the Java source files and scripts available in
the caompanion resource
Download WSOverSSL.zip and unzip it. This would create the directory with name
WSOverSSL and place the contents within this directory. As the scripts to compile, deploy
and run the client are SOAP Platform specific and there are minot differences in the client source
code as well, I have kept sources for Apache Axis and HP-WSP in separate sub-directories with names
I have written only Windows scripts to compile, deploy and run the examples only. Translation to Linux/Unix scripts are straightforward. A future revision of this document will use OS neutral Apache Jakarta Ant scripts. File and directory pathnames and environment variable used in this guide follow the Windows convention. Again, translation to Linux/Unix names are trivial.
JAVA_HOME is used in all the scripts for easy switch
among different JDKs, either from one or different vendors.
Rest of the guide is organised in following sections:
You can skip this if you using JDK1.4 or above as JSSE is now part of the JDK.
I tried the steps on my WIndows NT machine with Sun's JDK1.3. It sould work on other OS platforms and JDK1.2.x and 1.3.x with no or minor changes.
Note that you must have JSSE, either as part of JDK1.4 or separately installed, to be able to setup Apache Jakarta TomCat or HP-AS 8.0 for SSL. It is also needed for running the client program.
%JAVA_HOME%\jre\lib\extdirectory and editing the
%JAVA_HOME%\jre\lib\security\java.securityfile to add the following line:
%JAVA_HOME%\lib\ext, but that didn't work for me. Later on, I figured that Sun's documentation for JSSE uses
JAVA_HOMEto point to
jresub-directory of JDK installation directory whereas I have used JAVA_HOME to point to JDK Installation directory itself.
hpwspand edit the script
testhttps.batfor your environment. This script invokes the
URLReaderprogram ( part of the download ) to access url
https://www.etrade.comwith proper options to the JVM. If you are behind a corporate firewall, you should edit the script file to use appropriate values for System properties
https.proxyPort. Following worked fine for me:
%java_home%\bin\java -Dhttps.proxyHost=web-proxy -Dhttps.proxyPort=8088 \ -Djava.protocol.handler.pkgs=com.sun.net.ssl.internal.www.protocol \ URLReader https://www.etrade.com
Note that character
\ is used to indicate line continuation and must not appear in
the actual command.
Pay attention to these System properties and understand their significance. A proper understanding now will save you a lot of grief later on.
If the script
testhttps.bat doesn't work, recheck the steps in Installing JSSE. If
you are not using environment variable
%JAVA_HOME%, you may want to verify that the
right JVM ( the one whose
jre\lib sub-directory has been updated ) is being used.
One way to do this is to display System property
java.ext.dirs. This should have
%JAVA_HOME%\jre\lib\ext as a component.
CLASSPATH. Also, you could add the SSL Provider to the
java.lang.Securityclass within your program and not specify in the commandline. Refer to JSSE documentation for more details.
Generate Certificates and KeyStores
In this section, we will use the
keytool utility of JDK to generate keys,
certificates, keystores and truststores. Though you don't need to
understand the underlying concepts for
setting up your system for this example, but if you run into problems or want to modify the setup for
your own specific needs, I would advise going through the references at the end of this guide or any
other source to understand the functioning of
keytool utility and its relationship
to certificates, public and private keys, keystores, truststores and other such topics.
Take a look at the script file
if not "%JAVA_HOME%" == "" goto gotJavaHome echo You must set JAVA_HOME to point at your Java Development Kit installation goto cleanup :gotJavaHome echo Generating the Server KeyStore in file server.keystore %java_home%\bin\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 %java_home%\bin\keytool -export -alias tomcat-sv -storepass changeit \ -file server.cer -keystore server.keystore echo Generating the Client KeyStore in file client.keystore %java_home%\bin\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 %java_home%\bin\keytool -export -alias tomcat-cl -storepass changeit \ -file client.cer -keystore client.keystore echo Importing Client's certificate into Server's keystore %java_home%\bin\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 %java_home%\bin\keytool -import -v -trustcacerts -alias tomcat -file \ client.cer -keystore server.keystore -keypass changeit -storepass changeit :cleanup
Note that the character
\ is used to indicate continuation of the same line. You won't
find this in the actual script file.
As the comments indicate, this script creates a self signed cerficate for the server and the client
and stores them in keystores
respectively. Also, the server's certificate is exported to file
imported to client's keystore
client.keystore. Similarly, the client's
certificate is exported to file
client.cer and imported to
server.keystore. This way, keystore
can also be used by the client as the truststore to verify the cetificate supplied by the server
With respect to the script
genks.bat, it is important to note that:
localhost. If you plan to access the server with its symbolic name or IP address on the network, you must specify that string while generating the key. You can also have multiple certificates for the same physical machine.
Note that in a typical use of SSL to access a web application, the client authenticates the server
based on the certificate presented but the server rarely authenticates the client based on certificate.
That is how we use https protocol from our browsers most of the time. This works fine as there are
other mechanisms to identify and authenticate the client such as username and password, credit card
no. and the billing address and so on. However, these mechansims will not be availalble to a Web
Services client and hence it makes sense to use certificate based client authentication.
Configure Servlet Container for SSL
Configure Tomcat 4.0.x for SSL
This configuration is really simple. Edit the %TOMCAT_HOME%\conf\server.xml file and uncomment the entry for SSL connector. Also add the attributes for keystore filename and password. Find below the edited entry for my setup:
<!-- Define an SSL HTTP/1.1 Connector on port 8443 --> <Connector className="org.apache.catalina.connector.http.HttpConnector" port="8443" minProcessors="5" maxProcessors="75" enableLookups="true" acceptCount="10" debug="0" scheme="https" secure="true"< <Factory className="org.apache.catalina.net.SSLServerSocketFactory" keystoreFile="c:\progs\java\WSOverSSL\hpwsp\server.keystore" keystorePass="changeit" clientAuth="false" protocol="TLS"/< </Connector>
The bold lines are specific to my setup. You may need to change these values for your setup.
To test the new configuration, restart the container and access the URL
https://localhost:8443 from your browser. It might warn you that the
certificate presented by the server is not recognised. We did not get our certificates signed
by a well-known CA, did we? However, keep pressing 'Yes'
to the questions and eventually you should see the welcome page for Tomcat.
Tomcat 4.0.1 doesn't seem to support client authentication. I did not find any attribute of
Factory to specify the truststore and its password. A truststore is needed to
verify the certificate presented by a client. As I have the client's certificate exported to the same
keystore file, I tried just setting the attribute
this didn't work.
However, you can supply the truststore and its password as System properties to the JVM running the Tomcat and that would enable client authentication. Though I did not try this myself, a couple of folks have pointed to me that it does work.
We will see in the next section that HP-AS 8.0 supports specification of truststores and SSL
based client authentication.
Configure HP-AS 8.0 for SSL
This section assumes that you have HP-AS 8.0 installed in directory
you have selected default options while installing HP-AS, its value should be
If you don't have HP-AS 8.0, you can get it from
%HPAS_HOME%\config\hpasand copy file
https-service-config.xml. Now edit this file to reflect your setup. Find below the edited file for my setup:
<listener-service ports="9443" backlog="50" max-request-handlers="20" max-request-contexts="20" max-response-contexts="20" request-handler= "com.hp.mwlabs.as.services.listeners.https.HttpsRequestHandler" container="servlet" socket-timeout="PT0S" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation= "http://www.hp.bluestone.com/xml/schemas/listener-service-2_0.xsd"> <server-socket-factory class-name="com.hp.mwlabs.as.services.listeners.JsseSslServerSocketFactory"> <property name="remoteTrustAlgorithm" value="SunX509"/> <property name="keyStorePassword" value="changeit"/> <property name="protocolVersion" value="TLS"/> <property name="keyStoreFile" value="file:///c:/progs/java/WSOverSSL/hpwsp/server.keystore"/> <property name="enableSessionCreation" value="true"/> <!-- rarely will this be false --> <property name="keyType" value="SunX509"/> <property name="keyStoreType" value="JKS"/> <property name="keyPass" value="changeit"/> <property name="requireClientAuth" value="true"/> <property name="useKeyStorePassAsKeyPass" value="false"/> <property name="trustStoreFile" value="file:///c:/progs/java/WSOverSSL/hpwsp/server.keystore"/> <property name="trustStorePassword" value="changeit"/> </server-socket-factory> </listener-service>Lines that changed are in bold. Note that this configuration file requires that the clients also present certificates. Also, in my installation of HP-AS, the original file
https-service-config-example.xmlhad XML comments at the end of the file. Delete these lines. I had to go through tech. support to get this right.
hpas-deploy.xmlto add an entry for HTTPS listener. I added this entry just after the entry for HTTP listener:
<Service name="https" class="com.hp.mwlabs.as.services.listeners.ListenerService"> <Configuration url="https-service-config.xml" reload="30"/> </Service>Note that this entry is very similar to the entry for HTTP.
http://localhost:9443. It should take you the HPAS 8.0 start page.
Running the Example Program
The supplied example demonstrates the use of HTTP over SSL ( or https ) for communication between two Web Service end points. Use of https protects the content exchanged and can also be used by one end point to authenticate the other.
The example consists of a simple Java class
Hello with method
String greet(String anme) and a client class
Hello is deployed as a Web Service and the client invokes the method
greet() with the string specified in the command line parameter.
Instructions to run the example program and troubleshooting tips can be found in readme.html file
stored with example
sources and scripts, in sub-directory
axis for Apache Axis example and in sub-directory
hpwsp for HP-WSP.
Here are some generic troubleshooting tips.
setHPWSEnv.batfile for values reflecting your setup. Check and recheck the spelling of values. Once you have identified the problem, look at the appropriate resource for troubleshooting tips.
Look at the platform specific readme.html for more specific troubleshooting tips.
I have observed following problems during my experimentation. These may be specific to the version of the software I am using.
https.proxyPort. The exact error message I got was:
Unable to tunnel through web-proxy:8088. Proxy returns "HTTP/1.0 503 Service Unavailable. Utility
Wsdl2javaretrieved the WSDL file correctly from https url outside the corporate firewall but the client program failed. This is possible as
Wsdl2javauses the JDK classes to access the URL whereas Axis has its own implementation of HTTP over TCP/IP.
BindException: Address in use: connect. I have never encountered this over HTTP. Also, I didn't observe this on my slower 350MHz Pentium machine, but can reproduce very quickly on faster 900MHz Athlon machine.
Copyright © 2002, Hewlett-Packard Co.