Tuesday, November 27, 2012

Https Spring WSDL Tomcat

Just want to share my experience in my work.

At 4 on a Friday afternoon, we were waiting for the integration of our application to a company's premise server. But unknowingly, the design and architecture we've setup is not the same as the client's system admin is expecting. From http application, the client is requiring us to render it in https, on that same day. It's Friday, c'mon!

Good thing we've used Spring MVC and no configuration else is required for delivering it to https aside from some tweaks on out tomcat container in the cloud.

To avoid some of you, running into same scenario, of any troubles in the way, I'm listing down the things I've executed. So here's what I did.

1. Create keystore. The code below will create .keystore in your home directory.
  
$JAVA_HOME/bin/keytool -genkey -alias tomcat -keyalg RSA


   You will be prompted for password, default password used by tomcat is "changeit".

   Next, you will be prompted for Certificate information. AGoogleour server will be accessed outside of the cloud, in the First and Last Name, eg. CN="ec2-12-345-678-90.compute-1.amazonws .com"

    I didn't use the public domain name of our server before and it caused me trouble when accessing our wsdl file through Spring. Will discuss it later.

    You will be asked for the key password and you must use the same password as was used for the keystore password itself.

2. Using tomcat, edit server.xml and lookfor your JSSE Connector and edit it to look like:
  
<Connector port="443" protocol="org.apache.coyote.http11.Http11Protocol"
        SSLEnabled="true"
        keystoreFile="<home.base>/.keystore"
        keystorePass="changeit"
        maxThreads="150" scheme="https" secure="true"
        clientAuth="false" sslProtocol="TLS" />


   I've used port 443, rather of tomcat's default of 8443 for SSL, since it's the https default port. Change Connector port 80's redirectPort to "443" instead of default 8443.

3. Add this to your webapps' web.xml files you want to render in https:

    <security-constraint>
      <web-resource-collection>
            <web-resource-name>Automatic SSL Forward</web-resource-name>
           <url-pattern>/*</url-pattern>
      </web-resource-collection>
      <user-data-constraint>
        <transport-guarantee>CONFIDENTIAL</transport-guarantee>
      </user-data-constraint>
    </security-constraint>


4. Restart your tomcat. And you may now access your container applications through https://<domain>:443. If you access your applications using http://<domain>/, it will redirect you to https protocol.

If you're using Spring MVC, then everything should be alright, except when importing wsdl file from your newly setup https container. If your using this setup:

<bean id="classWebService" class="org.springframework.remoting.jaxws.
 JaxWsPortProxyFactoryBean">
    <property name="serviceInterface" value="com.service.ClassService" />
    <property name="wsdlDocumentUrl"
      value="https://ec2...compute-1.amazonaws.com/serv/service?wsdl" />
    <property name="namespaceUri" value="http://service.com/" />
    <property name="serviceName" value="ClassWebService" />
    <property name="portName" value="ClassWebServiceImplPort" />
</bean>


It may throw,

Caused by: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target

The problem thrown is because of the unregistered certificate on the consumer's machine. To solve the problem, try installing the certificate on consumer's keystore. Here's how:

1. Access the wsdl in http through your browser. Through the browser, download the certificate and save it as "certificate".
2. Add the downloaded certificate. Execute this command:

 sudo keytool -import -alias <domain name>
   -keystore <java-6-sun>/jre/lib/security/cacerts -file ~/certificate

*make sure that the the certificate CN="name" = "domain name" = the address right after the 'http://', else you'll be getting another exception saying that the certificate can't be found in you keystore.

*more on tomcat ssl configuration here.

No comments:

Post a Comment