最近在用Spring Security作登陸管理,登錄成功後,頁面長時間無操做,超過session的有效期後,再次點擊頁面操做,頁面無反應,需從新登陸後纔可正常使用系統。java
爲了優化用戶體驗,使得在session失效後,用戶點擊頁面對服務器發起請求時,頁面可以自動跳轉到登陸頁面。本次使用spring security 3.1。web
第一步:配置spring security的專用配置文件spring-security.xml。ajax
<http auto-config="true" entry-point-ref="myLoginUrlAuthenticationEntryPoint"></http> <beans:bean id="myLoginUrlAuthenticationEntryPoint" class="com.ushareit.beyla.security.MyLoginUrlAuthenticationEntryPoint"> <beans:property name="loginFormUrl" value="/login.jsp"/> </beans:bean>
entry-point-ref屬性,英文的意思是入口點引用,它實際上是被ExceptionTranslationFilter引用的,該過濾器的做用是異常翻譯。在出現認證異常、訪問異常的時候,經過入口點決定redirect、forword的操做。好比如今是form-login的認證方式,若是沒有經過UsernamePasswordAuthenticationFilter的認證就直接訪問某個被保護的url,那麼通過ExceptionTranslationFilter過濾器處理後,先捕獲到訪問拒絕異常,並把跳轉動做交給入口點來處理。form-login的對應入口點類爲LoginUrlAuthenticationEntryPoint,這個入口點類的commence方法會redirect或forward到指定的url(form-login標籤的login-page屬性)。spring
第二步:自定義MyLoginUrlAuthenticationEntryPoint繼承LoginUrlAuthenticationEntryPoint類,並覆蓋commence方法。json
package com.ushareit.beyla.security; import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.springframework.security.core.AuthenticationException; import org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint; @SuppressWarnings("deprecation") public class MyLoginUrlAuthenticationEntryPoint extends LoginUrlAuthenticationEntryPoint { @Override public void commence(HttpServletRequest request, HttpServletResponse response,
AuthenticationException authException) throws IOException, ServletException { HttpServletRequest httpRequest = (HttpServletRequest)request; if ("XMLHttpRequest".equalsIgnoreCase(httpRequest.getHeader("X-Requested-With"))){ response.sendError(HttpServletResponse.SC_UNAUTHORIZED,"SessionTimeout"); } else{ super.commence(request, response, authException); } } }
因爲只有在ajax請求的時候,其請求頭中有「X-Requested-With」屬性,而傳統請求的時候,請求頭中無此屬性,所以針對ajax請求異常的時候,咱們能夠經過response.sendError(HttpServletResponse.SC_UNAUTHORIZED,"SessionTimeout");來返回錯誤代碼「401」,來標記訪問出錯。spring security在經過用戶名和密碼進行登陸的時候是普通請求,直接經過super.commence(request, response, authException)服務器
第三步:ajax方法中經過利用statusCode對象根據服務器返回的不一樣狀態進行處理,我使用的jQuery。在session失效後,頁面又發起的新的ajax請求中經過statusCode對象進行相應處理。session
$.ajax({ url: 'xxxx', type: 'get', data: datas, cache: true, dataType: 'json', success: function (data) { alert(123); }, error: function (data) { console.log(data); }, statusCode: { 401: function() { alert("The session is timed out,please log in again!"); window.location.href = '/login.jsp'; } } });