EQUIP2 WebApp Login and Interceptors

Chris Greenhalgh, 2007-02-02

Introduction

The Spring Web MVC framework, in addition to Controllers, also has allows "Handler Interceptors" to be specified, which have a chance to run before and after each request. These can be used to do various run-time checks, and also provide a means to implement web-site log and tracking through session state.

Standard EQUIP2 interceptor

The equip2webdb JAR includes an EQUIP2 interceptor class, equip2.spring.EquipSessionReleaseInterceptor, which should normally be inserted into the handler chain of any requests which will access the EQUIP2 dataspace. The postHandle method of this interceptor, run at the end of the request, ensures that any dataspace session is closed and the session released. Otherwise, if a session is left open (e.g. by a particular code path or due to an exception) then access to the dataspace will be blocked until the session times out (~30 seconds).

The interceptor is specified to the URL mapper, e.g.:

  <bean id="urlMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
<property name="interceptors">
<list>
<ref bean="equipSessionReleaseInterceptor"/>
</list>
</property>
<property name="mappings">
....
An instance of this interceptor is defined in the standard EQUIP2 portion of applicationContext.xml.

Login example

The 'login' servlet, configured by WEB-INF/login-servlet.xml, gives a pretty typical example of using an interceptor with supporting controllers to implement a set of pages which are only accessible after logging in.

The controller, equip2.webapptutorial.login.CheckLoginInterceptor, checks in the HTTP session for a named attribute (this is configurable, in this case it looks for 'loginSessionBean'. If an attribute of that name is not found in the current request's sesison then the controller sends a redirect to the client, which will normally redirect it to the login page.

Logging in is supported by the controller equip2.webapptutorial.login.LoginFormController, which uses the JSP form login/login_form.jsp
which in turn is backed by an instance of class equip2.webapptutorial.login.LoginBean - this has properties for the user id and password. The URL for this is http://.../login/login.html

When the form is submitted, the login form controller delegates to a method 'checkPassword' to see if the user id and password are accepted; this should be over-riden to implement an actual authentication check suitable to the application - this example accepts any (non-zero length) user name and any password. If the user id/password is accepted then the login controller creates an instance of class equip2.webapptutorial.login.LoginSessionBean, fills in the userId, and adds it to the session as an attribute (again, the attribute name is configurable, and should match that configured for the login interceptor):

	// OK!
LoginSessionBean lsb = new LoginSessionBean();
lsb.setUserId(loginBean.getUserId());
session.setAttribute(sessionAttributeName, lsb);

Logging out is supported by the simple controller equip2.webapptutorial.login.LogoutController, which simply removes the configured attribute from the session.

Note that session tracking in J2EE is typically performed using cookies. If a browser's security settings are such that it will not accept the cookie then the session tracking will fail, and the user will be unable to log in. This can be diagnosed with the example page/controller arrangement because the login controller will authenticate them, and return the success view (presumably a secure page) correctly. However, as soon as they request another secure page the login interceptor will again redirect them to the login page. A more complex arrangement of interceptors and redirect on login would allow a site to diagnose this problem and give the user appropriate feedback (redirect on successful login to a secure welcome page with an interceptor which on failure redirects to a diagnostic/help page rather than the normal log in page).

Operator pages and HTTP Basic Authentication

It is also possible to configure a J2EE web application to use HTTP Basic Authentication for some URLs; we have often done this for author/admin/operator areas. The mapping of URL paths to security roles is specified in the web application's web.xml file, e.g. as in the example:
  <security-constraint>
<display-name>EQUIP2 Operator login</display-name>
<web-resource-collection>
<web-resource-name>Operator Area</web-resource-name>
<!-- remove comments to require basic authentication -->
<!-- <url-pattern>/db/*</url-pattern> -->
</web-resource-collection>
<auth-constraint>
<role-name>operator</role-name>
</auth-constraint>
</security-constraint>

<login-config>
<auth-method>BASIC</auth-method>
<realm-name>EQUIP2 Operator Application</realm-name>
</login-config>

<security-role>
<role-name>operator</role-name>
</security-role>

Note, however, that basic authentication is performed by the container (i.e. Tomcat) rather than by the application. Consequently the container needs to know how to authenticate users, and be able to access the application database (or whatever) as appropriate.

The simplest case is to add static usernames, roles and passwords to (in the case of Tomcat) the conf/tomcat-users.xml file in the Tomcat installation directory. Refer to the Tomcat documentation if you want to do more than this.

Changes

2007-02-02