WebAuth is a J2EE module that can perform web-based authentication-related common operations, such as login, logout, password management and user management. It is released in the form of a Jar file that can be included in War or Ear files.
In order to better understand what WebAuth is, let’s take look at an example. Supposedly, we are writing a web-based application. In this application, we want to restrict certain pages and operations to members only. Therefore, we need to authenticate users and require them to use username and password to identify themselves. This process is called login. If a user has not logged in and is requesting a page restricted to members, he or she will be asked for login. After a member logs in, he or she can change password. The member can log out at any time. We might also need functionalities to add or remove members. Although these functionalities might be performed by another type of users, say admin users.
In a nutshell, the example above illustrates that common features related to authentication include login, logout, changing password, adding users, and removing users. In addition, the example indicates that multiple types of users may be needed in one application. Common types include: member, admin users, and CSR (Customer Service Representative) users.
WebAuth not only supports all the common features listed above, but also is a generic module that can be used for any type of users.
This document describes the procedure to use WebAuth in a web-based J2EE application. Sample codes are provided in every step. For better illustration, the example above is used in sample codes. This document first lists the technical requirement of WebAuth. It then explains the page structure required by WebAuth. Steps followed are creating a new type of users who need authentications, using Servlet Filter to restrict page accesses to desired users, adding login and logout, adding password management, adding user management, initializing the database and JDBC parameters, and finally including WebAuth in the web application.
We assume that the audience of this document is familiar with Servlet 2.3, JSP 1.2 and Struts 1.1.
In order to use WebAuth, you need the followings.
Before we use WebAuth, we need to understand the page structure required by WebAuth. Using the example above, this section explains the necessary page flow when using WebAuth.
A common way of restricting page accesses to desired users is to use URL pattern. For instance, we can put all member-restricted pages in a section of which URLs are in the pattern of http://<servername>:<port>/<appname>/members/*. And we can put all admin-restricted pages in a section of which URLs are in the pattern of http://<servername>:<port>/<appname>/admin/*.
If a user has not logged in and is requesting a page restricted to members, he or she will be redirected to the login page for members. If a user has not logged in and is requesting a page restricted to admin users, he or she will be redirected to the login page for admin users.
We must have a login page for users to enter username and password. If the login is unsuccessful, the same login page will be displayed with detailed error messages. If the login is successful, a user will see a different page. Since WebAuth is based on JSP, we need to write two JSP pages, one for login failed and one for login successful.
Logout is only a link. We don’t need a page for it. But we need to know which page to go once a user logs out.
We need a password-change page for users to enter old password and new password. If the password-change operation is unsuccessful, the same page will be displayed with detailed error messages. Otherwise, a user will see a confirmation page. Similar to Login, we need two JSP pages, one for failed and one for successful.
Now, we are ready to use WebAuth in a web-based J2EE application. The first thing is to create a new type of users who need authentication. In our example above, the new type of users is member.
User.java is an abstract class that models any type of users. We need to create a class extending from User.java. The subclass should model the new type of users. For example, we can create a subclass called Member.java to model members. Since the getUserType() method in User.java is abstract, we have to provide the body of getUserType() in the subclass. This method should return a unique integer to represent the type of users. For example, Member.java might look like this:
public class Member extends User{
private static
final int user_type = 1;
public int
getUserType() {
return
user_type;
}
}
Since each subclass of User.java models a type of users, the subclass may need to contain additional code to reflect the business logic of the type of users. For instance, members may have additional attributes other than username and password and may have additional methods. In the design of WebAuth, subclasses of User.java are free to do anything, as long as they implement getUserType().
For each type of users, we need to create a subclass of UserSession.java. UserSession.java is an abstract class that models generic user sessions. A user session is created after a user logs in. The session is removed when the user logs out or when the session is timed out. The subclass should model sessions for the new user type. For example, we can create a subclass called MemberSession.java to model sessions for members. Similar to the subclass of User.java, we have to provide the body of getSessionType() in the subclass of UserSession.java. This method should return a unique integer to represent the type of user sessions. For example, MemberSession.java might look like this:
public class MemberSession extends UserSession {
public
final static int SESSION_TYPE = 1;
public
int getSessionType() {
return
SESSION_TYPE;
}
}
Subclasses of UserSession.java are free to do anything, as long as they implement getSessionType().
In section URL Patterns for Restricted Pages, we discussed that page accesses can be restricted via URL patterns. WebAuth uses filters to accomplish this goal. LoginFilter, a subclass of javax.servlet.Filter, detects whether a user has the right privilege to access a page. If not, LoginFilter redirects the user to the login page.
Associating a URL pattern with LoginFilter is done via editing <filter> and <filter-mapping> tags in web.xml.
The syntax is:
<filter>
<filter-name>FILTER_NAME</filter-name>
<filter-class>org.web_auth.ui.servlet.LoginFilter</filter-class>
<init-param>
<param-name>UserSessionClass</param-name>
<param-value>SESSION_CLASS_NAME</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name> FILTER_NAME</filter-name>
<url-pattern>URL_PATTERN</url-pattern>
</filter-mapping>
FILTER_NAME |
The name of your filter. This can be an arbitrary name. |
SESSION_CLASS_NAME |
The name of the subclass of UserSession.java. See Create a Subclass of UserSession.java. |
URL_PATTERN |
The URL pattern used for restricting page accesses to this type of users. |
In the following example, all pages in the URL pattern of http://<servername>:<port>/<appname>/members/* require member to log in.
<filter>
<filter-name>MemberLoginFilter</filter-name>
<filter-class>org.web_auth.ui.servlet.LoginFilter</filter-class>
<init-param>
<param-name>UserSessionClass</param-name>
<param-value>application.MemberSession</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>MemberLoginFilter</filter-name>
<url-pattern>/members/*</url-pattern>
</filter-mapping>
Please add the following code to your web.xml. This adds UserSessionListener to your application. UserSessionListener invalidates a user session once the corresponding Http session is expired.
<listener>
<listener-class>
org.web_auth.ui.servlet.UserSessionListener
</listener-class>
</listener>
As discussed in section Login Pages, we need to create two jsp pages.
Firstly, declare the form bean.
<form-beans>
<form-bean name="loginForm" type="org.web_auth.ui.formbean.LoginForm"/>
</form-beans>
Secondly, declare the mapping for login.
<action-mappings>
<action path="URL_PATTERN/login"
type="org.web_auth.ui.action.LoginAction"
name="loginForm"
input="LOGIN_JSP "
parameter="UserClass=USER_CLASS_NAME;
UserSessionClass= SESSION_CLASS_NAME"
scope="request">
<forward name="success" path="LOGIN_SUCCESSFUL_JSP
"/>
<forward name="failure" path="LOGIN_JSP"/>
</action>
URL_PATTERN |
The URL pattern used for restricting page accesses to this type of users. |
LOGIN_JSP |
The jsp page that allows user to enter username and password, and displays detailed error messages when login is failed. |
USER_CLASS_NAME |
The name of the subclass of User.java. See Create a Subclass of User.java. |
SESSION_CLASS_NAME |
The name of the subclass of UserSession.java. See Create a Subclass of UserSession.java. |
LOGIN_SUCCESSFUL_JSP |
The jsp page to be displayed after the login is successful. |
Finally, declare the mapping for logout.
<action path="LOGOUT_URL"
type="org.web_auth.ui.action.LogoutAction"
parameter="UserSessionClass= SESSION_CLASS_NAME"
scope="request">
<forward name="success" path="PAGE_AFTER_LOGOUT"/>
</action>
LOGOUT_URL |
The URL for users to initiate the logout. |
SESSION_CLASS_NAME |
The name of the subclass of UserSession.java. See Create a Subclass of UserSession.java. |
PAGE_AFTER_LOGOUT |
The jsp page to be displayed after logout. |
In the following example, the login URL for members is /members/login.jsp or /members/login.do. If the login is successful, the user sees /members/home.jsp. Otherwise, /members/login.jsp is displayed again with detailed error messages. The action name of the form in /members/login.jsp must be /members/login.do.
The logout URL is /member_logout. After log out, user sees /index.jsp.
<form-beans>
<form-bean name="loginForm"
type="org.web_auth.ui.formbean.LoginForm"/>
</form-beans>
<action-mappings>
<action
path="/members/login"
type="org.web_auth.ui.action.LoginAction"
name="loginForm"
input="/members/login.jsp"
parameter="UserClass=application.Member;
UserSessionClass=application.MemberSession"
scope="request">
<forward name="success"
path="/members/home.jsp"/>
<forward name="failure"
path="/members/login.jsp"/>
</action>
<action
path="/member_logout"
type="org.web_auth.ui.action.LogoutAction"
parameter="UserSessionClass=application.MemberSession"
scope="request">
<forward name="success" path="/index.jsp"/>
</action>
As discussed in section Password-Change Pages, we need to create two jsp pages.
First, declare the form bean.
<form-beans>
<form-bean name="passwordChangeForm"
type="org.web_auth.ui.formbean.PasswordChangeForm"/>
</form-beans>
Then, declare the mapping for password change.
<action
path="URL_PATTERN/change_password"
type="org.web_auth.ui.action.PasswordChangeAction"
input="PASSWORD_CHANGE_JSP"
name="passwordChangeForm"
parameter="UserClass= USER_CLASS_NAME;
UserSessionClass=
SESSION_CLASS_NAME "
scope="request">
<forward name="failure" path="PASSWORD_CHANGE_JSP"
/>
<forward name="success" path="CHANGE_SUCCESSFUL_JSP
" />
</action>
URL_PATTERN |
The URL pattern used for restricting page accesses to this type of users. |
PASSWORD_CHANGE_JSP |
The jsp page that allows user to enter old and new password, and displays detailed error messages when change is failed. |
USER_CLASS_NAME |
The name of the subclass of User.java. See Create a Subclass of User.java. |
SESSION_CLASS_NAME |
The name of the subclass of UserSession.java. See Create a Subclass of UserSession.java. |
CHANGE_SUCCESSFUL_JSP |
The jsp page to be displayed after the change is successful. |
In the following example, the URL for members to change password is /members/change_password.jsp or /members/change_password.do. If the change is successful, the user sees /members/password_changed.jsp. Otherwise, /members/change_password.jsp is displayed with detailed error messages. The action name of the form in /members/change_password.jsp must be /members/change_password.do.
<form-beans>
<form-bean name="passwordChangeForm"
type="org.web_auth.ui.formbean.PasswordChangeForm"/>
</form-beans>
<action
path="/members/change_password"
type="org.web_auth.ui.action.PasswordChangeAction"
input="/members/change_password.jsp"
name="passwordChangeForm"
parameter="UserClass=application.Member;
UserSessionClass=application.MemberSession"
scope="request">
<forward name="failure"
path="/members/change_password.jsp" />
<forward name="success"
path="/members/password_changed.jsp" />
</action>
User management operations normally include adding users, removing users and modifying users. These operations are outside of the realm of WebAuth and hence are the responsibilities of applications. However, when a user is added, WebAuth needs to perform a corresponding database operation: insert. This is done via the User.add() call. When a user is removed, WebAuth needs to perform a corresponding database operation: delete. This is done via the User.remove() call. Please make sure that these calls are included when the subclasses of User.java add or remove objects to or from the database.
User.add() and User.remove() throw an application exception when the operation is failed. Please see JavaDoc about how to deal with the exception.
If your application uses MySQL, please follow the following steps.
dataSourceType=MysqlDataSource
url=JDBC_URL
username=DATABASE_USERNAME
password=DATABASE_PASSWORD
If your application uses Oracle, please follow the following steps.
dataSourceType=OracleDataSource
url=JDBC_URL
username=DATABASE_USERNAME
password=DATABASE_PASSWORD
WebAuth is released in the form of a jar file called web-auth-<version>.jar, where <version> is the version number of WebAuth. Your web application is normally bundled in a war file or an ear file.
The final steps are: