Spring Security + Ajax会话超时问题
问题内容:
我有一个使用Spring MVC构建的应用程序,并通过Spring安全性进行了安全保护,其中许多控制器都是JSON
rest服务,所有这些服务均受保护。我LoginUrlAuthenticationEntryPoint
用来检测AJAX请求并403
在发生会话超时时发送错误代码-所有其他请求都被重定向回登录页面。
下面是Spring Security XML代码段和authenticationEntryPoint Java类。
问题是会话超时后的第一个AJAX请求,Spring重定向到登录页面并返回登录页面HTML,如果我尝试再次执行AJAX请求(在重定向发生后),则执行authenticationEntryPoint并返回HTTP错误代码403。我已经尝试过使用这种机制进行相同的操作http://distigme.wordpress.com/2012/11/01/ajax-
and-spring-security-form-based-
login/,
并且发生了相同的事情(在第一个AJAX请求中发生重定向,则返回所有后续的AJAX请求HTTP
403)。我不希望会话超时的AJAX请求重定向到登录页面。
有任何想法吗?
<beans:bean id="authenticationEntryPoint" class="mojo.ocs.web.AjaxAwareAuthenticationEntryPoint">
<beans:constructor-arg name="loginUrl" value="/login"/>
</beans:bean>
<!-- ENTRY POINT REF IMPLEMENTATION -->
<http auto-config="true" use-expressions="true" access-denied-page="/accessdenied" entry-point-ref="authenticationEntryPoint">
<intercept-url pattern="/login" access="isAnonymous()"/>
<intercept-url pattern="/loginfailed" access="isAnonymous()"/>
<intercept-url pattern="/welcome" access="isAuthenticated()" />
<intercept-url pattern="/" access="isAuthenticated()" />
<intercept-url pattern="/private_res/**" access="isAuthenticated()" />
<intercept-url pattern="/tne/**" access="isAuthenticated()" />
<intercept-url pattern="/team_reports/**" access="isAuthenticated()" />
<form-login login-page="/login" default-target-url="/welcome" always-use-default-target="true" authentication-failure-url="/loginfailed" />
<logout delete-cookies="JSESSIONID" logout-success-url="/logout" invalidate-session="true"/>
<session-management invalid-session-url="/login" />
</http>
这是LoginAuthenticationEntryPoint:
public class AjaxAwareAuthenticationEntryPoint extends LoginUrlAuthenticationEntryPoint
{
public AjaxAwareAuthenticationEntryPoint(String loginUrl) {
super(loginUrl);
}
@Override
public void commence(
HttpServletRequest request,
HttpServletResponse response,
AuthenticationException authException)
throws IOException, ServletException {
String ajaxHeader = ((HttpServletRequest) request).getHeader("X-Requested-With");
boolean isAjax = "XMLHttpRequest".equals(ajaxHeader);
if (isAjax) {
response.sendError(HttpServletResponse.SC_FORBIDDEN, "Ajax REquest Denied (Session Expired)");
} else {
super.commence(request, response, authException);
}
}
}
问题答案:
我通过自己的自定义过滤器实现了此问题,将其放置在ANONYMOUS_FILTER之前,如果Spring主体不存在,则返回403。