Saturday, March 8, 2008

More on How to make Acegi work on Sun Application Server 8.x?

Applying the solution mentioned in my previous post IMHO: How to make Acegi work on Sun Application Server 8.x? has been proved working quite well. Well, until I encountered the same ClassCastException again. This time it was because the access was denied. Looking into the stack trace, I found that it was because Acegi's AccessDeniedHandlerImpl forwards the SecurityContextHolderAwareRequestWrapper to show the error page.

Similar to the solution in the previous post, I creates a NullPrincipalAccessDeniedHandlerImpl, which extends Acegi's AccessDeniedHandlerImpl but wrap the HttpServletRequest with the NullPrincipalHttpServletRequestWrapper.

Following is the source code of NullPrincipalAccessDeniedHandlerImpl:



import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;

import org.acegisecurity.AccessDeniedException;
import org.acegisecurity.ui.AccessDeniedHandlerImpl;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;


* An Acegi AccessDeniedHandler implementation designed specific to get around
* the bug in Sun Application Server 8.x where a custom security framework's
* implementation of Principal is casted to Sun Application Server's own
* implementation.
* @author Alex
* @version 1.0
public class NullPrincipalAccessDeniedHandlerImpl extends
AccessDeniedHandlerImpl {

private static final Log log =

* Default no-arg constructor.
public NullPrincipalAccessDeniedHandlerImpl() {

public void handle(ServletRequest aRequest, ServletResponse aResponse,
AccessDeniedException aAccessDeniedException) throws IOException,
ServletException {

super.handle(new NullPrincipalHttpServletRequestWrapper(
(HttpServletRequest)aRequest), aResponse, aAccessDeniedException);


Of course, the Spring application context must be changed to replace the original AccessDeniedHandler implementation with this in the definition of the exceptionTranslationFilter bean:
<bean id="exceptionTranslationFilter"
<property name="authenticationEntryPoint">
<ref local="authenticationProcessingFilterEntryPoint"/>

<property name="accessDeniedHandler">
<bean class="">
<property name="errorPage" value="/faces/ForbiddenAccess.jsp"/>


Now it works even if user's access to a protected URL is denied by Acegi.