如何使用 Spring Security 和 jQuery 处理过期会话?
我在我的应用程序中使用 Spring Security 和 jQuery。主页通过 AJAX 将内容动态加载到选项卡中。一切都很好,但有时我的选项卡中有登录页面,如果我输入凭据,我将被重定向到没有选项卡的内容页面。
所以我想处理一下这种情况。我知道有些人使用 AJAX 身份验证,但我不确定它是否适合我,因为它对我来说看起来相当复杂,而且我的应用程序不允许在没有登录之前进行任何访问。我只想为所有 AJAX 响应编写一个全局处理程序,如果我们需要进行身份验证,该处理程序将执行 window.location.reload()
操作。我认为在这种情况下,最好得到 401
错误而不是标准登录表单,因为它更容易处理。
那么,
1) 是否可以为所有 jQuery AJAX 请求编写全局错误处理程序?
2) 如何自定义 Spring Security 的行为,以便为 AJAX 请求发送 401 错误,但为常规请求发送 401 错误以照常显示标准登录页面?
3)你可能有更优雅的解决方案吗?请分享。
谢谢。
I'm using Spring Security and jQuery in my application. Main page uses loading content dynamically into tabs via AJAX. And all is OK, however sometimes I've got the login page inside my tab and if I type credentials I will be redirected to the content page without tabs.
So I'd like to handle this situation. I know some of the people use AJAX authentication, but I'm not sure it's suitable for me because it looks quite complicated for me and my application doesn't allow any access without log into before. I would like to just write a global handler for all AJAX responses that will do window.location.reload()
if we need to authenticate. I think in this case it's better to get 401
error instead of standard login form because it's easier to handle.
So,
1) Is it possible to write global error handler for all jQuery AJAX requests?
2) How can I customize behavior of Spring Security to send 401 error for AJAX requests but for regular requests to show standard login page as usual?
3) May be you have more graceful solution? Please share it.
Thanks.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
这是我认为非常简单的方法。这是我在该网站上观察到的方法的组合。我写了一篇关于它的博客文章:
http://yoyar.com/blog/2012 /06/dealing-with-the-spring-security-ajax-session-timeout-problem/
基本思想是使用上面建议的 api url 前缀(即 /api/secured)以及身份验证条目观点。它很简单并且有效。
这是身份验证入口点:
这是 spring 上下文 xml 中的内容:
Here's an approach that I think is quite simple. It's a combination of approaches that I've observed on this site. I wrote a blog post about it:
http://yoyar.com/blog/2012/06/dealing-with-the-spring-security-ajax-session-timeout-problem/
The basic idea is to use an api url prefix (i.e. /api/secured) as suggested above along with an authentication entry point. It's simple and works.
Here's the authentication entry point:
And here's what goes in your spring context xml:
我使用了以下解决方案。
在 spring security 中定义了无效的会话 url
对于该页面添加了以下控制器
对于 ajax 使用 ajaxSetup 来处理所有 ajax 请求:
I used the following solution.
In spring security defined invalid session url
For that page added following controller
And for ajax used ajaxSetup to handle all ajax requests:
看看 http://forum.springsource.org/showthread.php?t= 95881,我认为建议的解决方案比这里的其他答案更清晰:
X-Requested-With
标头。Take a look at http://forum.springsource.org/showthread.php?t=95881, I think the proposed solution is much clearer than other answers here:
X-Requested-With
header that jQuery sends.我只是想出了解决这个问题的方法,但还没有彻底测试过。我还使用 spring、spring security 和 jQuery。首先,从我的登录控制器中,我将状态代码设置为 401:
在它们的 onload() 方法中,我的所有页面都调用全局 javascript 文件中的函数:
}
此时,您可以按照自己喜欢的方式处理 401 错误。在一个项目中,我通过在包含登录表单的 iframe 周围放置一个 jQuery 对话框来处理 jQuery 身份验证。
I just came up with a solution to this problem, but haven't tested it thoroughly. I am also using spring, spring security, and jQuery. First, from my login's controller, I set the status code to 401:
In their onload() methods, all of my pages call a function in my global javascript file:
}
At this point, you can handle the 401 error any way you like. In one project, I have handled jQuery authentication by putting a jQuery dialog around an iframe containing a login form.
我通常是这样做的。每次 AJAX 调用时,请在使用之前检查结果。
然后
HasErrors()
函数如下所示,并且可以在所有页面上共享。Here's how I typically do it. On every AJAX call, check the result before using it.
And then the
HasErrors()
function looks like this, and can be shared on all pages.所以这里有两个问题。 1) Spring 安全性正在工作,但响应是通过 ajax 调用返回到浏览器的。 2) Spring security 会跟踪最初请求的页面,以便在您登录后将您重定向到该页面(除非您指定在登录后始终要使用某个页面)。在本例中,请求是一个 Ajax 字符串,因此您将被重定向到该字符串,这就是您将在浏览器中看到的内容。
一个简单的解决方案是检测 Ajax 错误,如果发回的请求特定于您的登录页面(Spring 将发回登录页面 html,它将是请求的“responseText”属性),则检测它。然后只需重新加载当前页面,这将从 Ajax 调用的上下文中删除用户。然后 Spring 会自动将它们发送到登录页面。 (我使用默认的 j_username,它是我的登录页面唯一的字符串值)。
So there are 2 problems here. 1) Spring security is working, but the response is coming back to the browser in an ajax call. 2) Spring security keeps track of the originally requested page so that it can redirect you to it AFTER you log in (unless you specify that you always want to use a certain page after logging in). In this case, the request was an Ajax string, so you will be re-directed to that string and that is what you will see in the browser.
A simple solution is to detect the Ajax error, and if the request sent back is specific to your login page (Spring will send back the login page html, it will be the 'responseText' property of the request) detect it. Then just reload your current page, which will remove the user from the context of the Ajax call. Spring will then automatically send them to the login page. (I am using the default j_username, which is a string value that is unique to my login page).
情况下触发任何 ajax 操作后,用户将被重定向到登录页面
发生超时时,在会话已清除安全上下文:
登录侦听器:的
}
When a timeout occurs, user is redirected to login page after any ajax action is triggered while session already cleared
security context :
Login listener :
}