Redirect handling PrimeFaces Ajax requests on session timeout in Spring Security
Asked Answered
P

1

5

I am trying to get the JSF web front-end to redirect to back to the login page (in Spring Security) when the session times-out.

I have tried using a meta-refresh approach, however this causes an undesired side-effect that the meta-refresh time will not be updated when only AJAX controls are used on the page. This means that the page may refresh while you are still using it, because you haven't transitioned to another page and only made AJAX calls to the server. I have not found a way to change this behavior easily using Primefaces.

The Spring Security sends a 302 HTTP error message back to Primefaces when the session has expired, however Primefaces just ignores redirect request. You can tell when the session has expired as the Primefaces controls stop responding as their AJAX calls are not succeeding.

I have am using Primefaces 3.4.2, and Spring Security 3.1.4 running on Glassfish 3.1.2.2.

Putscher answered 31/5, 2013 at 13:6 Comment(0)
P
13

This is a problem with the default way that Spring Security sends redirects back to the client. The default method of sending a redirect to the client is the HTML approach of sending a 302 Temporarily Moved response, however this does not work for AJAX clients. The AJAX client will interpret this as a redirect to a new location to post/get its data and not as a page redirect. The correct way to get the AJAX client to redirect the browser to a new page in the same way as a normal HTML request is:

<?xml version=\"1.0\" encoding=\"UTF-8\"?>
<partial-response>
  <redirect url="http://your.url.here/"></redirect>
</partial-response>

To override the default invalid session strategy used by Spring Security, you need to create a SessionManagementFilter bean in your Spring config, and pass it a class that implements InvalidSessionStrategy and sends the correct redirect response when a request is received either via HTML or AJAX:

<bean id="sessionManagementFilter" class="org.springframework.security.web.session.SessionManagementFilter">
  <constructor-arg name="securityContextRepository" ref="httpSessionSecurityContextRepository" />
  <property name="invalidSessionStrategy">
    <bean class="yourpackage.JsfRedirectStrategy">
       <constructor-arg name="invalidSessionUrl" value="/your_session_expired_page.xhtml" />
    </bean>
  </property>
</bean>
<bean id="httpSessionSecurityContextRepository" class="org.springframework.security.web.context.HttpSessionSecurityContextRepository"/>

You then need to add this filter to your Spring Security HTTP block:

<security:http use-expressions="true">
    <security:custom-filter ref="sessionManagementFilter" before="SESSION_MANAGEMENT_FILTER" />
    ...
</security:http>

The custom session management filter will now be created when your application starts, and the invalid session strategy class provided will execute whenever an expired session is found.

A good example of how to implement the invalid session strategy can be found here: https://gist.github.com/banterCZ/5160269

A similar question using IceFaces is available here: JSF 2, Spring Security 3.x and Richfaces 4 redirect to login page on session time out for ajax requests

Putscher answered 4/6, 2013 at 8:35 Comment(1)
One note from my (successful) implementation of your answer here: Don't clear your cookies then trigger the ajax request as a way of testing this method! The new, session-less request isn't considered "invalid" the same way an expired session is!Buoyage

© 2022 - 2024 — McMap. All rights reserved.