Metawerx Java Hosting Small Logo

Securing your site with Container Managed Security

Author: Neale Rudd, Metawerx

Date: 21-Jan-2007

This is a short tutorial on securing sections of your website or web application, using the container managed security provided by Tomcat 5 and other servlet containers. We will lock down a /members and /admin folder, so that a password is required to gain access.

We will use:

  • META-INF/context.xml to add a memory-based security realm, which will read users and roles from an XML file
  • WEB-INF/web.xml to add a security constraint, security roles, and a login configuration
  • WEB-INF/users.xml to add users, passwords and roles

The tutorial assumes:

  • you are using Tomcat 5.x
  • your application is called MyApp
  • you want to protect a members-only area of your site, which is in the /members folder
  • you want to protect the administration area of your site, which is in the /admin folder

Add the folders

We are going to protect two new folders on the site, so create the folders and put something useful in them.

Source Code: <Your Application Root>/admin/index.jsp

<h1>Administration Area - Access Granted</h1>

Source Code: <Your Application Root>/members/index.jsp

<h1>Welcome to the Members Area</h1>

We will also make a simple index.jsp page, which has links into each of these areas.

Source Code: <Your Application Root>/index.jsp

<h1>Welcome to my secured application!</h1>

Please click a link below to log in.

<p /><a href="/members/index.jsp">Members area</a>
<br /><a href="/admin/index.jsp">Admin area</a>

Adding the realm

Next, create a file called META-INF/context.xml in your web application, if it doesn't already exist.

Source Code: <Your Application Root>/META-INF/context.xml

<Context>
    <Realm className="org.apache.catalina.realm.MemoryRealm" 
           pathname="[PATH-TO-YOUR-WEB-INF-FOLDER]/users.xml" />
</Context>

This simple example uses an xml file to define the users and roles. It is also possible to use a JDBCRealm or other realm types.

Change the pathname attribute to a suitable location as necessary. It makes sense to point to a file in your WEB-INF folder, so that you can find and edit the file easily in the future alongside web.xml.

Examples:

Windows:
    pathname="c:/tomcat5/jakarta/webapps/MyApp/WEB-INF/users.xml"

Linux:
    pathname="/tomcat5/jakarta/webapps/MyApp/WEB-INF/users.xml"

Your application structure should look like this:

<webapps>
    /MyApp
        /WEB-INF
            web.xml
            users.xml         - We will create this file in the next step
        /META-INF
            context.xml       - The new file we just added
        /admin
            index.jsp         - Main file for the /admin area
        /members
            index.jsp         - Main file for the /members area
        index.jsp

Creating your users.xml file

Now create a file called WEB-INF/users.xml.

Source Code: <Your Application Root>/WEB-INF/users.xml

<?xml version='1.0' encoding='utf-8'?>
<tomcat-users>

    <role rolename="admin"/>
    <role rolename="member"/>

    <user username="neale" password="mango" roles="admin"/>
    <user username="cassie" password="grape" roles="member"/>
    <user username="oliver" password="apple" roles="member"/>

</tomcat-users>

This file defines:

  • the role names you want to use in the application
  • user names and passwords
  • the roles each user is assigned to

Add as many roles or users as you want to. The roles attribute can contain a list of roles, separated by commas.

Example:

    <user username="fred" password="orange" roles="wiki,bugtracker,repository,cms"/>

For the sake of this example, make sure you define an "admin" and "member" role as in the example provided above.

Editing your web.xml file

The final step is to define the security constraint in web.xml.

Edit your web.xml file, and add the following before the final <web-app> tag.

Source Code: Insert into <Your Application Root>/WEB-INF/web.xml

<!-- Define the roles we want to use in the application -->
<security-role> 
    <role-name>admin</role-name> 
</security-role>
<security-role> 
    <role-name>member</role-name> 
</security-role>

<security-constraint> 

    <display-name>Security constraint for the /member folder</display-name> 

    <!-- Define the resource, a /members folder -->
    <web-resource-collection> 
        <web-resource-name>Members Only</web-resource-name> 
        <url-pattern>/members/*</url-pattern> 
    </web-resource-collection> 

    <!-- Only administrators and members can access this resource --> 
    <auth-constraint> 
        <role-name>admin</role-name> 
        <role-name>member</role-name> 
    </auth-constraint> 
    
</security-constraint> 

<security-constraint> 

    <display-name>Security constraint for the /admin folder</display-name> 

    <!-- Define the resource, a /admin folder -->
    <web-resource-collection> 
        <web-resource-name>Administration</web-resource-name> 
        <url-pattern>/admin/*</url-pattern> 
    </web-resource-collection> 

    <!-- Only administrators can access this resource --> 
    <auth-constraint> 
        <role-name>admin</role-name> 
    </auth-constraint> 
    
</security-constraint> 

<!-- Use BASIC security -->
<login-config> 
    <auth-method>BASIC</auth-method> 
    <realm-name>Secure Area</realm-name> 
</login-config> 

What did we just add?

  • Two <security-role> elements, defining the roles we have specified in the users.xml file. For every role we want to use, we have to define them in this way in web.xml.
  • Two <security-constraint> elements, defining the areas of the site to protect. In this case, we are protecting an /admin and a /members folder. Inside the constraint, there is an area to define the URL pattern, and the roles which can access the area (or "resource").
  • A <login-config> element. This tells the container to use BASIC Authentication, which creates a popup-dialog in the browser.

Success

Finally, restart your application.

If you followed the steps above, when you browse to either the /members or /admin folders, you will be asked to log in.

The name of the realm appears in the dialog. Here is a screenshot from Internet Explorer:

http://www.metawerx.net/images/screenshots/container_managed_security_dialog.png

Tips

  • Unsuccessul logins will result in a 401 - Access Denied error. You can create a custom error page, or redirect the user back to the login page using custom errors pages. See Custom Error Pages in Tomcat for a tutorial.
  • FORM-Based Authentication can also be used, but needs a little more work to implement, such as the creation of a login and error page, and the use of sessions. See <login-config> for details.
  • The user name can be displayed by the application after a successful login. See Security Realms for more information.

More Information

  • web.xml reference guide for usage examples of the tags used above
  • context.xml for other useful things you can do with your context file
  • Security Realms for more information on how each of the concepts above work together
navigation
metawerx specific
search
Share
tools
help

referring pages

Share