Acegi security is a natural choice for many enterprise applications built using the Spring framework. JSF (JavaServer Faces) is a Java-based Web application framework that facilitates rapid application development by assembling reusable UI components. As you will learn in this article, it is not hard to secure your JSF applications with Acegi. In fact, you can address most details of authentication and authorization in a Spring application context file.
I'll present a simple Web application example based on the Apache MyFaces JSF implementation. I'll then show you how to use the Spring application context to integrate Acegi's authentication and authorization functionality into the JSF application. You'll see how to implement Acegi's URL-level role-based authorization, and you'll also learn how to implement Acegi's business-layer security using Java 5 annotations.
Note that this article is intended for Java developers already familiar with JavaServer Faces, Acegi, and Spring-based application development. You will be introduced to securing JSF applications with Acegi.
The sample application used for this discussion presents a login page to the user. If the user attempts to log in with the
correct user name and password, he is redirected to a page where he may make a purchase. We will use the Acegi security framework
to configure the security details that ensure the user's ID has been authenticated, and that his presence on the purchase
page is authorized. The user can visit the purchase page if has the role ROLE_URLACCESS. But making a purchase is a secure business method, so the user will only be able to access the purchase page if he has the
role ROLE_ALLACCESS.
The application utilizes Acegi's support for Java 5 security annotations, so Java 5 is a pre-requisite for following the example.
You will need the JAR files of Acegi, MyFaces, and Spring in your WEB-INF/lib folder if you want to run the application.
Now let us see how we go about configuring the Spring application context to integrate Acegi and JSF.
Before attempting to integrate Acegi with JSF, it is important to understand how Acegi works in the Web layer. Acegi uses servlet filters for authentication and authorization. The filters can be chosen and configured in the order in which they need to be executed. The appropriate filter fetches authentication request information such as username and password, and passes this information to Acegi's authentication manager, which is configured as a Spring bean.
The authentication manager contacts an authentication provider to get a UserDetails object from a UserDetailsService. If authentication is successful, the user's granted authorities (application-wide permissions) are populated in the returned
UserDetails object. This information is used to build the authentication object, which is then stored in Acegi's security context (which
is created by yet another filter). The security context is associated with the current execution thread by the security context
holder. The security context is stored as a session attribute and used for authorization checks by Acegi in the Web layer.
I assume you are familiar with basic JSF application development, and so will not describe the steps involved in configuring
a JSF application, such as defining the JSF servlet and providing the servlet mapping. I also assume, for the sake of this
example, that we have already registered a ContextLoaderListener to load the Spring application context when the application starts up. Download the sample application code for details.
Assuming that the above configurations are complete, the first step toward integrating Acegi with JSF is to configure Acegi's filters and direct all requests and forwards to be routed through them.
Instead of registering all the Acegi filters individually in web.xml, you can use Acegi's security filter chain proxy. The
Acegi filter chain invokes the filters added to its property list in the Spring context file. Acegi's FilterToBeanProxy class implements the javax.servlet.Filter interface; hence its doFilter() method is invoked by the servlet container when the request for a JSF page is received. This object delegates filter requests
to a Spring-managed bean of type FilterChainProxy that is defined in the Spring bean context.
The configuration in web.xml is as shown in Listing 1.
<filter>
<filter-name>Acegi Filter Chain Proxy</filter-name>
<filter-class>
org.acegisecurity.util.FilterToBeanProxy
</filter-class>
<init-param>
<param-name>targetClass</param-name>
<param-value>
org.acegisecurity.util.FilterChainProxy
</param-value>
</init-param>
</filter>
The mapping in Listing 2 causes the requests and forwards to be routed through Acegi's filter chain proxy.
<filter-mapping>
<filter-name>Acegi Filter Chain Proxy</filter-name>
<url-pattern>/*</url-pattern>
<dispatcher>FORWARD</dispatcher>
<dispatcher>REQUEST</dispatcher>
</filter-mapping>
| Subject |
|
|
Getting j_acegi_logout is not available errorBy Anonymous on December 17, 2009, 3:02 amIn my application while logging out i get j_acegi_logout is not available error. Can anybody help with this.
Reply | Read entire comment
not workingBy Anonymous on October 1, 2009, 7:51 amits gettin error NoSuchMethod:javax.servlet.jsp.JspFactory
Reply | Read entire comment
wdBy Anonymous on September 3, 2009, 2:26 pmawd
Reply | Read entire comment
WrongBy Anonymous on June 10, 2009, 12:05 pmYikes. Did you not read Bilal Siddiqui's article developerWorks? Pay attention next time.
Reply | Read entire comment
Integration with JSF, Using a JSF Login PageBy Anonymous on October 9, 2008, 8:41 pmLots of people seem to be struggling with creating a pure JSF login page (with validation and full functionality.) I've come up with a solution that takes 5 lines...
Reply | Read entire comment
View all comments