Form based authentification using Facelets
Yesterday I found out how to configure my JEE Web Application with form-based login. In general it is not difficulty to secure a JEE Web Application with form based login. This is explained on lot of websites like this one: http://www.developinjava.com/readarticle.php?article_id=6
The problem I stumbled into was that my Web Application uses the facelets framework. So I have a lot of general layout parts like css and images which I wanted to use also in my Login Form and also some help pages which should be accessible without authentification.
To divide the web application into a restricted and a public area (where no authentification is needed) is easy:
in the web.xml you can specify the secured JSP pages separated in a folder e.g:
<security-constraint>
<web-resource-collection>
<web-resource-name>restricted</web-resource-name>
<url-pattern>/faces/pages/*</url-pattern>
<http-method>GET</http-method>
<http-method>POST</http-method>
</web-resource-collection>
<auth-constraint>
<role-name>org.imixs.ACCESSLEVEL.AUTHORACCESS</role-name>
</auth-constraint>
</security-constraint>
The Login.xhtml which I placed outside my secured /pages folder makes use of facelets technology and looks as followed:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html
xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:z="http://www.qualcomm.com/jsf/core"
xmlns:c="http://java.sun.com/jstl/core"
xmlns:fn="http://java.sun.com/jsp/jstl/functions">
<ui:composition template="/layout/layout.xhtml">
<ui:define name="content">
<form
method="post"
action="#{facesContext.externalContext.requestContextPath}/j_security_check">
<table>
<tr>
<td>User name:</td>
<td><input type="text" name="j_username" /></td>
</tr>
<tr>
<td>Password:</td>
<td><input type="password" name="j_password" /></td>
</tr>
<tr>
<td><input type="submit" value="Login" /></td>
</tr>
</table>
</form>
</ui:define>
</ui:composition>
</html>
/layout/layout.xhtml is accessible without authentification as this page is not placed inside my secured /pages/ folder. So the login.xhtml page looks perfect styled!
The real problem was how to jump into a secured page? I first have had a navigation.jsp page with a lot of jsf command links like:
<h:commandLink actionListener="#{workitemListBean.doRefresh}"
action="show_workitemlist">
My Navigation rule for "show_workitemlist" points to a secured page in the /pages folder.
faces-config.xml:
......
<navigation-case>
<from-outcome>show_worklist</from-outcome>
<to-view-id>/pages/workflow/worklist.jsp</to-view-id>
</navigation-case>
But these commandLinks will not work because the JSF Framework will invoke all backing beans which are connected to the target page behind the navigation rule "show_workitmelist". And all my backing beans invoke a lot of EJBs which are secured using declarative JEE security.
So my command link did not show up the login.xhtml form as expected but throws a lot of "permission denied" exceptions :-(
The trick is to forward the anonymous user direct to the faces/ URL to access the secured page without JSF Navigation Rules. So I replaced my <h:commandLink> with a simple anchor tag:
<a href="#{facesContext.externalContext.requestContextPath}/faces/pages/workflow/worklist.jsp">
<h:outputText value="#{global.login}" /></a>
So the result of these anchor tag is that the non authenticated user requests a secured page from my /faces/pages URL Pattern as defined in the web.xml.
The webContainer will invoke my Login Page, authenticate the user and after a successful login the JSF Framework starts up and builds all the necessary things to view the page with all backing-beans and EJBs. As the user is now authenticated everything works perfect as JSF has all the principal stuff and user informations to invoke my secured EJBs!
So: do not use commandLinks to login an anonymous user in a JSF Application inside a Facelets layouted login page.
Posted at 08:19PM Jun 18, 2008
Posted by: Ralph
Category: General