Chapter 6. Best Practices

6.1. Security
6.1.1. Declarative Security
6.1.2. Alternative Security solutions
6.1.3. Resources
6.2. Packages and Classes
6.2.1. Page Classes
6.3. Page Auto Mapping
6.4. Navigation
6.5. Templating
6.6. Menus
6.7. Logging
6.8. Error Handling
6.9. Performance

This chapter discusses Best Practices for designing and building Apache Click applications.

6.1. Security

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.

6.1.1. Declarative Security

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>&nbsp;</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>

6.1.2. Alternative Security solutions

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:

6.1.3. Resources

For more information on using security see the resources below: