最近在用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'; } } });