Monthly Archives: December 2012

Enabling CLIENT-CERT based authorization on Tomcat – Part 2

In continuation of my earlier blogs Enabling CLIENT-CERT based authorization on Tomcat and Enabling SSL in Tomcat, in this blog I will demonstrate, how you can configure multiple application to control access to their web resources using CLIENT-CERT mechanism. Please read both the above blogs, before reading further.

There are 2 tomcat web applications in the code base in GitHub called “client1” and “client2”, if you go to web.xml of client1 it looks as below,

<security-constraint>
<web-resource-collection>
<web-resource-name>Demo App</web-resource-name>
<url-pattern>/secure/*</url-pattern>
<http-method>GET</http-method>
</web-resource-collection>
<auth-constraint>
<role-name>secureconn</role-name>
</auth-constraint>
</security-constraint>

<login-config>
<auth-method>CLIENT-CERT</auth-method>
<realm-name>Demo App</realm-name>
</login-config>

<security-role>
<role-name>secureconn</role-name>
</security-role>

If you notice, there is a web resource called “/secure” it will be only accessed by a user with role “secureconn”. And in “client2” web.xml you have,

<security-constraint>
<web-resource-collection>
<web-resource-name>Demo App</web-resource-name>
<url-pattern>/secure/*</url-pattern>
</web-resource-collection>
<auth-constraint>
<role-name>secureconn1</role-name>
</auth-constraint>
</security-constraint>

Again, if you notice in client2, there is a web resource called “/secure” it will be only accessed by a user with role “secureconn1”.

In a typical enterprise, you will use a LDAPRealm and users with secureconn role can access client1 web resource and users with secureconn1 role can access client2 web resource. But in this demo we will use MemoryRealm and configure tomcat-users.xml with these users and roles as below,

<role rolename="secureconn"/>
<user username="CN=client1, OU=Application Development, O=GoSmarter, L=Bangalore, ST=KA, C=IN" password="null"  roles="secureconn"/>
<role rolename="secureconn1"/>
<user username="CN=client2, OU=Application Development, O=GoSmarter, L=Bangalore, ST=KA, C=IN" password="null"  roles="secureconn1"/>

I hope this blog helped you.

Advertisements

Enabling CLIENT-CERT based authorization on Tomcat

In continuation with my earlier Blog Enabling SSL on Tomcat, in this blog I will go to next step and enable CLIENT-CERT based authorization on Tomcat. Again if you want to tryout the code go to my Github and download the code.

For this sample, I assume that you have tried my earlier SSL example on Tomcat and have the setup. As per the SSL example I assume,

  • You have setup Tomcat 6.0 version
  • You have set the SSL Connector Configuration in Tomcat server.xml
  • You have started the Tomcat server and run the SecureHttpClient0Test test

In this blog, I will show you how to,

Setup MemoryRealm

In the server.xml comment the Realm tag and replace that with the code below,

<Realm className="org.apache.catalina.realm.MemoryRealm" />

Setup user role setup

In <tomcat home>/conf/tomcat-users.xml

<role rolename="secureconn"/>
<user username="CN=client1, OU=Application Development, O=GoSmarter, L=Bangalore, ST=KA, C=IN" password="null"  roles="secureconn"/>

Setup security-contraint

Add access control in the individual application web.xml as below,

<security-constraint>
<web-resource-collection>
<web-resource-name>Demo App</web-resource-name>
<url-pattern>/secure/*</url-pattern>
<http-method>GET</http-method>
</web-resource-collection>
<auth-constraint>
<role-name>secureconn</role-name>
</auth-constraint>
</security-constraint>
<login-config>
<auth-method>CLIENT-CERT</auth-method>
<realm-name>Demo App</realm-name>
</login-config>
<security-role>
<role-name>secureconn</role-name>
</security-role>

Run JUnit test

Open the class src/test/java/com/goSmarter/test/SecureHttpClient1Test.java file and change the below code to point to <tomcat home>/conf folder

public static final String path = "D:/apache-tomcat-6.0.36/conf/";

Start the Tomcat and run the JUnit test using “mvn test -Dtest=”com.goSmarter.test.SecureHttpClient1Test”

If you want to debug the Realm, you need to increase the log level for Realm in <tomcat-home>/conf/logging.properties as below,

org.apache.catalina.realm.level = ALL
org.apache.catalina.realm.useParentHandlers = true
org.apache.catalina.authenticator.level = ALL
org.apache.catalina.authenticator.useParentHandlers = true

If you notice there are 2 positive tests and 1 negative test, negative test will give a forbidden 403 return status when a wrong certificate is sent based on the security-constraint. I hope this blog helped you.

Enabling SSL in Tomcat

For people in hurry get the latest code and follow the steps mentioned in Github.

There are lots of documents on the web on how to configure SSL in Tomcat. Tomcat Server/Client Self-Signed SSL Certificate and Mutual Authentication with CLIENT-CERT, Tomcat 6, and HttpClient stand out. But there no simple example, where we can demonstrate Enabling SSL in Tomcat, I spent days pouring documents and Googling before I got the perfect solution. In this blog I have demonstrated using a simple Java Keystore to achieve 2 way handshake. In my next blog I will show you how to use security-constraint to achieve CLIENT-CERT based access control.

This sample only works with Tomcat 6.0. Download and unzip the zip file in a location and go to <tomcat-home>/conf location and copy the 2 batch files client1cert.bat and client2cert.bat. Run both the files in that order they will create all the necessary certificates required for 2 way handshake.

Open server.xml and replace the <Connector> tag with the one below,

<Connector
clientAuth="true" port="8443" minSpareThreads="5" maxSpareThreads="75"
enableLookups="true" disableUploadTimeout="true"
acceptCount="100" maxThreads="200"
scheme="https" secure="true" SSLEnabled="true"
keystoreFile="${catalina.base}/conf/server.jks"
keystoreType="JKS" keystorePass="password"
truststoreFile="${catalina.base}/conf/server.jks"
truststoreType="JKS" truststorePass="password"
SSLVerifyClient="require" SSLEngine="on" SSLVerifyDepth="2" sslProtocol="TLS" />

If you notice the clientAuth=”true” enabled.

Copy the client0 folder to <tomcat-home>/webapp directory. Finally start the server. Now under the sourcecode folder, go to, client-cert-test open the file src/main/java/com/goSmarter/test/SecureHttpClient0Test.java file and change the below line to point to your <tomcat home>/conf location,


public static final String path = "D:/apache-tomcat-6.0.36/conf/";

Run “mvn test -Dtest=com.goSmarter.test.SecureHttpClient0Test”. You notice that 1 test succeeded. If testcase passed it means, 2 way SSL is working correctly. Please looks at the code and understand the flow. The JUnit test uses HttpUnit api to access the secure webserver. You will also notice when you run the test, there are lot of certificate related messages on the console. For this to appear, I have turned on Client side SSL debugging by putting the below code in SecureHttpClient0Test.java class,

static {
System.setProperty("javax.net.debug", "ssl");
}

I hope this blog helped you.