如何处理AJAX请求中的会话超时?

时间:2013-06-13 15:02:36

标签: spring jsf jsf-2 primefaces spring-security

我使用Spring-Security和Primefaces作为视图。如何在会话超时后将用户重定向到登录页面?我有一个Tabview,里面有几个标签。所以我需要在ajax请求中处理会话超时。有没有解决方案?

Spring-security.xml文件

<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>

2 个答案:

答案 0 :(得分:5)

如果将命名空间配置放在一边并使用“纯”bean配置,则可以自定义ExceptionTranslationFilter以使其在ajax请求的情况下绕过配置的AuthenticationEntryPoint。详细解释了here的一个例子。

ExceptionTranslationFilter的想法是它检测到在执行请求之前抛出了AuthenticationException或AccessDeniedException。在这些情况下,如果用户未登录,通常应该启动authenticationEntryPoint。如果是AccessDeniedException并且用户已登录,则ExceptionTranslationFilter通常只会返回http状态代码403(禁止访问)

但是,如果您可以像blog post mentionned above那样自定义ExceptionTranslationFilter,则可以通过查看http标头来检测被拒绝的请求是否为ajax。在这种情况下,不是调用AuthenticationEntryPoint,而是发送重定向,你可以像thread balusC mentionned一样,但在ExceptionTranslationFilter而不是在jsf ExceptionHandler中执行。

希望得到这个帮助。

答案 1 :(得分:1)

我认为在Spring安全性和ajax(在jsf中)的情况下,登录页面的重定向请求已经发送到ajax请求处理程序,这里唯一的问题是jsf(prime-faces)的ajax标准请求处理程序没有处理相同。

我不是jsf专家,但我可以考虑在上述答案之外进行可能的解决方案,可选择实施以确保准确性。

  • 如果只需要对几个jsf页面处理此问题,则可以提供p:ajax标记的onsuccess属性

    • 处理程序将负责确定成功响应和重定向响应
    • 如果登录页面可以是html / jsp,那么在重定向的情况下,如果在responseText中没有<?xml标签就可以轻松检测到
  • 如果需要为整个应用程序处理此问题,则可以使用自定义渲染器提供默认的onsuccess处理程序

自定义Ajax处理程序需要保存在jsf模板的标题部分(使用渲染器或通过指定“onsuccess”属性)

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

对于渲染器:(如果整个应用程序处理问题)

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

面-配置

<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>
在素数面的情况下

TestRenderer to extend org.primefaces.component.behavior.ajax.AjaxBehaviorRenderer并覆盖以下方法:

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