|
|
 |
Integrating Apache SOAP with an EJB Server
By Billy Newport, EJB Consultant.
Part 1 |
Part 2 |
Part 3 |
Part 4
We're going to enable SSL and check that our SOAP client can connect using HTTP/SSL and
basic authentication with our server. No certificates on the client yet.
I'm using IBM HTTP Server 1.3.12. If you're using a different HTTP server then please follow the instructions
that came with your server. Setting up SSL with IHS is actually very easy. Before, we get in to setting
up SSL, I'm going to provide a quick introduction to how SSL works. If you know this already then just skip
the next section.
It's important to realize that while I talk about WebSphere and Visual Age a lot here, the parts of this
series related to the client (i.e. most of it!) applies equally to every and any EJB server on the market.
SOAP over HTTP or HTTP/SSL will work with any SOAP server.
Introduction to SSL.
SSL is basically used to provide an encrypted socket. It can also provide server authentication and optionally
client authentication. The server always has a RSA certificate. When a client opens an SSL connection
to the server, the server accepts the connection and provides the client with its certificate. The client then
checks that it trusts the server certificate. The client has a list of trusted certificates and a list of trusted
root certificate authorities. It trusts the certificate if it is a trusted certificate or if the server certificate
was signed by an authority it trusts. We can also optionally have a certificate at the client side. If we
have then the client also sends its certificate to the server. So, we have a certificate exchange. The client
verifies the server certificate as before and the server now does the same with the client certificate. If both
sides trust each others certificate then the connection is ok.
If WebSphere is on the server side then authentication can work two ways. First, SSL is simply used for encryption. Here
the client still must authenticate to the server using basic authentication. This is the way the majority of e-commerce
sites work. This is still good as normally (i.e. using HTTP) the client password is transmitted over a clear
connection, i.e. no encryption. This is obviously bad. When we use HTTP/SSL then all communication between the
client and the server is encrypted thus protecting our password and subsequent data from prying eyes. The other way
WebSphere can handle authentication is using certificates. If the client sends its certificate to the server then the
common name of the certificate can be mapped to a WebSphere id. If it can be mapped to a WebSphere id then WebSphere
authenticates the client. The client can then work using the WebSphere identity.
We will first do HTTPS + basic authentication and then we'll do certificate authentication. But, before we do anything,
we need to setup Apache and WebSphere to accept SSL connections.
Setting up Apache with SSL
First, we need a certificate for our web server. You can get one from Verisign or you can make a self
signed certificate. If you're making a production site then you need to use Verisign as otherwise
no-ones browser will accept your certificate as it is not signed by someone they trust.
I made a self signed certificate for these tests.
The IBM HTTP Server (IHS) comes with a key management utility (keyman). You
can launch this using the start menu. Click Start/Programs/IBM HTTP Server/Start Key Management Utility.
This application lets you manage your keys. The certificates are kept in a key ring file. This is a password
protected file where your certificates are kept. IHS needs this file and its associated password
to load the certificate used to secure your web site. This utility lets you create or import certificates
in to a key ring file and then store its associated password in a stash file. A stash file
stores the key ring file password in an obfuscated form but it is not strongly encrypted. The password is used
by Apache to decrypt the keyfile so that it can retrieve the private key part of the certificate the web server
will use. Here are the steps to create a keyfile, make a certificate and stash the password.
- Start the keyman utility.
- Make a new key file.
The type is a CMS file and put it in the same directory as apache is installed. Enter a password,
it should contain upper and lower case letters, digits and a symbol. Check the stash checkbox to indicate
that you want the password stashed and don't set an
expiration time. If you do set an expiration time then you must change and restash the password before it expires. You'll need
to restart apache when you change the password.
- Make a certificate for your site.
You should now see a list of signer certificates. Click on the signer button and change
it to Personal Certificates. This list should be empty. Click the New Self-signed button. A dialog appears. Enter a
key label (any text is fine). Make sure the version is PK509V3, key size is 1024. Make the common name the host name of your
site. Enter an organization name. You can also change the validity time of the certificate, I left mine at 365.
It will expire and be useless after this period. Click the OK button.
Thats it. You have a site certificate. It should have a '*' beside it. This means it is the default. Apache will use the default
certificate for its site certificate. You can also name a specific certificate when we configure apache later but leave it as the
default now. Now, we need to export the key as a PKCS12 file. Select your certificate and click the EXPORT button. A new
dialog appears. Make
sure export is checked, PKCS12 is selected and enter a file name. Remember this file name as we need it later to setup the
client. Click OK. It then asks whether to use weak or strong encryption. I used weak.
Now, we have a certificate in a key file. We need to enable SSL on Apache. Start Apache and open a browser for your URL. Click the
view documentation (I'm assuming you're still using the default IBM pages that came with it). Click on How To and then
click set up password protection. Now, on the right you should see a set up secure connections. Click this
and print out the page that appears. This page contains exactly what you need to do to enable Apache/SSL. I followed this to
the letter and it worked almost. I suggest you do the same. During this process you need to enter the location of the key file.
Enter the location of the key file we made previously. The instructions basically tell you to use the
http admin server (not the WAS admin console) to do the configuration. You need to make sure that it is started (its the IBM HTTP Admin server in your control
panel/services list). You also need a password. You set this using the htpasswd utility that is in your apache
directory. When you enter the default page for apache, click on configure server. It then prompts you for a password. Click
cancel and it then displays the instructions for specifying a password. Do this on the command line and then try to configure
the server again. Now follow the instructions you just printed out and then restart everything (IHS + Admin server).
Once, I'd done this then my apache server wouldn't start. The problem was that the admin utility had inserted
a ClearModuleList directive and had LoadModule ibm_mod_ssl twice in the httpd.conf file (this is in the conf directory of
your apache installation). I removed the clear module list and the extra LoadModule
and all was well. Apache should now start on the command line and display no error messages. The problem I saw were things like:
- No password for keyfile
I forgot to stash the password using the keyman utility.
- No keyfile
I forgot to enter the keyfile location in the admin utility. Follow the instructions exactly.
OK, so you've restarted Apache and now all should be well. When I did this I could no longer connect to my HTTP server using
just HTTP, I had to use HTTPS all the time. It should be possible to have both HTTP and HTTPS connections but I did not pursue
this further. If you enter the url 'HTTPS://hostname' you should see the same apache default page as before. Your
browser probably complained that the certificate wasn't trusted. You can override this to force it to
accept the certificate using a button on the dialog it pops up. We will now import the certificate in to the browser (I'm using IE 5) so that the browser accepts
the certificate by default.
Start IE. Open the Tools/Options menu. Click on the content tab. Click on the certificates button. Click on the import button. Remember,
we exported the certificate using the keyman utility. Enter the location of this file. Accept all the default choices on the subsequent
panels and when it's done, IE will now accept your certificate as trusted.
Configure WebSphere for SSL.
This is actually very easy. Start the admin console. Right click on the default_host and click properties. For every host in the
alias, add a new one with the same host name but with a :443 following it. For example, if you see 127.0.0.1, then add
a new one called 127.0.0.1:443. Do this for all the hosts in the alias list. This redirects SSL requests to WAS now also. Thats it. You now need to restart
the admin server (thats server, not client!) Do this and when WAS restarts, we should be in business.
Start the default server (to get the samples) and enter the following URL in your browser:
https://host/webapp/examples/ping
You should see ping just fine. If not then retrace all the above steps and make sure you did everything as described. I have done
this and it worked without any trouble except for the problems I mentioned above. Now start the server containing our SOAP
server. Try invoking the page. I enter the URL:
https://p300/soap/soap/index.html
in my browser. Click on the dispatcher link and you should get prompted for a password. If this happens then everything is
fine on the server side. All is working perfectly. Don't touch anything else on the server from this point on!
Making our client work with SSL
Remember, we obtained JSSE 1.02 from Sun in part 2. This has the magic when combined with HTTPClient to enable SSL. It's a little
troublesome to get working how-ever but having gone through the pain, here's how to do it. First, get the 1.3 JDK from
Sun. We need the keytool utility from the JDK. I could not get the one with 1.2 to work at all. The 1.3 one works
as described in the instructions for 1.2, go figure. Anyway, download and install 1.3. The keytool utility is contained
in the bin directory and must be used from the command line.
Configuring JSSE with our server certificate.
OK, remember I said before that the client verifies the web servers certificate when the SSL connection is started. The JSSE
stuff does this too. If you bought a Verisign certificate then you can ignore the following section. JSSE should recognise
your certificate with no extra work. For the rest of us, the following section will save you a lot of grief. JSSE had a trusted
certificate store. This is of course a different file format from the one we made using keyman with Apache. It also doesn't
understand the certificate we exported from keyman that IE understands perfectly. It will complain that it is not a 509
certificate when you try to import the PKCS12 file. We have already
imported this PKCS12 file in to IE. We will now export it from IE using
a file format JSSE understands.
Again, start IE, goto Tools/Options. Click the Content tab and again click the certificates button. Now, click the Trusted Root
Certification tab. Scroll down until you see your sites certificate. Click it and then click the export button. Follow the
resulting dialog through and export the certificate as a DER encoded binary .CER file. Remember where you exported the file
to. It's ok if you don't export the private key. JSSE needs only the public key.
Start VAJ. Now, add some properties to the GetAddress client. Right click on the GetAddress class in the SOAP Samples
project and in the properties edit box, add the following text:
javax.net.debug=ssl,handshake,data,trustmanager
java.protocol.handler.pkgs=HTTPClient
The first line switchs on trace for JSSE. The second tells the JDK to use HTTPClient as the default HTTP handler an enables
HTTPS, if you don't add the protocol property then you'll get a malformed URL exception when you
run the client. Now, add
the following line to the main of this class at the top.
java.security.Security.addProvider(
new com.sun.net.ssl.internal.ssl.Provider());
This adds the JSSE security provider to the JDK security runtime. If you don't do this then you'll see a 'No SSL Provider'
exception when you run the client. The Source for Address Client
can also be downloaded. You can use this to check the changes you made to it so far. It incorporates all the
changes needed for this article and is exactly what I tested when writing this up.
Now change the command line parameters to something like this:
https://p300/soap/soap/servlet/rpcrouter "Bob Q. Public"
The HTTP Transport class I gave in part 2 had a bug in it
that I noticed doing the SSL. Please download it again and import it
to VAJ again by clicking the previous link. Change the addAuthorizationInfo line also to use the 443 port instead of 80.
SSL uses this port. Now, run the client. You should see a lot of trace on the console. It will fail and you should
see an exception like 'Peer not authenticated'. This is fine. This happened because JSSE doesn't trust our sites certificate
yet. Scroll to the top of the console output. You should see a line like this:
trustStore is: C:\ibmvjava\ide\program\lib\security\cacerts
This is the certificate file that JSSE is using to store certificates that it trusts. We will now use the JDK 1.3 keytool
utility to import our sites certificate to this file. Enter the following command line:
c:\jdk\1.3\bin\keytool -import -alias ejbinfo -file d:\ejbinfo.cer
-keystore c:\ibmvjava\ide\program\lib\security\cacerts -keypass changeit
I exported from IE my certificate to the file d:\ejbinfo.cer. Change this to your certificate file. Again change the cacerts
file to the one you see in your trace. The keypass is the default password for the keystore file. This is changeit. Change
the alias ejbinfo to some else too if you want. It should ask you whether to trust the certificate or not. Answer yes.
Now, JSSE will trust our site. Run the client again and this time it should work. If it doesn't work then check you
can still access the rpcrouter servlet using a browser, if you didn't touch anything on the server side this should still work.
Now, repeat the steps for configuring JSSE and look at the trace for hints. If it will doesn't work then just go back to the beginning
and verify all the previous steps.
Conclusion
Congrats if all is well. You now have a SSL enabled SOAP client using basic authentication against a WebSphere app server. This
client should work in applets and through proxy servers. The fact that our HTTP transport uses the HTTP keep alive feature is a
big performance gain with SSL. Creating an SSL socket is an expensive operation. Our new transport reuses the socked and thereby
gives us a lot of performance.
The next article will look at certificate authentication instead of the basic authentication we've used up to now. The article
following that wraps up the series and shows how to write a SOAP bridge to session beans instead of the samples we've
been using so far.
|