Sometimes it’s easier to use server based authentication than to implement your own authentication. Just write some lines in some xml and everything works.
But what if your users don’t respect all the rules for a standard tomcat authentication?

The smart guys from Tomcat have a solution for that. You can write your own Realm Authentication.

In my case I needed a SSL + LDAP authentication. Tomcat has standard authentication for each one, but not combined.
The SSL certificate provides an username that must be verified in the LDAP (if the user has the right permissions).

A Realm authentication is defined by the org.apache.catalina.Realm interface. But it’s easier to extend RealmBase and override some methods instead of implementing Realm.

In my case I had to override:

public class LdapCertificateRealm extends RealmBase {
//the authentification for the certificate
//I've created my own Principal which returns the username from the LDAP corensponding to a SSL certificate.
//you have to write your own code for the ldap operations
public Principal authenticate(X509Certificate[] arg0) {
....
}


//with the LDAP username from the custom Principal we check the role
//you have to write your own code for the ldap operations
public boolean hasRole(Principal arg0, String arg1) {
....
}

@Override
protected String getName() {
return "LdapCertificateRealm";
}

@Override
protected String getPassword(String arg0) {
// do nothing
return null;
}

@Override
protected Principal getPrincipal(String arg0) {
//do nothing
return null;

}

}

Tomcat configuration:

Server.xml
1. SSL configuration (another story which will be told by Adi)
2. Realm configuration should look something like this

<Engine name="Catalina" defaultHost="localhost" debug="0">
<Logger className="org.apache.catalina.logger.FileLogger"
prefix="catalina_log." suffix=".txt"
timestamp="true"/>

<Realm className="auth.LdapCertificateRealm" debug="0"/>

<Host name="localhost" debug="0" appBase="webapps" unpackWARs="true" autoDeploy="true" xmlValidation="false" xmlNamespaceAware="false">
<Logger className="org.apache.catalina.logger.FileLogger" directory="logs" prefix="localhost_log." suffix=".txt" timestamp="true"/>
</Host>
</Engine>

Web.xml (Application web.xml)
<login-config>
<auth-method>CLIENT-CERT</auth-method>
<realm-name>Site configuration</realm-name>
</login-config>

<security-constraint>
<web-resource-collection>
<web-resource-name>Application configuration</web-resource-name>
<url-pattern>/testuser.jsp</url-pattern>
<http-method>GET</http-method>
<http-method>POST</http-method>
</web-resource-collection>

<auth-constraint>
<role-name>admin</role-name>
</auth-constraint>

<!-- Automatically redirects http to https -->
<user-data-constraint>
<transport-guarantee>CONFIDENTIAL</transport-guarantee>
</user-data-constraint>
</security-constraint>

That’s all folks!

Helpful links:
http://lekkimworld.com/2005/07/29/1122648646441.html
http://www.vorburger.ch/blog1/2006/08/setting-up-two-way-mutual-ssl-with.html
http://www.bath.ac.uk/bucs/accessing-ldap.shtml#java