4

我有一个安全的Backbone.js应用程序(使用Spring security atm。),因此登录的用户必须具有有效的会话cookie(JSESSIONID )。现在,如果此会话无效(删除,过期,无论)并且用户尝试发出请求,则Spring安全性将返回302错误,以尝试将用户重定向到登录表单。处理HTTP 302错误并在Backbone.JS“同步”方法中重定向

正如解释in this answer,这302响应被浏览器(它没有达到我的应用程序),那么,什么是回到我的应用程序是用的contentType =“text/html的” 200 OK响应处理(含登录形成)。

这是一个问题,因为当我的骨干模型试图做一个网址同步,它期望JSON。如果这个同步发生时没有一个有效的会话,当预期“application/json”时会返回200“text/html”响应,给我一个jQuery.extend.parseJSON中的JSON解析错误。

this question/answer的大力帮助下,我重写了Backbone.sync方法以便使用我自己的错误处理。但是,因为302永远不会到达我的错误处理程序,所以我无法覆盖自己的重定向。

我的情况与this question非常相似,但是从未公布过该问题的最终解决方案。有人能帮我找出确保重定向到登录页面的理想方式吗?

回答

3

您应该配置Spring Security为未经身份验证的AJAX请求返回HTTP 401 Unauthorized,而不是返回登录页面HTTP 200 OK。您可以通过检查X-Requested-With: XMLHttpRequest请求标头来检测AJAX请求(而不是普通的页面请求)。

您可以使用全局$.ajaxError处理程序来检查401错误并将其重定向到登录页面。

这是我们如何实现它,它很好地工作。尽管我不是Spring的家伙,所以我不能真正帮助Spring Security配置。

+0

+1用于检测AJAX请求,不用于他们默认重定向到登录页面 –

+0

在Spring Security 3.1+中,您可以为您的AJAX URI定义单独的领域(''tag),并将其配置为使用基本HTTP认证只(见[这个答案](http://stackoverflow.com/a/11968411/2842067),但不要使AJAX URI无状态 - 不要使用'create-session =“无状态”')。当会话过期时,您将获得这些URI的401个响应。但是,浏览器会提示输入登录名和密码 - 请参阅[本答案](http://stackoverflow.com/a/9872582/2842067)(附带评论)或[本文](http://loudvchar.blogspot。 ca/2010/11/avoid-browser-popup-for-401.html)。 – Alexey

0

编辑。使用@fencliff提供的解决方案会更好,而不是自定义coockie。

我想你可以使用XHR的其他领域来检测这种情况。一个特殊的coockie可以做到这一点。

您可以从Spring Security端定义自己的身份验证失败处理程序。在重定向到登录页面的那一刻,你将能够添加一些coockie到HttpServletResponse。您的自定义Backbone.sync方法将检查此cookie。如果它存在,它将启动您的自定义处理程序(请不要忘记同时移除coockie)。

<sec:http ... > 
    <sec:form-login login-page='/login.html' authentication-failure-handler-ref="customAuthenticationFailureHandler" /> 
</sec:http> 

<bean id="customAuthenticationFailureHandler" class="com.domain.CustomAuthenticationFailureHandler" /> 

CustomAuthenticationFailureHandler必须实现org.springframework.security.web.authentication.AuthenticationFailureHandler接口。你可以添加你的coockie,然后调用默认的SimpleUrlAuthenticationFailureHandler.onAuthenticationFailure(...)实现。