Thursday, June 17, 2010

Which style of WSDL should I use?

A Web Services Description Language (WSDL) binding style can be RPC or document. The use can be encoded or literal. How do you determine which combination of style and use to use? The author describes the WSDL and SOAP messages for each combination to help you decide.

Which style of WSDL should I use?

Saturday, October 31, 2009

Java 5 EOSL

Java 5 has reached End Of Life. Most of the bigger organization in the service industry are still using Java 1.4 and are not willing to migrate as they anticipate migration issues and feel that its a risk and unjustifiable. Java 6 has been out for a long and its time to take advantage of the new features, especially the web services stack (JAX-WS). There are lot of performance improvements which might be one reason to migrate.

On a personal note migration is little to do with technical, but more often political.

http://java.sun.com/products/archive/eol.policy.html

Thursday, September 17, 2009

File Download issue with IE over HTTPS

I am currently working on a project where the user can download PDF, XLS and CSV files. These files are dynamically generated within the application and thrown out on the browser when the user clicks on a particular link. This was running like a charm till recently, we decided to move to HTTPS and it stopped working. We were getting a message saying

"The file could not be stored in cache."
"Internet Explorer was unable to open this site. The requested site is either unavailable or cannot be found. Please try again later."


After a little googling I found that it is a known issue with IE. Refer to the link below. http://support.microsoft.com/kb/815313 But installing a hotfix was out of question. So I went looking for a solution that could be handled through code and here is the solution that seems to work for us and the magic required to satisfy IE
response.setHeader("Pragma", "public");
response.setHeader("Cache-Control", "max-age=0");

Wednesday, August 12, 2009

Two way SSL on Tomcat & JBoss

Continued from the previous post where I had put in steps to setup one way SSL. In this post i shall provide steps to enable client certificate authorization. Hence here we will see a situation where the client verifies the server cert and server verifies the client cert for validity and trust before a successful SSL handshake. The initial steps shall be the same as mentioned in my previous post and with an assumption that your one way SSL is already working. Now to enable the client authorization, we need to modify the server.xml as below:
<Connector 
  port="8443" minSpareThreads="5" maxSpareThreads="75" enableLookups="true"
  disableUploadTimeout="true" acceptCount="100" maxThreads="200" scheme="https" 
  secure="true" SSLEnabled="true" keystoreFile="c:/certs/test_store" keystorePass="password" 
  clientAuth="true" truststoreFile="c:/certs/test_store" 
  truststorePass="password" sslProtocol="TLS"/>
Export a certificate from the client keystore (client_store in this example) and import it into the server's truststore (test_store in this example). In real world you probably would not import each client cert but a CA root cert and then sign each client cert with that one. The above mentioned way is only for testing purposes and get the feel of the process. Launch the server. No modifications are needed in the code on the client side. You can launch the client using:
c:\>java -Djavax.net.ssl.trustStore=c:/certs/client_store -Djavax.net.ssl.trustStorePassword=password -Djavax.net.ssl.keyStore=c:/certs/client_store -Djavax.net.ssl.keyStorePassword=password HelloWorld
Additional Tips: 1)In order to get detailed debug statements for the SSL handshake between the server and the client you can use the vm argument -Djavax.net.debug=ssl,handshake on either side. 2)If you want to be able to access the site using your browser then you will have to have the client certificate in the Internet Options > Content > Certificates > Personal section. For this you will have to be using a PKCS12 keystore instead of a standard JKS keystore. Hence instead use the following steps to generate the keystore on the client side:
keytool -genkey -v -alias clientKey -keyalg RSA -storetype PKCS12 -keystore client.p12
The keypass and storepass needs to be the same. Like in the steps for client using JKS, even here you can use a similar command to export the cert
keytool -export -alias clientKey -keystore client.p12 -storetype PKCS12 -rfc -file client.cer
Rest instructions like importing this cert into server's keystore continue to be same. One important point to note is that since the server's cert cannot be imported into PKCS12 keystore on client side, you have to import it into a JKS truststore and the commandline to launch the program needs to be modified as:
c:\>java -Djavax.net.debug=ssl,handshake -Djavax.net.ssl.keyStoreType=PKCS12
-Djavax.net.ssl.keyStore=c:/certs/client.p12 -Djavax.net.ssl.keyStorePassword=password
-Djavax.net.ssl.trustStore=c:/certs/cacerts -Djavax.net.ssl.trustStorePassword=password HelloWorld
In this case, the server's certificate has been imported into the cacerts truststore of type JKS. The PKCS12 keystore can be imported into the internet explorer at the above mentioned path. Now if you hit the URL using https, you shall be displayed a dialog box to select the cert you want to use for client authorization. Once you select it, the handshake process continues. Through out the example we have been making hits to a servlet (https://personal-PC:8443/SampleWebApp/HelloWorld). We can get the details of the client cert used to access this URL from an attribute in the request object.
X509Certificate certs[] = (X509Certificate[])request.getAttribute("javax.servlet.request.X509Certificate");
for (X509Certificate cert : certs) {
out.println(cert.getIssuerDN());
}

Tuesday, August 4, 2009

SSL on Tomcat, JBoss and command line client (continued)

I finished my previous post with the ending lines as So if you had used domain name in the cert CN, then use domain name or if it is machine name then use the machine name ; and if you don't do so you shall see error messages similiar to HTTPS hostname wrong: should be <personal-pc> where you had given your ip or localhost as the CN name while creating the keystore whereas referring the machine by its name (personal-pc in this case). If you go by the rules mentioned in previous post, it shall work i.e. using the same name in the URL to refer the machine you used as CN. What if you still want to be able to work with the different name (not the one similiar to the CN) or you want to use the IP in the URL when accessing the site? Well there is also a provision for this. You can write your own code to decide what needs to be done in such a situation by implementing the HostnameVerifier interface.
URL url = new URL("https://personal-PC:8443/SampleWebApp/HelloWorld");
URLConnection connection = url.openConnection();

if (connection instanceof HttpsURLConnection) {
    ((HttpsURLConnection) connection).setHostnameVerifier(new HostnameVerifier() {

        public boolean verify(String hostname, SSLSession session) {
           //TODO: Logic controlling the verfication.
           return true;
        }
    });
}

BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
//Rest of the IO code.
In the code above, I am just returning true for what ever comes in as host name, you shall write your logic here to handle the situation the way you like. With the above code in place, you will be able to use all valid names to refer your machine in the URL including computer name and localhost/127.0.0.1 (only for testing purposes).