Java: Tomcat Security Protected Example

Posted on July 21, 2010

3


I am recently attracted to look into the Tomcat security protected example. If you freshly install Tomcat servlet container together with the examples, you will get the examples folder in the webapps directory. After you start your Tomcat server, you should be able to access the examples from http://localhost:8080/examples. This post is going to talk specifically about this example: http://localhost:8080/examples/jsp/security/protected.

Makes long story short, I couldn’t run the example, and was very upset. I browsed through the web but still couldn’t find anything. Finally I decided to start everything from scratch, creating my own experiment, a webapp. I called this webapp as “securetest”. So, to do so, first I created a folder named “securetest” in which I had another folder called “war”. In this “war” folder I created another folder called “WEB-INF”.

Creating build script

As I was using windows, I create a build.bat file in securetest directory (the same level as war folder). This is the content of my build.bat file:

cd war
jar -cvf ..\securetest.war *
cd ..
pause

Creating web.xml file

I went into the WEB-INF folder and created the web.xml file. The content of the web.xml file is copied over from the examples webapp. The content is as follow:

<web-app
xmlns=”http://java.sun.com/xml/ns/j2ee&#8221;
xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance&#8221;
xsi:schemaLocation=”http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd&#8221;
version=”2.4″
>

<description>Xander Tan Tomcat Security Experiment</description>
<display-name>Xander Tan Tomcat Security Experiment</display-name>

<security-constraint>
<display-name>Example Security Constraint</display-name>
<web-resource-collection>
<web-resource-name>Entire Application</web-resource-name>
<!– Define the context-relative URL(s) to be protected –>
<url-pattern>/*</url-pattern>
<!– If you list http methods, only those methods are protected –>
<http-method>DELETE</http-method>
<http-method>GET</http-method>
<http-method>POST</http-method>
<http-method>PUT</http-method>
</web-resource-collection>
<auth-constraint>
<!– Anyone with one of the listed roles may access this area –>
<role-name>tomcat</role-name>
</auth-constraint>
</security-constraint>

<!– Default login configuration uses form-based authentication –>
<login-config>
<auth-method>FORM</auth-method>
<realm-name>Example Form-Based Authentication Area</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 roles referenced by this web application –>
<security-role>
<role-name>tomcat</role-name>
</security-role>

</web-app>

Creating JSP files

Of course, as I intended to try out this security. I had to create three files, i.e. error.jsp, login.jsp and index.jsp. The idea was to make sure that the user would go into the login.jsp if he was not logged in. The user would be able to access the index.jsp when he had successfully logged in. And if the user logged in with wrong password, he would go into error.jsp. See… It is very simple. To make it even simpler, I actually copied these files from the Tomcat example.

index.jsp

<%
if (request.getParameter(“logoff”) != null) {
session.invalidate();
response.sendRedirect(“index.jsp”);
return;
}
%>
<html>
<head>
<title>Protected Page for Examples</title>
</head>
<body bgcolor=”white”>

You are logged in as remote user
<b><%= request.getRemoteUser() %></b>
in session <b><%= session.getId() %></b><br><br>

<%
if (request.getUserPrincipal() != null) {
%>
Your user principal name is
<b><%= request.getUserPrincipal().getName() %></b>
<br><br>
<%
} else {
%>
No user principal could be identified.<br><br>
<%
}
%>

<%
String role = request.getParameter(“role”);
if (role == null)
role = “”;
if (role.length() > 0) {
if (request.isUserInRole(role)) {
%>
You have been granted role
<b><%= role %></b><br><br>
<%
} else {
%>
You have <i>not</i> been granted role
<b><%= role %></b><br><br>
<%
}
}
%>

To check whether your username has been granted a particular role,
enter it here:
<form method=”GET” action='<%= response.encodeURL(“index.jsp”) %>’>
<input type=”text” name=”role” value=”<%= role %>”>
</form>
<br><br>

If you have configured this app for form-based authentication, you can log
off by clicking
<a href='<%= response.encodeURL(“index.jsp?logoff=true”) %>’>here</a>.
This should cause you to be returned to the logon page after the redirect
that is performed.

</body>
</html>

login.jsp

<html>
<head>
<title>Login Page for Examples</title>
<body bgcolor=”white”>
<form method=”POST” action='<%= response.encodeURL(“j_security_check”) %>’ >
<table border=”0″ cellspacing=”5″>
<tr>
<th align=”right”>Username:</th>
<td align=”left”><input type=”text” name=”j_username”></td>
</tr>
<tr>
<th align=”right”>Password:</th>
<td align=”left”><input type=”password” name=”j_password”></td>
</tr>
<tr>
<td align=”right”><input type=”submit” value=”Log In”></td>
<td align=”left”><input type=”reset”></td>
</tr>
</table>
</form>
</body>
</html>

error.jsp (I modified this file)

<h1>ERROR</h1>

Building and deploying the war file

I double-clicked on the build.bat and open my web browser, accessing http://localhost:8080/manager/html to deploy the war file. I immediately went to the http://localhost:8080/securetest to look at my login window, and yes, it was there. (In Singaporean-English: I am happy liao!)

Logging-in Pain

I tried to login as “tomcat” with password “tomcat”. If you don’t know how it goes like this, because Tomcat has the default “tomcat” username, with password “tomcat” and role “tomcat”. That’s why it is indicated in the web.xml above that the role is “tomcat”. And… It didn’t work. *Heart broken*

After spending hours changing here and there, I finally realized what’s wrong with my stupid Tomcat. I went to my Tomcat configuration (depending on your installation folder, mine is C:\Program Files\Tomcat 7.0 – it is very new when I wrote this post) at C:\Program Files\Tomcat 7.0\conf, and checked my tomcat-users.xml, and found (I simplified the problem):

<tomcat-users>
<user name=”xandertan” password=”xandertan” roles=”admin,manager,manager-gui” />
<!–
<role rolename=”tomcat”/>
<user username=”tomcat” password=”tomcat” roles=”tomcat”/>
–>

</tomcat-users>

Yes, the account was commented out, very well done. So, I unc0mmented the “tomcat” account and it worked. Well, actually I only uncommented the <user username=”tomcat” password=”tomcat” roles=”tomcat”/> and forgotten about the <role rolename=”tomcat”/>. It didn’t work… I fed up… I threw my laptop out of the window, picked it up and realized that I missed the <role rolename=”tomcat”/>. After that, it worked fine. Well… nearly.

Just for additional information: The security doesn’t look at the username but at the role. If you login with valid username and password, let say you login using “xandertan” username and “xandertan” password, you will get the  incredible 403 message. And then, you’ve got to wait until the session expires before you are able to login again. Painful no?

Advertisements
Tagged: ,
Posted in: MyWay, Technology