ONJava.com    
 Published on ONJava.com (http://www.onjava.com/)
 See this if you're having trouble printing code examples


J2EE Form-based Authentication

by Prabu Arumugam
06/12/2002

Implementing security for Web applications is a mandatory task for architects and Web application developers. In J2EE, the Web containers have support for built-in security mechanisms for their applications.

There are two major components of Web application security: authentication and authorization. J2EE-based Web containers offer three types of authentication mechanisms: basic, form-based, and mutual authentication. Most Web applications use the form-based authentication mechanism, since it allows applications to customize the authentication user interface. Web containers implement authorization on Web resources of applications, using security roles defined in the deployment descriptor of the Web application.

There are three issues that software architects and software developers come across using the form-based authentication mechanism:

Despite the fact that there is plenty of documentation and many examples available for form-based authentication, none of them clarifies these issues. Hence, most applications have implemented security in their own way.

This article demonstrates how the form-based authentication mechanism works with other security realms, especially the database. It also explains how Web containers use the security roles to implement authorization, and how applications can extend these security roles to protect functionalities within single resource.

Form-Based Authentication

Form-based authentication lets developers customize the authentication user interface. The login-config section of web.xml defines the type of authentication mechanism, and the URIs to login and error pages.

<login-config>
<auth-method>FORM</auth-method>
<form-login-config>
<form-login-page>/login.jsp</form-login-page>
<form-error-page>/fail_login.html</form-error-page>
</form-login-config>
</login-config>

The login form must contain fields for entering username and password. These fields must be named j_username and j_password, respectively. This form should post these values to j_security_check logical name.

Here is an example showing how the form should be coded into an HTML page:

<form method="POST" action="j_security_check">
<input type="text" name="j_username">
<input type="password" name="j_password">
</form>

This form of authentication, which uses base64 encoding, can expose username and password unless all connections are over SSL.

The Web containers activate the authentication mechanism that has been configured for that resource, when protected Web resources are accessed.

Web containers perform the following steps to implement security of a Web application.

  1. Determines whether the user has been authenticated when the protected Web resources are accessed.

  2. If the user has not been authenticated yet, requests that the user provide security credentials by redirecting to the login page defined in the deployment descriptor.

  3. Validates the user's credentials against the security realm configured for the container.

  4. Determines whether the authenticated user is authorized to access Web resources defined in the deployment descriptor (web.xml).

In the deployment descriptor of a Web application, form-based authentication does not specify the security realm, as the basic authentication mechanism does. In other words, it does not explicitly declare the type of security realm it should use to authenticate a user. This causes some confusion as to what security realm it actually uses to authenticate the user.

Web containers perform the following steps to validate a user:

  1. Determines the configured security realm for the container.

  2. Uses that security realm for authentication.

Since database and LDAP provide greater flexibility in maintaining information, most organizations may want this persistence for security authentication and authorization information.

Many Web containers have support for different types of security realms: database, LDAP, and custom realm.

For example, in the Tomcat Web container, server.xml configures database as its security realm.

<Realm 
className="org.apache.catalina.realm.JDBCRealm" 
debug="99"
driverName="oracle.jdbc.driver.OracleDriver"
connectionURL="jdbc:oracle:thin:@{IPAddress}:{Port}:{Servicename}"
         connectionName="{DB Username}"
         connectionPassword="{Password}"
         userTable="users" 
userNameCol="username" 
         userCredCol="password"
userRoleTable="user_roles" 
roleNameCol="rolename" 
/>

The <Realm> tag of Tomcat's server.xml defines the type of security realm that the container should use to authenticate a user. Note that the container uses this realm for Web applications whose authentication mechanism is form-based.

Note: Please see the sections on deploying database security realm support for Tomcat and WebLogic below.

Java Enterprise in a Nutshell

Related Reading

Java Enterprise in a Nutshell
By William Crawford, Jim Farley, David Flanagan

Authorization

Once the user has been authenticated, the container retrieves security roles for the authenticated user and checks to see if the user belongs to one of the roles defined in the <auth-constraint> tag of the deployment descriptor. The Web container displays an error message if the user does not belong to one of roles.

The <security-constraint> tag of the deployment descriptor (web.xml) defines protected Web resources and a list of roles that have access to these Web resources.

<security-constraint>
<web-resource-collection>
<web-resource-name>AdminPages</web-resource-name>
<description> accessible by authorised users </description>
<url-pattern>/admin/*</url-pattern>
<http-method>GET</http-method>
</web-resource-collection>
<auth-constraint>
<description>These are the roles who have access</description>
<role-name>manager</role-name>
</auth-constraint>
</security-constraint>

Web containers enforce authorization at a page level. However, commercial applications may also want to enforce authorization on functionalities within a single page. This may require that some additional new application-specific security roles be defined in the application. To control access to functionalities, the application needs to understand the notion of privileges for a role. The Web container specification does not address privileges.

Since authorization roles are dynamic, developers often get confused as to whether these security roles need to be added to the deployment descriptor. Web containers just need one role defined in the deployment descriptor for the application to take advantage of security support. So, the application can define one high-level role and assign all users to this role. This allows all users in this role to have access to the Web resources.

In addition, the application can define additional roles to enforce authorization on low-level functionalities within a single Web resource. These low-level security roles do not need to be in the deployment descriptor, since the application has been configured with a high-level security role that contains all of the users in the application. This allows Web applications to take advantage of container authorization support, and to implement application-specific authorization.

For example, you can define an administrator role for all of the users at a high level in the deployment descriptor to protect administration Web resources. This allows all of the users in the administrator role to access the administration pages. To control other functionalities within the administration pages, you can create new roles, such as sysadmin or appadmin, within the application.

The application can extend these security roles to have privileges. Then, the application can use these privileges to control access to its functionalities.

Despite the fact that application-specific security roles are not defined in the deployment descriptors, these roles can still be used in the isUserInRole method to determine whether the user in these security roles.

Advantages

Configuring the Database Security Realm in Tomcat

  1. Create User Table

    This table needs the username and password columns.

    create table users (username varchar(20) not null, password(20) not null)

  2. Create Role Table

    This table maintains the list of roles in application. It just needs role name column in the table.

    create table roles (rolename varchar(20) not null)

  3. Create User-Role Association Table

    This table maintains association between a user and roles. A user can belong to one or more roles.

    create table user_roles (username varchar(20) not null, rolename varchar(20) not null)

  4. Insert data into tables

    insert into users values('user1', 'password')

    insert into role values('manager')
    insert into user_roles values('user1', 'manager')

  5. Create User Table

    This table needs the username and password columns.

    create table users (username varchar(20) not null, password(20) not null)

  6. Create Role Table

    This table maintains the list of roles in the application. It just needs the role name column in the table.

    create table roles (rolename varchar(20) not null)

  7. Create User-Role Association Table

    This table maintains association between a user and roles. A user can belong to one or more roles.

    create table user_roles (username varchar(20) not null, rolename varchar(20) not null)

  8. Insert data into tables

    insert into users values('user1', 'password')

    insert into role values('manager')

    insert into user_roles values('user1', 'manager')

  9. Configure Tomcat (This example uses the Oracle thin driver) by copying this information in server.xml in the {tomcat}\conf\ folder. (Tomcat uses memory realm as default realm. Comment the memory realm.)

    <Realm 
    className="org.apache.catalina.realm.JDBCRealm" 
             debug="99"
    driverName="oracle.jdbc.driver.OracleDriver" 
    connectionURL="jdbc:oracle:thin:@{IP address}:{Port}:{Servicename}"
    connectionName="{DB Username}"
             connectionPassword="{Password}"
             userTable="users" 
             userNameCol="username" 
             userCredCol="password"
             userRoleTable="user_roles" 
             roleNameCol="rolename" 
    />

    Replace the following values with environment values

    {IP Address} - IP address of database server

    {Port} - Port number

    {Servicename} - Service name

    {DB Username} - database login

    {Password} - password to database login

    Note: You need to have the JDBC driver for your database. (The Oracle thin driver is used in this example.)

  10. Copy the Oracle thin driver JAR file or JDBC driver for your database (oracle_thin_driver.jar) into the {tomcat_home}/server/lib directory.

  11. Configure the Web application deployment descriptor with security constraints.

    <security-constraint>
    <web-resource-collection>
    <web-resource-name>Protected Area</web-resource-name>
    <!-- Define the context-relative URL(s) to be protected -->
    <url-pattern>/*</url-pattern>
    <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>
    <role-name>manager</role-name>
    </auth-constraint>
    <user-data-constraint><transport-guarantee>
    NONE</transport-guarantee></user-data-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>/jsp/login.jsp</form-login-page>
    <form-error-page>/jsp/error.jsp</form-error-page>
    </form-login-config>
    </login-config>

    Note that the <role-name> value of this tag in <auth-constraint> should be one of the role names in the user-roles table.

Deploying The Sample Program Into Tomcat

  1. Configure Tomcat using the instructions defined in the previous section.

  2. Download the security-form-based.war file and copy it into Tomcat's webapps directory.

  3. Start the Tomcat server.

  4. Open a Web browser and go to http://{ip address:port no}/security-form-based/protected/index.jsp.

  5. Type in the username and the password (user1, password).

Configuring the Database Security Realm in WebLogic

There is very good documentation on configuring the database security realm. Please refer to this link.

Configure your Web application deployment descriptor, similar to the one shown in the configuration steps for Tomcat.

One difference between Tomcat and WebLogic deployment descriptors is that the deployment descriptor for WebLogic requires the following section, while Tomcat does not require this section.

<security-role>
<description>
Manager security role
</description>
<role-name>
manager
</role-name>
</security-role>

Conclusion

This article has provided in-depth understanding of the form-based mechanism and how it works with database security realms to handle authentication. Web applications can take advantage of the form-based mechanism to protect their resources while at the same time using legacy security realms for authentication information.

In addition, this article has described the level of authorization support provided by J2EE Web containers and how you can define new security roles without modifying the deployment descriptor of a Web application.

Resources

Download the source code: security.zip.

Download the .war file: security-form-based.war.

Web Tier Security Documentation from Sun.

Tomcat JDBC Realm.

WebLogic RDBMS Realm

Prabu Arumugam is a software architect and senior Java developer at Forest Express, LLC.


Return to ONJava.com.

Copyright © 2009 O'Reilly Media, Inc.