0


We have a JSF 2.0, Primefaces 5.0, Spring Security 3.2.3.RELEASE application.
To handle session timeout, I am using primefaces idleMonitor and p:dialog & javascript to display a countdown popup and redirect them back to login page.
I have also implemented a custom CacheControlPhaseListener so that the pages are not cached. I set the no-cache in the response headers in the CacheControlPhaseListener.

<lifecycle><phase-listener id="nocache">com..filter.CacheControlPhaseListener</phase-listener></lifecycle>

I also have error handling configured in my web.xml:

 <error-page>
    <exception-type>javax.faces.application.ViewExpiredException</exception-type>
    <location>/error.jsf</location></error-page>

I have also implemented a ViewExpiredHandler that extends ViewHandlerWrapper

@Override
public UIViewRoot restoreView(FacesContext ctx, String viewId)
{
    UIViewRoot viewRoot = super.restoreView(ctx, viewId);
    try
    {
        if (viewRoot == null)
        {
            viewRoot = super.createView(ctx, viewId);
            ctx.setViewRoot(viewRoot);
        }
    }
    catch (Exception e)
    {
        e.printStackTrace();
    }
    return viewRoot;
}

The problem I am still having is:
1. When the session expires on a idle page (E.g. Search page) and if some ajax action is triggered on a page, even though I logout, when I navigate back to the page (e.g. Login-> Home-> Search page). I see a partial-response xml error:

<partial-response><changes><update id="blGridId"><table id="blGridId" style="width:100%;"> <tbody> <tr> <td><div id="blTableId" class="ui-datatable ui-widget ui-datatable-scrollable ui-datatable-resizable"><div id="sublTableId_paginator_top" class="ui-paginator ui-paginator-top ui-widget-header ui-corner-top" role="navigation"><span class="ui-paginator-prev ui-state-default ui-corner-all ui-state-disabled"><span class="ui-icon ui-icon-seek-prev">p</span></span><span class="ui-paginator-next ui-state-default ui-corner-all ui-state-disabled"><span class="ui-icon ui-icon-seek-next">p</span></span></div><div class="ui-widget-header ui-datatable-scrollable-header"><div class="ui-datatable-scrollable-header-box"><table role="grid"><thead id="blTableId_head"><tr role="row"><th id="blTableId:j_idt101" class="ui-state-default ui-resizable-column" role="columnheader" style="width:34px; #width:37px;"><span class="ui-column-title"><span style="word-wrap: break-word;white-space: normal;">Client </span></span></th><th id="blTableId:j_idt104" class="ui-state-default


2. If I hit a browser refresh, it loads back the page and I can continue with the actions.
Please let me know what I need to do in addition to the above to resolve the partial-response error. Do I need to add a servlet filter to invalidate the session?
I would really appreciate any help and feedback on this as it is high priority.

BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
srmthy4
  • 81
  • 1
  • 2
  • 7
  • @BalusC: I am not quite clear on the resolution given in http://stackoverflow.com/questions/28317891/spring-security-login-after-session-expiration-redirects-to-last-jsf-ajax-reques - do we need to redirect to a default page after login? – srmthy4 Oct 09 '15 at 14:48
  • Use same settings. I.e. tell Spring security to always redirect to given target URL after login. – BalusC Oct 09 '15 at 14:48
  • O.k thank you, I will try that. – srmthy4 Oct 09 '15 at 14:49
  • @BalusC : I checked and we have configured a default target URL. Below is the Spring configuration: .... **** ` – srmthy4 Oct 09 '15 at 15:35
  • however, the error still occurs – srmthy4 Oct 09 '15 at 15:35
  • I also wanted to add that I have added below in web.xml as per some of the suggestions given to avoid ViewExpiredException: *** javax.faces.STATE_SAVING_METHOD client *** – srmthy4 Oct 09 '15 at 16:44

1 Answers1

0

I had got the same issue when session had been expired. I thought it was too late, but maybe would be helpful for others who has issues like me.

The root cause is Spring Security saves the last request before redirecting client to do the authentication. After then, Spring security would try to perform the request again when user visits the page of last request. Unfortunately, the request was ajax/partial and its view was expired -> partial xml content was returned.

Easy way to get rid of this issue is removing the saving behavior of Spring Security. SavedRequestAwareAuthenticationSuccessHandler class is used to handle these kind of behaviours. Configure as:

<bean id="authenticationFilter"  class="org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter"
        p:authenticationManager-ref="authenticationManager"
        p:authenticationFailureHandler-ref="authenticationFailureHandler"
        p:authenticationSuccessHandler-ref="authenticationSuccessHandler"
        p:usernameParameter="username"
        p:passwordParameter="password">
    </bean>
... 

<bean id="authenticationSuccessHandler" class="org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler"
        p:defaultTargetUrl="/"
        p:alwaysUseDefaultTargetUrl="true"/>

Hope it would help.