Authentication and Authorisation by the servlet container

The document describes how to let the servlet container handle webapp security. There are two parts to security that we consider here:

You can handle this manually by creating a login form and then using Actions in the sitemap to check if the user is logged in. Better yet, there's a framework to do this in Cocoon described here.

Doing the authorisation in the sitemap gives more flexibility regarding what parts of the pipeline should be protected compared to using the security features of the servlet container. However, in many cases what the servlet container offers may be more than enough and is easier and quicker to set up (in my opinion, of course).

In this document we will describe how to set up servlet security for Tomcat 4.

First of all, you need to configure a realm in Tomcat's server.xml. How this can be done is described here.

Basically this involves three things:

But all this is described in the document referenced before.

The next step is to edit Cocoon's web.xml (usually found in $TOMCAT_HOME/webapps/cocoon/WEB-INF/web.xml), and add something like shown below near the bottom of the file (before the closing </webapp> tag -- consult the web.xml DTD if unsure).

{{{<security-constraint>

</security-constraint>

<login-config>

</login-config>}}}

The url-pattern element describes all the resources to be protected. This should start with a slash and end with '/*'. The path is relative to the context path on which the webapp is mounted. You can not use more complex expressions like in Cocoon's matchers. You can however use multiple url-pattern elements. It could also specify a single resource, by not ending the path on '/*'.

The login-config element describes how the login should happen. In the example above we have used form-based login, which requires us to create login pages. An alternative is basic authentication, in which case the browser will show a popup window asking for your credentials.

To use basic authentication, replace the login-config element from the above example with this: {{{<login-config>

</login-config>}}}

Note also that form-based login requires (creates) a session, and will thus always be a little heavier on the server. It will also require cookies to be enabled in users' browsers to keep track of the session.

In case you have chosen to use basic authentication, your work ends here. Restart tomcat and try to access a protected URL. It should ask your user name and password.

In case you have chosen to use form-based login, you need to create the login pages. These will be generated by Cocoon pipelines. To keep it simple, here we'll use static HTML files. Create two files in $TOMCAT_HOME/webapps/cocoon as follows:

login.html {{{<html>

</html>}}}

loginfailed.html {{{<html>

</html>}}}

The special resource "j_security_check" used in the action attribute of the form is a special resource recognized by Tomcat. It is not needed to create a matcher for that one in the sitemap.

Now, we need to add matchers to the sitemap for the login pages. It is recommended to place the login pages themselves outside the protected area, because if the page references images which are also in the protected area, you will get into troubles. This is because (1) the images themselves cannot be accessed if they are in the protected area and (2) after login, Tomcat will redirect you to the last requested protected URL which will in that case be the image.

Here is an example sitemap snippet:

{{{<map:match pattern="login">

</map:match>

<map:match pattern="loginfailed">

</map:match>}}}

The patterns of the matchers should of course correspond to what you configured in the web.xml in the elements form-login-page and form-error-page.

Now you are ready to try it out. Restart Tomcat and try accessing a protected resource, and you will get the login form.

A last problem now remains: how to log out?

In case of basic authentication, the user needs to close its browser window.

In case of form-based authentication, you can invalidate the session to log out. This can be done with a pipeline like this.

{{{<map:match pattern="logout">

</map:match>}}}

In this case, you would place a link to "/logout?goto=somewhere" which would logout the user and redirect him or her to page "somewhere".

Note that the "session-invalidate" action used above ships with Cocoon (2.03) but is not declared by default in the sitemap. Therefore, add this in the map:actions section of the sitemap:

{{{<map:action

If you get the error "Invalid direct reference to form login page"

If you are getting this error, it usually means that either:

AuthWithTomcat (last edited 2009-09-20 23:42:34 by localhost)