Apache Tomcat
Description
A common task when developing a web application is user authentication and authorization - parts of the application should only be seen by the users which you want to see them. Three things are required for realizing this, a mechanism for authentication which checks the credentials provided by the user in the login form. A mechanism for authorization which decides about user privileges and a data store where user information & credentials are stored.
A perfect choice for the data store is ApcheDS. LDAP is a widely adopted standard so you can reuse your user data also for other systems.
For authentication and authorization J2EE provides a few standard mechanisms. The most popular mechanism for authentication, and the one used in the example, is form based authentication, where you can create your own customized JSP login form. There exist
three further authentication mechanisms which are not discussed here, so look at the resources if you are interested in.
So let's talk about authorization. In a J2EE environment it's possible to assign one or more roles to each user. A role is a logical grouping of users, for example you could have different roles for employees, customers and guests. Basing on these roles you can grant different rights on what you allow your users to see and to do.
The following example shows the building of a simple web application where you can Login using username and password and afterwards receive a page confirming your successful login and presenting details about it.
Example
Prerequisites:
- Tomcat 5.5 (this example was tested with 5.5.20 but should work with every 5.5.x version)
- ApacheDS
Configuration used in this example:
Tomcat |
|
---|---|
Host |
madagaskar |
Port |
8080 |
ApacheDS |
|
Host |
zanzibar |
Port |
10389 |
Suffix |
o=sevenSeas |
Admin user dn |
uid=admin,ou=system |
Admin pass |
secret |
Data
First import the example data in an own partition of your directory server, you can find them here, if you haven't already done this. How to create a partition is described here, how to import data into the directory is described here. This should result in the following directory structure:
Download the archive with the JSP files for this example, (which are taken from an tomcat example) and extract it to the webapps folder of your tomcat installation.
Deployment Descriptor
The archive doesn't contain a deployment descriptor (DD) for Tomcat, hence we have to create one for our application. The DD defines which part of our application we wish to protect, whom we want grant access to it, which authentication method should be used and other things, but it does not define the details for connecting to ApacheDS. In our example, we want to grant only the crew of "HMS Bounty" access to our application. The DD is stored at /security/WEB-INF/web.xml.
Let's have a closer look at it.
This describes which url should be protected, which means, that the url's defined here can only been requested by a user who has successfully been authenticated (and has an appropriate role assigned). You can provide multiple patterns here. It's also possible to restrict access only for specific HTTP Methods. Which roles are allowed to request these restricted URL's is defined in the following lines. You can specify either some concrete role names here, in our example "HMS Bounty", or just write "*" to allow access for all registered users.
The login-config element provides details about the authentication method you want to use. This example uses form-based authentication, so we need to define the authentication method "FORM" and the location for our login and error pages.
The security-role element lists all roles available.
JNDI Realm
The details for the connection to ApacheDS are defined using a Tomcat JNDI Realm. Save the following in a file at /security/protected/META-INF/context.xml
Let's have a closer look at it. The following specifies the details for the user connecting to ApacheDS. Make sure that this user has the appropriate rights for reading all required entries and attributes. We have used the admin credentials here, but in general it's not a good idea to provide your admin credentials everywhere in your config files. We have done this here because it's only a very simple example.
But the question is: How does Tomcat figure out where the entries for the user's you want to allow to login are stored?
The attribute "userPassword" contains the name of the attribute, which contains the password of the user. "userPattern" specifies where to search for user entries. The expression "{0}" is a placeholder for the value of the username entered by the user into the login form.
Finally you have to tell Tomcat how he can determine if someone is member of the crew from HMS Bounty. All members of the crew are stored in a groupOfUniqueNames entry below "ou=crews,ou=groups,o=sevenSeas".
Starting the application
Now (re)start Tomcat and go to http://madagaskar:8080/security/protected/index.jsp. You should see the following Login Form. Enter name and password (which is simply "pass" in our example) of a member of the crew of HMS Bounty.
After successful login you can test of your user belongs to a specific role.
Login Form
If you have a closer look at the source of the login form (/security/protected/login.jsp) you'll see the following
It's always crucial that the Login Form has the action "j_security_check" and that the fields "j_username" and "j_password" are present, otherwise Form-Based authentication won't work properly. This and further details are explained in the J2EE Tutorial and servlet specification.
Resources
Tomcat's Homepage
Realms in Tomcat
The J2EE 1.4 Tutorial (Chapter 32 contains more information about J2EE security)
Servlet Specification 2.4 (the one which belongs to J2EE 1.4)