April 16, 2008

JSF & Security

This article introduces a Java module which utilizes phase listeners for securing JSF applications.

Feature list:
  • user, password and role based
  • interfaces throughout for independence of concrete implementations
  • easy to integrate into a Spring framework environment
  • supports password and cookie encoding
  • login data can be placed in cookies for automatic user logins
  • a special navigation handler ensures that invalid navigation rules do not open security holes
  • users may be allowed to login to multiple sessions or not

Introduction

The security core is independent of JSF. Thus, it could be used for other view technologies as well as for any view-independent access control. This affects all classes for authentication, authorization, access rules and cryptography.

How does it work ?

We have identities, usually representing application users. Identities are grouped by assigning roles. Access rules define which roles
are required to path through to certain views.
The authenticator is responsible for identifying users, whereas guards process authorization requests and either approve or refuse them.

Guards do not know whether access requests represent web sites or anything else. They just follow their given rules to make decisions.
Thus, other implementations of Guard and Rule are possible, for example to secure single UI components.

The following two classes allow the integration of the security core into JSF:
  • SecurityListener is a phase listener working in the RESTORE_VIEW phase
  • the LoginService is responsible for logins, cookies and creating identities respectively user objects

For denied requests two cases must be distinguished:
  1. The user is not logged in. If so, the loginRequiredNavigation of LoginService returns the new navigation.
  2. The user was logged in or can be logged in automatically. Then,
    • the Guard delivered the violated rule, its errorView is taken as navigation target
    • property defaultErrorNavigation of LoginService represents the fallback for rules without error view

In either case, if no valid target can be obtained or any exception raises, a 403-HTTP error is sent.


Configuration

Sample Spring configuration:




The default navigation handler of JSF is ignorant of invalid navigation rules. Non-existing rule outcomes result in no navigation at all, meaning that view requests which have just been denied, would pass through nevertheless.
The AssertingNavigationHandler takes care of this problem: an InvalidNavigationRuleException is thrown in case of an unknown or maybe just misspelled navigation directive.
<navigation-handler>
   de.voodoosoft.jroots.ui.jsf.core.AssertingNavigationHandler
</navigation-handler>   
(faces-config.xml)

To be able to configure the SecurityListener as Spring bean, the following listener delegate must be installed:
<lifecycle>
   <phase-listener>
      de.voodoosoft.jroots.ui.jsf.core.DelegatingPhaseListenerMulticaster
   </phase-listener>
</lifecycle>
(faces-config.xml)

The DelegatingPhaseListenerMulticaster automatically searches Spring's application context for registered phase listeners like this:
<bean id="securityListener"
   class="de.voodoosoft.jroots.ui.jsf.security.SecurityListener">
   <property name="loginService" ref ="loginService"></property>
   <property name="guard" ref="guard"/>  
   <property name="defaultErrorNavigation" value="login"></property>
</bean>

Download and Example

The complete package jroots-jsf-security.zip with a full working example (folder /examples/example4) and sample Spring configurations can be downloaded here: JRoots Application Bricks

2 comments:

  1. I found this site using [url=http://google.com]google.com[/url] And i want to thank you for your work. You have done really very good site. Great work, great site! Thank you!

    Sorry for offtopic

    ReplyDelete