FullAjaxExceptionHandler does not redirect to error page after invalidated session
Asked Answered
A

1

3

I am having issues with the Omnifaces FullAjaxExceptionHandler (http://showcase.omnifaces.org/exceptionhandlers/FullAjaxExceptionHandler). It does not redirect to the specified error page after the session is invalidated.

I have the following in my faces-config:

<factory>
    <exception-handler-factory>org.omnifaces.exceptionhandler.FullAjaxExceptionHandlerFactory</exception-handler-factory>
</factory>

And the following in my web.xml:

<error-page>
    <exception-type>javax.faces.application.ViewExpiredException</exception-type>
    <location>/pages/error/viewExpired.html</location>
</error-page>

After I invalidate the session, from a user's perspective nothing seems to happen. The application is just 'dead'. In my console I see the following Ajax request:

  • A POST to the original facelet page with a response code of 302
  • a GET to the login page with a code 200 (but nothing happens because it's requested via Ajax)

I am running MyFaces 2.1.10, Primefaces 3.5, Primefaces Extension 0.6.3 & Omnifaces 1.4.1 on WebLogic 12c

Could anyone help me in the right direction? How do I get the FullAjaxExeptionHandler to work properly?

Thanks

Adequacy answered 16/4, 2013 at 7:14 Comment(0)
S
3

A POST to the original facelet page with a response code of 302

This is not right. A redirect on a JSF ajax request must have a response code of 200 with a special XML response with a <redirect> element with target URL in its url attribute.

This thus indicates that you manually used HttpServletResponse#sendRedirect() somewhere long before JSF has the chance to deal with ViewExpiredException.

Perhaps you've somewhere a servlet filter which checks some session attribute and sends a redirect based on its presence/state? That filter should then be manipulated based on the following answer: JSF Filter not redirecting After Initial Redirect in order to recognize JSF ajax requests and return a special XML response instead of a 302 response.

E.g.

if ("partial/ajax".equals(request.getHeader("Faces-Request"))) {
    response.setContentType("text/xml");
    response.getWriter()
        .append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>")
        .printf("<partial-response><redirect url=\"%s\"></redirect></partial-response>", loginURL);
} else {
    response.sendRedirect(loginURL);
}

This all is completely unrelated to the FullAjaxExceptionHandler. JSF didn't have any chance to throw a ViewExpiredException because you're already sending a redirect yourself beforehand.

Shortsighted answered 16/4, 2013 at 12:6 Comment(9)
Thanks for your answer. I am certain that I am not sending a redirect manually... Could this be a weblogic specific issue? And would it be possible to write my own filter with your implementation code to fix this?Adequacy
Yes, that would very well happen if you're using container managed authentication. I'm however not that familiar enough with Weblogic in order to propose the right solution; OmniFaces has a builtin solution in OmniPartialViewContext which should cover this specific case, however that only works when a forward is performed (as done by Tomcat, JBoss and Glassfish) instead of a redirect. As first step, explore all request attributes to see if WebLogic hasn't set some specific request attribute indicating that the container managed authentication has kicked in.Shortsighted
See also this related question: stackoverflow.com/questions/12504131/…Shortsighted
Yes we are using Container Managed Authentication. Does this mean I could not use the FullAjaxExceptionHandler? Would you be able to point me in a direction to get this to work without the use of your FullAjaxExceptionHandler? Thank you in advance!Adequacy
You need to understand that your particular problem is completely unrelated to FullAjaxExceptionHandler. It didn't even had the chance to run, because the container has redirected the restricted request to a login page upon session expiration. It would only work the way you expected if the request wasn't blocked by container managed authentication because the user was logged out due to session expiration.Shortsighted
So the only way is not to use container managed authentication?Adequacy
Depends on the concrete functional requirement. From the other way round, it can also just be that you're just looking in the wrong direction for the solution to the concrete problem. The FullAjaxExceptionHandler only intercepts on exceptions thrown during JSF ajax requests. In your particular case, there's no means of any exception. WebLogic has redirected the request to the login page because the user is not logged-in anymore. Even if you used normal request instead of ajax request, you would still not have gotten a ViewExpiredException and thus never hit the <error-page> at all.Shortsighted
I found a solution - the problem was in FullAjaxExceptionHandler I replaced the "renderErrorPageView" Method with ` String viewId = getViewIdAndPrepareParamsIfNecessary(context, errorPageLocation); ViewHandler viewHandler = context.getApplication().getViewHandler(); String actionURL = viewHandler.getRedirectURL(context, viewId, null, false); context.getExternalContext().redirect(actionURL);`Clyte
@Dan: You're sending a HTTP redirect instead of rendering the view. This is not conform standard servlet spec and does not work for error pages in /WEB-INF.Shortsighted

© 2022 - 2024 — McMap. All rights reserved.