How do I use Basic authentication with Tomcat?
Author: Deron Eriksson
Description: This tutorial describes setting up Basic authentication on Tomcat.
Tutorial created using: Windows XP || JDK 1.5.0_09 || Eclipse Web Tools Platform 1.5.1 || Tomcat 5.5.20


Page:    1 2 >

Setting up your web application to do Basic authentication with TomcatSW is quite easy. However, if you use plain HTTP, your name and password can be intercepted by monitoring network communication, so I recommend using HTTP with SSL (HTTPS) if you do any kind of authentication with your web application so that your name and password are encrypted. With Basic authentication (with and without SSL), your name and password do get automatically Base64- encoded , which is better than having the name and password cross the network in plaintext, but Base64 is 'encoding', not 'encryption', and it can be easily decoded, as we will show in this tutorial.

In Basic authentication, if you try to hit a web application url that is protected and you are currently unauthenticated, a popup window appears and you enter a particular username/password, which gets sent to Tomcat. Tomcat checks to see that the sent username and password match a user entry in tomcat-users.xml, and it makes sure that the user's tomcat-users.xml role (or roles) match the role (or roles) that have access to your web application resource, which is specified in your web.xmlW file. If we have a match (username/password/role), the user gains access to the application resource.

Our tomcat-users.xml file is shown below. It has one role called 'tomcat', and three users -- 'tomcat', 'myname', and 'test'. The 'tomcat' and 'myname' users both have the 'tomcat' role.

tomcat-users.xml

<?xml version='1.0' encoding='utf-8'?>
<tomcat-users>
  <role rolename="tomcat"/>
  <user username="tomcat" password="tomcat" roles="tomcat"/>
  <user username="myname" password="mypassword" roles="tomcat"/>
  <user username="test" password="test"/>
</tomcat-users>

Our demo web application is called 'tomcat-demo'. Its structure is shown below. For convenience, I also have a simple project called '_shortcuts' that contains shortcuts to the Tomcat server.xml and tomcat-users.xml files in the file system.

Eclipse Navigator View

The tomcat-demo web.xml is shown below. The login-config element contains the auth-method element, which specifies the authentication method that we use, which is BASIC. The security-constraint element contains 3 elements: web-resource-collection, auth-constraint, and user-data-constraint. The web-resource-collection specifies the parts of our application that require authentication. The /* indicates that the whole application requires authentication. The auth-constraint specifies the role that a user needs to have in order to access the protected resources. The user-data-constraint's transport-guarantee can be NONE, CONFIDENTIAL, or INTEGRAL. We set it to NONE, which means that redirecting to SSL is not required when you try to hit the protected resource.

web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app id="tomcat-demo" version="2.4"
	xmlns="http://java.sun.com/xml/ns/j2ee"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
	<servlet>
		<servlet-name>TestServlet</servlet-name>
		<servlet-class>test.TestServlet</servlet-class>
	</servlet>
	<servlet-mapping>
		<servlet-name>TestServlet</servlet-name>
		<url-pattern>/test</url-pattern>
	</servlet-mapping>

	<security-constraint>
		<web-resource-collection>
			<web-resource-name>Wildcard means whole app requires authentication</web-resource-name>
			<url-pattern>/*</url-pattern>
			<http-method>GET</http-method>
			<http-method>POST</http-method>
		</web-resource-collection>
		<auth-constraint>
			<role-name>tomcat</role-name>
		</auth-constraint>

		<user-data-constraint>
			<!-- transport-guarantee can be CONFIDENTIAL, INTEGRAL, or NONE -->
			<transport-guarantee>NONE</transport-guarantee>
		</user-data-constraint>
	</security-constraint>

	<login-config>
		<auth-method>BASIC</auth-method>
	</login-config>

</web-app>

The demo application has one servletW, TestServlet. It displays the request headers that the browser client sends to Tomcat. It also takes the 'authorization' header value from the request and Base64-decodes the value to show that the username and password are in fact very easily readable if someone intercepts the network communication. (This is why it's a very good idea to use HTTPS for authentication).

TestServlet.java

package test;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.Enumeration;

import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.tomcat.util.buf.Base64;

public class TestServlet extends HttpServlet {

	private static final long serialVersionUID = 1L;

	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {
		response.setContentType("text/html");
		PrintWriter out = response.getWriter();
		out.println("This is the Test Servlet");

		Enumeration headerNames = request.getHeaderNames();
		while (headerNames.hasMoreElements()) {
			String headerName = (String) headerNames.nextElement();
			out.print("<br/>Header Name: <em>" + headerName);
			String headerValue = request.getHeader(headerName);
			out.print("</em>, Header Value: <em>" + headerValue);
			out.println("</em>");
		}

		out.println("<hr/>");
		String authHeader = request.getHeader("authorization");
		String encodedValue = authHeader.split(" ")[1];
		out.println("Base64-encoded Authorization Value: <em>" + encodedValue);
		String decodedValue = Base64.base64Decode(encodedValue);
		out.println("</em><br/>Base64-decoded Authorization Value: <em>" + decodedValue);
		out.println("</em>");
	}

}

(Continued on page 2)

Page:    1 2 >