This chapter discusses Best Practices for designing and building Apache Click applications.
For application security it is highly recommended that you use the
declarative JEE Servlet path role based security model. While Click pages
provide an onSecurityCheck()
method for rolling your own
programmatic security model, the declarative JEE model provides numerous
advantages.
These advantages include:
Its an industry standard pattern making development and maintenance easier.
Application servers generally provide numerous ways of integration with an organisations security infrastructure, including LDAP directories and relational databases.
Servlet security model support users bookmarking pages. When users go to access these pages later, the container will automatically authenticate them before allowing them to access the resource.
Using this security model you can keep your Page code free of security concerns. This makes you code more reusable, or at least easier to write.
If your application has very fine grained or complex security requirements you may need to combine both the JEE declarative security model and a programmatic security model to meet your needs. In these cases its recommended you use declarative security for course grained access and programmatic security for finner grained access control.
The declarative JEE Servlet security model requires users to be authenticated and in the right roles before they can access secure resources. Relative to many of the JEE specifications the Servlet security model is surprisingly simple.
For example to secure admin pages, you add a security
constraint in your web.xml
file. This requires users
to be in the admin
role before they can access to any
resources under the admin directory:
<security-constraint>
<web-resource-collection>
<web-resource-name>admin</web-resource-name>
<url-pattern>/admin/*</url-pattern>
</web-resource-collection>
<auth-constraint>
<role-name>admin
</role-name>
</auth-constraint>
</security-constraint>
The application user roles are defined in the web.xml
file as security-role
elements:
<security-role>
<role-name>admin
</role-name>
</security-role>
The Servlet security model supports three different authentication method:
BASIC
- only recommended for internal
applications where security is not important. This is the easiest
authentication method, which simply displays a dialog box to users
requiring them to authenticate before accessing secure resources.
The BASIC method is relatively insecure as the username and password
are posted to the server as a Base64 encoded string.
DIGEST
- recommended for internal applications
with a moderate level of security. As with BASIC authentication,
this method simply displays a dialog box to users requiring them to
authenticate before accessing secure resources. Not all application
servers support DIGEST authentication, with only more recent
versions of Apache Tomcat supporting this method.
FORM
- recommended applications for where
you need a customised login page. For applications requiring a high
level of security it is recommended that you use the FORM method
over HTTPS.
The authentication method is specified in the <login-method> element. For example to use the BASIC authentication method you would specify:
<login-config>
<auth-method>BASIC
</auth-method>
<realm-name>Admin Realm</realm-name>
</login-config>
To use the FORM method you also need to specify the path to the login page and the login error page:
<login-config>
<auth-method>FORM
</auth-method>
<realm-name>Secure Realm</realm-name>
<form-login-config>
<form-login-page>/login.htm</form-login-page>
<form-error-page>/login.htm?auth-error=true</form-error-page>
</form-login-config>
</login-config>
In your Click login.htm
page you need to include a
special j_security_check
form which includes the input
fields j_username
and j_password
.
For example:
#if ($request.getParameter("auth-error")) <div style="margin-bottom:1em;margin-top:1em;color:red;"> Invalid User Name or Password, please try again.<br/> Please ensure Caps Lock is off. </div> #end <form method="POST" action="j_security_check
" name="form"> <table border="0" style="margin-left:0.25em;"> <tr> <td><label>User Name</label><font color="red">*</font></td> <td><input type="text" name="j_username
" maxlength="20" style="width:150px;"/></td> <td> </td> </tr> <tr> <td><label>User Password</label><font color="red">*</font></td> <td><input type="password" name="j_password
" maxlength="20" style="width:150px;"/></td> <td><input type="image" src="$context/images/login.png" title="Click to Login"/></td> </tr> </table> </form> <script type="text/javascript"> document.form.j_username.focus(); </script>
When using FORM based authentication do NOT put application logic in a Click Login Page class, as the role of this page is to simply render the login form. If you attempt to put navigation logic in your Login Page class, the JEE Container may simply ignore it or throw errors.
Putting this all together below is a web.xml
snippet which features security constraints for pages under the admin
path and the user path. This configuration uses the FORM method for
authentication, and will also redirect unauthorized (403) requests to the
/not-authorized.htm
page.
<web-app> .. <error-page> <error-code>403</error-code> <location>/not-authorized.htm
</location> </error-page> <security-constraint> <web-resource-collection> <web-resource-name>admin</web-resource-name> <url-pattern>/admin/*
</url-pattern> </web-resource-collection> <auth-constraint> <role-name>admin</role-name> </auth-constraint> </security-constraint> <security-constraint> <web-resource-collection> <web-resource-name>user</web-resource-name> <url-pattern>/user/*
</url-pattern> </web-resource-collection> <auth-constraint> <role-name>admin</role-name> <role-name>user</role-name> </auth-constraint> </security-constraint> <login-config> <auth-method>FORM
</auth-method> <realm-name>Secure Zone</realm-name> <form-login-config> <form-login-page>/login.htm
</form-login-page> <form-error-page>/login.htm?auth-error=true
</form-error-page> </form-login-config> </login-config> <security-role> <role-name>admin</role-name> </security-role> <security-role> <role-name>user</role-name> </security-role> </web-app>
There are also alternative security solutions that provide extra
features not available in JEE, such as RememberMe functionality, better
resource mapping and Post Logon Page
support.
(Post Logon Page
support allows one to specify a default
URL where the user will be forwarded after successful login. This feature
allows one to embed a login form in all non-secure pages and after successful
authentication the user will be forwarded to their home page.)
Below are some of the alternative security solutions available:
For more information on using security see the resources below:
Form Based Authentication by Louis E. Mauget
Servlet Specification by Sun Microsystems