Monday, February 11, 2008

HTTPS Connection in Java

Every time I had to create a java client to access a page using a https connection, I come across some issue and I keep googling for the answer. So this time I decided to document this so it will be useful for me the next time. There are few steps that we need to follow to make a https connection in java.

1) Create a trust storeTo create a https client you need to provide the trust store with the certificate of the host you are connecting. The trust store is a file where a list of trusted certificates are stored. Thie file need to be created or the certificate of your host need to be manually added to the trust store. I believe there is a way to automatically extract this from the url and dynamically add a handler. (I say this because JMeter does not require you to do this step) This is an isssue when you are connecting to servers in your development environment or servers, whoose certificate is not signed by a valid signing authority.

So, to create the truststore, you need a certificate. You can create a certificate by pointing your browser to the host and use your browser to extract the certificate file. Here are the steps to extract the certificate using IE. Point your browser to the site. When the browser shows the padlock, doubleclick the padlock and bringup the popup window. Go to the details tab and select the options to copy the certificate to a file.Now, use the keytool that is part of the jdk to create a store file.

In the above command, testkeys is the name of the truststore file to be created/edited, mycert.cer is the name of the certificate file created by the browser.

If you prefer to install the certificate using a java program you can follow the instructionsfrom Andreas Sterbenz's Blog.

2) Make truststore available to jvmOnce you have created the truststore file, your code to make normal URL connection should work even for the ssl connection. The only change you need to do is add a JVM argument to the command line. java -Djavax.net.ssl.trustStore="\testkeys" If you dont want to add the extra parameter you can update the default trust store found under /lib/security/cacerts file using the above procedure. I suggest that you backup the file before you do anything with the file.

3) Make URL connection as usualHere is a sample snippet for making a url request.

4) Create host verifier if your host name does not match with certificate

If your certificate issuing name does not match with the hostname you are connecting to, you may run in to another error. Thie can be solved by adding your own hostverifier to your code. Adding the following snippet will accept any host. Use this with caution in a production environment and allow only known mappings.

The next challenge you may run in to is if the site you are visiting is protected by username/password. You need to add an authenticator. The easiest way to do this is to add a default authenticator.The following is an example of a simple authenticator:

Ben, The approach will work for web pages that uses basic authentication. Typically you can identify those pages when you visit the page and you get the browser's popup window prompt for authentication.

The site you mentioned appears to be using forms based authentication. If you are trying to screen scrape such web pages, you will have to pass in the credentials to the page using the same parameter names used by the login form.

Hi Jean. Cheers for the initial post.I pass the email and password with the same parameter names as the form. However it recognises bad credentials (returns HTML code with error) but for good credentials it accepts them but just returns information the same HTML code for the login page.