Form based authentication on Tomcat

Form based authentication is the most common type of authentication and is used when the user is accessing your web page by entering username and password.


We will use the most basic realm Tomcat has to offer - UserDatabaseRealm. This realm reads file tomcat-users.xml at startup and stores the users in memory. The realm is enabled by default, so there will not be much to do.

This is example of tomcat-users.xml file:

<tomcat-users>
<user password="tomcat" roles="manager,admin" username="tomcat"/>
<user password="test" roles="user" username="test"/>
</tomcat-users>

Let’s start coding. In your favorite IDE create new web project named Hello. Next we need to make three jsp pages:
- index.jsp (first page, entry point)
- login.jsp (login page, login form)
- error.jsp (not-authenticated message page)

index.jsp

<%@page contentType="text/html" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">

<html>
<head>
<title>Hello</title>
</head>
<body>
<h3>Hello Web Application</h3>

</body>
</html>

login.jsp

<%@page contentType="text/html" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">

<html>
<head>
<title>Log In</title>
</head>
<body>
<form method="POST" action="<%=response.encodeURL("j_security_check")%>">
<table>
<tr>
<td>Username:</td>
<td><input type="text" name="j_username"></td>
</tr>
<tr>
<td>Password:</td>
<td><input type="password" name="j_password"></td>
</tr>
</table>
<input type="submit" value="Log In"></form>
</body>
</html>

error.jsp

<%@page contentType="text/html" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">

<html>
<head>
<title>Hello</title>
</head>
<body>
<h1>Not Authenticated!!!</h1>
<a href="login.jsp">Try again?</a>
</body>
</html>

Add the following lines to web.xml. The element <url-pattern> defines which part of your application will be protected by realm and <role-name> defines the user’s role who can access your page. The next important element <auth-method> tells your application to use FORM type of authentication when a user tries to access your index.jsp page. Inside <form-login-config> you define a page that will show up to authenticate user and another page that will report an error if authentication fails.

<security-constraint>
<web-resource-collection>
<web-resource-name>Hello Application</web-resource-name>
<url-pattern>/*</url-pattern>
</web-resource-collection>
<auth-constraint>
<role-name>manager</role-name>
</auth-constraint>
</security-constraint>
<login-config>
<auth-method>FORM</auth-method>
<realm-name>My Realm</realm-name>
<form-login-config>
<form-login-page>/login.jsp</form-login-page>
<form-error-page>/error.jsp</form-error-page>
</form-login-config>
</login-config>
<security-role>
<role-name>manager</role-name>
</security-role>

Before we deploy application on Tomcat let’s take a look at server.xml. There you can see that default UserDatabase realm is already implemented and enabled, so we will use this one.

<Realm className="org.apache.catalina.realm.UserDatabaseRealm" resourceName="UserDatabase" />

Search for <Resource> element, where you can find the details about UserDatabase realm. It says that this realm will use file tomcat-users.xml for authentication:

<Resource name="UserDatabase" auth="Container"
type="org.apache.catalina.UserDatabase"
description="User database that can be updated and saved"
factory="org.apache.catalina.users.MemoryUserDatabaseFactory"
pathname="conf/tomcat-users.xml" />

Deploy Hello application and see if it works:

http://localhost:8080/Hello

UserDatabaseRealm intercepts the request and shows login.jsp page first. If login is succesful you should see index.jsp page, otherwise error.jsp page.