Cocoon AuthenticationThe Cocoon Authentication FrameworkA short introduction by Carsten Ziegeler (Cocoon release manager and active committer) IntroductionThis short tutorial is a brief introduction to the Cocoon authentication framework. It conforms to the current development version of Cocoon, 2.1-dev which you can get via CVS. For more information on how to obtain this version of Cocoon, have a look here. The authentication framework is a donation of my current employee, the S&N AG, Germany and was developed for our e-integration platform sunShine. The original name of the authentication framework is sunRise. First stepsSo, if you don't have the current CVS version of Cocoon, check it out first, before we can proceed. Everything will be explained by looking at the portal demo contained in Cocoon. After you have checked out Cocoon, build it and start it with your favorite servlet engine. If you experience any problems, have a look at the provided document and in the mailing lists. Once you started Cocoon, you will get the welcome page, there you will find a link to the portal demo. Try it out! Next, make yourself comfortable with the basic Cocoon concepts, like the sitemap, the processing pipelines, generators, transformers, serializers or actions. You can use the Cocoon documentation or ... our book for more information. ConceptsThe basic concept of the authentication framework is to protect documents generated by Cocoon. A document is protected by a so called (authentication) handler. A document is associated to a defined handler to be protected. A user can only request this document if he is authenticated against this handler. A handler can be used to protect several documents in the same way. If a user is authenticated he can access all these documents. It is possible to use different handlers, to product documents in different ways. A handler has two required configurations:
The flow for accessing documents can be described as follows:
So let's have a look at the configuration. ConfigurationThe handler configuration is a so-called component configuration for the authentication manager:
<map:sitemap>
...component definitions...
<map:pipelines>
<map:component-configurations>
<authentication-manager>
<handlers>
<handler name="portalhandler">
<redirect-to uri="cocoon:/sunspotdemoportal"/>
<authentication uri="cocoon:raw:/sunrise-authuser"/>
</handler>
</handlers>
</authentication-manager>
</map:component-configurations>
<map:pipeline>
... document pipelines following here:
You can see by the above example how a handler is defined in the sitemap. Both, the redirect-to document and the authentication resource use a special protocol, the cocoon protocol. In this case, this protocol points to pipeline definitions in the same sitemap as the handler is defined. So, if a user requests a procteced document, he is redirected to a Cocoon pipeline matching 'sunspotdemoportal' etc. In fact, you will find this sitemap in the webapps/samples/portal directory. If you look in the pipelines section, you will find the definitions for those two pipelines there. For advanced users: the handler definitions are inherited from a parent sitemap to a sub sitemap, so you can use in a sub sitemap all handlers defined in its parent sitemaps and those defined only in this sub sitemap. But of course you cannot use a handler defined in a sub sitemap in a parent sitemap. ProtectingSo, how can a document be protected? This can be done by a Cocoon action, the auth-protect action:
...
<map:match pattern="sunspotdemo**">
<map:act type="auth-protect">
<map:parameter name="handler" value="portalhandler"/>
...
<map:match pattern="sunspotdemo-conf">
<map:generate type="portal-conf"/>
<map:transform src="styles/portalconfHTML.xsl"/>
<map:transform type="encodeURL"/>
<map:serialize/>
</map:match>
</map:act>
</map:match>
...
So a document is associated with an authentication handler by using the 'auth-protect' action and the handler parameter. Now, if this document is requested, the action checks if the user is authenticated. If not, the action automatically redirects to the redirect-to document of the handler. If the user is authenticated, the commands inside the map:act will be execute and the user gets the document itself. For advanced users: The portal demo uses the 'encodeURL' transformer as you can see in the example above. This transformer automatically performs url rewriting for session handling, if no cookies are used. The Login ProcessUsually, the redirect-to document of a handler contains a form for the user to authenticate. But of course, you are not limited to this, you can call any pipeline. In the case of the portal demo, the user is presented with the welcome page of the portal containing a login form. When the user submits the values of the form, the are processed by a Cocoon pipeline. To authenticate a user, the 'auth-login' action helps. Put this action in the pipeline handling the submitted form values:
...
<map:match pattern="sunspotdemofree-auth">
<map:act type="auth-login">
<map:parameter name="handler" value="portalhandler"/>
<map:parameter name="parameter_name" value="{request:name}"/>
<map:parameter name="parameter_password" value="{request:password}"/>
<map:redirect-to uri="sunspotdemo-portal"/>
</map:act>
<map:generate src="resources/free/auth.xml"/>
<map:transform src="styles/TO-html.xsl"/>
<map:transform type="encodeURL"/>
<map:serialize/>
</map:match>
...
The 'auth-login' action gets the handler as a parameter. In addition a custom set of parameters can be passed to the action by using a parameter starting with the prefix 'parameter_'. These parameters are then passed on to the authentication resource of the handler configuration. So in the example above two parameters are passed on: name and password. The value for these parameters comes from the request, or more precisly from the two request parameters called name and password. These are the values of the two input fields of the form submitted by the user. (Please notice, that we use the so called InputModules here to get the values of the two request parameters.) Now the 'auth-login' action calls the authentication resource and passes on the parameters. In the case of the portal this is a usual pipeline. If the user is authenticated successfully, this pipeline must return valid XML conforming to this schema:
<authentication>
<ID>Unique ID of the user in the system</ID>
<role>The optional user role</role>
<data>
Any additional optional information can be supplied here.
This will be stored in the session for later retrieval
</data>
</authentication>
The XML is very simply, only the root element 'authentication' and the 'ID' element with a valid unique ID for the user in this handler is required. Everything else is optional. If the user cannot be authenticated, the resource can deliver any other XML. For advanced users: In this case, the authentication resource can deliver error messages which could then be used to display the case of error, for example password not correct etc. The Cocoon documentation contains more information on this. If the authentication is successfull, the statements inside the 'auth-login' action are executed. So in the example above, this means a redirect to the portal view is performaed. If the authentication is not successful, everything inside the map:act tag is skipped. So in the example above, the pipeline starting with the generator is executed. The displayed document shows a message that the login process was not successful and the user can try it again. So, this is everything for a short introduction. What I didn't explain is the authentication resource. You can either look at it yourself - it reads an XML file and uses a stylesheet to compare the incomming parameters with the users listed in the XML document - or you can look at Matthews introduction to sunRise (which is not that upto-date but still valid for the authentication resource!). FlexibilityAs you can see by this short introduction, the user management of the authentication framework is very flexible. You can design your application without taking into account, which backend is used for the user management. This can be the file-system, a SQL database, an XML database, a LDAP directory, just anything. Simply by developing the authentication resource, you can connect to any system. And another advantage is the flexible switching between user databases. You can for example use the file-system for the development process and switch than later on to a LDAP system on the production system. This can be done by simply changing the authentication resource. If you test this resource on your production system, you don't have to test your whole application again. (Also this is in general a good idea...). And now...This tutorial showed you some basics of the Cocoon authentication mechanism. You can have a look at the Cocoon documentation for more infos. The authentication framework offers more like support for building configurable web applications, for example portals. I will put up another tutorial about the Cocoon portal framework in the next days, so stay tuned. |