2

I am using Spring-Security and Primefaces as view. How can i redirect user to login page after session timeout? I have a Tabview and several tabs inside it. so I need to deal with session timeouts in ajax requests. Is there any solution?

Spring-security.xml file

<beans:beans xmlns="http://www.springframework.org/schema/security"
         xmlns:beans="http://www.springframework.org/schema/beans" 
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security-3.1.xsd">



<http auto-config='true' use-expressions="true">
    <intercept-url pattern="/login" access="permitAll"/>
    <intercept-url pattern="/pages/*" access="hasRole('admin')" />
    <intercept-url pattern="/j_spring_security_check" access="permitAll"/>        
    <logout logout-success-url="/login.xhtml" />
    <form-login login-page="/login.xhtml"
                login-processing-url="/j_spring_security_check"                                                       
                default-target-url="/pages/index.xhtml"
                always-use-default-target="true"                                                        
                authentication-failure-url="/login.xhtml"/>
</http>


<!--Authentication Manager Details -->    
<authentication-manager alias="authenticationManager">
    <authentication-provider user-service-ref="customUserDetailsService">
        <!--            <password-encoder hash="md5"/>-->
    </authentication-provider>
</authentication-manager>

Turgut Dsfadfa
  • 775
  • 6
  • 20
  • 42

2 Answers2

4

If you put namespace configuration aside and use "pure" beans configuration, you could customize the ExceptionTranslationFilter to make it bypass the configured AuthenticationEntryPoint in the case of an ajax request. An example of this is explained in details here.

The idea of the ExceptionTranslationFilter is that it detects that an AuthenticationException or an AccessDeniedException as been thrown before executing the request. In these cases, normally it should launch the authenticationEntryPoint if the user is not logged in. In the case of an AccessDeniedException and the user is logged in, the ExceptionTranslationFilter would normally just return an http status code 403 (access forbidden).

But, if you can customize the ExceptionTranslationFilter as in the blog post mentionned above, you can detect if the rejected request is an ajax one by looking at the http headers. In this case, instead of calling the AuthenticationEntryPoint, wich would send a redirection, you can do as the thread balusC mentionned, but in the ExceptionTranslationFilter instead of doing it in a jsf ExceptionHandler.

Hope this help.

Community
  • 1
  • 1
baraber
  • 3,296
  • 27
  • 46
1

I think in case of spring security and ajax (in jsf), redirect request for login page is already sent to ajax request handler, the only issue here is ajax standard request handler for jsf(prime-faces) is not processing the same.

I am not jsf expert but i can think of following possible work-around in-addition to above answer which may be optionally implemented for accuracy.

  • If this issue needs to be handled for only couple of jsf pages then onsuccess attribute of p:ajax tag can be provided

    • handler will be responsible for determining success response and redirect response
    • If login page can be made html/jsp then it can be easily be detected with absence of <?xml tag in responseText in case of redirect
  • If this issue needs to be handled for entire application then custom-renderer can be used to provide default onsuccess handler

Custom Ajax Handler needs to be kept in header section of jsf template (either using renderer or by specifying on "onsuccess" attribute)

function handleAJAX(data,status,xhr) {
        if (xhr.responseText.indexOf("<?xml") == -1) {
            window.location.href="login.jsp";
    }
}

For Renderer: (in case of handling issue for entire application)

Ref: http://docs.oracle.com/javaee/6/tutorial/doc/bnaxh.html

faces-config

<render-kit>
<client-behavior-renderer>
        <client-behavior-renderer-type>org.primefaces.component.AjaxBehaviorRenderer</client-behavior-renderer-type>
        <client-behavior-renderer-class>test.component.TestRenderer</client-behavior-renderer-class>
    </client-behavior-renderer>
</render-kit>

and TestRenderer to extend org.primefaces.component.behavior.ajax.AjaxBehaviorRenderer in case-of prime-faces and override following method:

public String getScript(ClientBehaviorContext behaviorContext,
        ClientBehavior behavior) {
AjaxBehavior ajaxBehavior = (AjaxBehavior) behavior;
ajaxBehavior.setOnsuccess("handleAJAX(data,status,xhr)");
return super.getScript(behaviorContext, behavior);
}
Snehal Patel
  • 819
  • 6
  • 9