会话到期后重定向到不同的页面

时间:2013-06-28 12:43:27

标签: spring redirect spring-security spring-webflow

我使用这些技术构建了一个Web应用程序:

  • Spring MVC
  • Web Flow
  • Spring Security
  • Primefaces

我需要在会话到期后将用户重定向到不同的页面。经过一些研究,我找到了两个选择。使用具有超时功能或<meta http-equiv="refresh">标记的JavaScript。 但是有更优雅的方式吗?

我也尝试用HttpSessionListener来做,但我不知道如何将客户端重定向到不同的站点(我不确定是否可行)。

或者可以在一段时间后以某种方式配置Tomcat或Apache来刷新客户端视图吗?

提前致谢。

3 个答案:

答案 0 :(得分:0)

一种方法是实施过滤器:
1)检查HttpServletRequest.getRequestedSessionId(),如果它返回null这是一个新的请求,否则之前有一个活动的会话。
2)检查HttpServletRequest.isRequestedSessionIdValid(),如果它返回false,则表示会话已在服务器端过期。
3)如果需要,从过滤器重定向。

答案 1 :(得分:0)

以下是我用来通知用户会话过期并将用户重定向到“您已经注销”页面的代码:

   <h:form prependId="false" style="display:none;">
      <p:idleMonitor
         timeout="#{session.maxInactiveInterval * 1000 - 60000}"
         onidle="startIdleMonitor()"
         onactive="timeoutDialog.hide()" />

      <p:dialog id="timeoutSession"
         header="Session expiring..."
         widgetVar="timeoutDialog"
         showEffect="fade" hideEffect="fade"
         modal="true"
         closable="false"
         draggable="false"
         resizable="false"
         appendToBody="true"
         position="center"
         onHide="stopCount()"
         onShow="doTimer()">
         <br />
         <p>
            <span class="ui-icon ui-icon-alert" style="float: left; margin: 8px 8px 0;"/>
            <p:panel>
               Your session will expire in&nbsp;
               <span id="dialog-countdown" style="font-weight: bold"></span>
               &nbsp;seconds
            </p:panel>
         </p>
         <br/>
         <p style="font-weight: bold;">Please move your mouse to keep the session alive</p>
      </p:dialog>
      <p:remoteCommand name="keepAlive" actionListener="#{applicationBean.keepSessionAlive}" />
   </h:form>
   <script type="text/javascript">
      var TIME = 60; // in seconds
      var countTimer = TIME;
      var processTimer;
      var timer_is_on = 0;
      var redirectPage = "#{applicationBean.logoutURL}";

      var countDownDiv = "dialog-countdown";
      var txtCountDown = null;
      if (!txtCountDown)
        txtCountDown = document.getElementById(countDownDiv);

      function startIdleMonitor() {
        countTimer = TIME;
        txtCountDown.innerHTML = countTimer;
        timeoutDialog.show();
      }
      function timedCount() {
        txtCountDown.innerHTML = countTimer;
        if (countTimer == 0) {
            stopCount();
            window.location.href = redirectPage;
            return;
        }
        countTimer = countTimer - 1;
        processTimer = setTimeout("timedCount()", 1000);
      }
      function doTimer() {
        if (!timer_is_on) {
            timer_is_on = 1;
            timedCount();
        }
      }
      function stopCount() {
        clearTimeout(processTimer);
        timer_is_on = 0;
        keepAlive();
      }
      </script>

答案 2 :(得分:0)

我认为确保应用程序处理所有3种情况(登录失败,无效会话和过期会话)是个好主意。弹簧安全性的一种方法如下:

    <http>
...
<!-- form login if you have one -->
<form-login authentication-failure-url="/handleLoginFailure" />
     ...
     <custom-filter position="CONCURRENT_SESSION_FILTER" ref="concurrentSessionFilter" />
<session-management invalid-session-url="/handleSessionNoLongerActive" session-authentication-strategy-ref="concurrentSessionControlStrategy" />

</http>



<beans:bean id="concurrentSessionFilter" 
    class="org.springframework.security.web.session.ConcurrentSessionFilter" 
    c:sessionRegistry-ref="sessionRegistry" 
    c:expiredUrl="/handleSessionExpired">
</beans:bean>


@Bean
public SessionRegistry sessionRegistry() {
    SessionRegistryImpl impl = new SessionRegistryImpl() ;
    return impl;
}

@Bean
public ConcurrentSessionControlStrategy concurrentSessionControlStrategy() {
    ConcurrentSessionControlStrategy impl = new ConcurrentSessionControlStrategy(sessionRegistry()) ;
    return impl;
}   

另见Session Management。 (web.xml更改)。

根据应用程序功能,您可能还需要处理拒绝访问的情况。