How do I use Form authentication with Tomcat?
Author: Deron Eriksson
Description: This tutorial describes the use of Form authentication with Tomcat.
Tutorial created using:
Windows XP || JDK 1.5.0_09 || Eclipse Web Tools Platform 1.5.1 || Tomcat 5.5.20
In another tutorial, we set up TomcatSW with SSL with a self-signed certificate. Since we set this up, this tutorial will use SSL, since it is concerned with authentication, which typically should use encrypted communication. Basic authentication's pop-up window is fine but not exactly pretty. Form authentication allows you to specify an htmlW file (or jspW) to go for authentication. You can also specify a file to go to if authentication fails. The demonstration project is called 'tomcat-demo'. It has a web.xmlW file, a login.html file, a login-failed.html file, and a TestServlet class. The web.xml file is shown below. Notice that login-config → auth-method specifies FORM since we want to use Form authentication. Note that form-login-page points to our login.html file in our web directory, and form-error-page points to our login-failed.html file. Of further interest is the transport-guarantee value, which is CONFIDENTIAL. This causes a request for a protected resource on a non-secure port to be redirected to a secure port. This allows us to authenticate securely with HTTPS even if the initial request is to the HTTP port. 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>CONFIDENTIAL</transport-guarantee> </user-data-constraint> </security-constraint> <login-config> <auth-method>FORM</auth-method> <form-login-config> <form-login-page>/login.html</form-login-page> <form-error-page>/login-failed.html</form-error-page> </form-login-config> </login-config> </web-app> The login.html file contains a form with j_security_check as its action. It contains a text input called j_username and a password input called j_password. These are the input names that need to be used in order for Tomcat to process the Form authentication. login.html<form method="POST" action="j_security_check"> <table> <tr> <td colspan="2">Login to the Tomcat-Demo application:</td> </tr> <tr> <td>Name:</td> <td><input type="text" name="j_username" /></td> </tr> <tr> <td>Password:</td> <td><input type="password" name="j_password"/ ></td> </tr> <tr> <td colspan="2"><input type="submit" value="Go" /></td> </tr> </table> </form> The login-failed.html file displays a simple message if the Form authentication fails. login-failed.html<p> Sorry, login failed! </p> The TestServlet class is shown below. It enumerates over the request headers from the browser and writes them to the response. TestServlet.javapackage 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; 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>"); } } } In another tutorial, I changed the Tomcat HTTPS connector port to 4321 rather than the default 8443. I also changed the HTTP connector port's redirectPort to 4321 so that the request to 8080 will get redirected to port 4321 (to handle the transport-guarantee CONFIDENTIAL setting mentioned earlier). <Connector port="8080" maxHttpHeaderSize="8192" maxThreads="150" minSpareThreads="25" maxSpareThreads="75" enableLookups="false" redirectPort="4321" acceptCount="100" connectionTimeout="20000" disableUploadTimeout="true" /> <Connector port="4321" maxHttpHeaderSize="8192" maxThreads="150" minSpareThreads="25" maxSpareThreads="75" enableLookups="false" disableUploadTimeout="true" acceptCount="100" scheme="https" secure="true" clientAuth="false" sslProtocol="TLS" /> (Continued on page 2) Related Tutorials:
|