Chris Greenhalgh, 2007-02-02
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.
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">An instance of this interceptor is defined in the standard EQUIP2 portion of applicationContext.xml.
<property name="interceptors">
<list>
<ref bean="equipSessionReleaseInterceptor"/>
</list>
</property>
<property name="mappings">
....
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.
<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.