首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 其他教程 > 开源软件 >

是哪位高手动了小弟我的cookie?Spring Security自动登录功能开发经历总结

2013-12-28 
是谁动了我的cookie?Spring Security自动登录功能开发经历总结在使用Spring Security的remember me模块为

是谁动了我的cookie?Spring Security自动登录功能开发经历总结

在使用Spring Security的remember me模块为云端开源论坛XLineCode开发自动登录模块时,本着用户至上的理念优先采用了PersistentTokenBasedRememberMeServices作为实现根基。通过参考Spring Security的官网推荐书籍Spring Security 3?,很简单也很顺利的在Spring Security命名空间下配置了该service,本地环境也简单测试通过了该功能,但在上线后接近两个月的时间内,却出现了各种多线程引发的问题而导致自动登录功能失效的情况。

?

Spring Security的remember me模块的两个实现机制简介

PersistentTokenBasedRememberMeServices

使用JdbcTokenRepositoryImpl在数据库创建persistent_logins表。当勾选自动登录时随机产生键值对并将该键值对保存在persistent_logins表及浏览器的cookie中,在浏览器当前会话失效后从下一request中提取cookie键值对,通过对比是否与数据库中的键值对一致来判断该自动功能是否有效。有效则根据该key生成新的token并更新至数据库和浏览器。如根据key未能从数据库找到记录,则不进行登录授权并取消该key在浏览器中对应的cookie。如该key对应的cookie token与数据库得到的token不一致,则该cookie在浏览器中可能已经被黑客攻破,被盗用于信息窃取,因此抛出cookie被盗的异常并根据该用户id删除其在数据库对应的所有键值记录(该用户在多个浏览器登录则有多条记录)。

核心方法processAutoLoginCookie代码如下

?

?

?

?

TokenBasedRememberMeServices

根据用户id和密码生成cookie,同样通过对比判断cookie是否有效。该机制的缺点是用户修改密码后其在其他浏览器中的cookie不会自动更新,需再次登陆生成cookie。另一缺点是密码经过加密后保存在客户端,存在一定风险。

核心方法processAutoLoginCookie代码如下

?

?

使用PersistentTokenBasedRememberMeServices遇到的各种情况

1. 因Spring Security的filter链未作并发控制,所以PersistentTokenBasedRememberMeServices的processAutoLoginCookie在处理自动登录时如服务器负载过大用户多次刷新页面会产生线程A和B同时在运行processAutoLoginCookie的情况。假设A是先于B的请求,而A在未执行tokenRepository.updateToken(newToken.getSeries(), newToken.getTokenValue(), newToken.getDate());时被系统挂起了线程,导致B先于A完成了请求。此时A获得资源后执行完时因A请求已被浏览器取消,故A所产生的新的cookie无法在浏览器中更新,导致该浏览器的下次请求中的cookie与数据库中的token不一致从而抛出Cookie被盗的异常(该情况只在极低的概率下才可能发生)。

?

2. 跑完PersistentTokenBasedRememberMeServices的processAutoLoginCookie后在业务逻辑中如抛出异常而未被代码或者web.xml中的500配置捕获,则会直接返回500错误给浏览器,此时新生成的cookie不会在浏览器更新,同样会导致cookie被盗的情况。不过一般情况下都会捕获,问题不大。

?

3. filter配置不当导致拦截了页面加载后触发的ajax或一般业务请求:同上,在发生异常时导致cookie更新失败。

?

4. 在浏览器请求未返回时直接取消该请求,因该请求在服务器执行完后不能正常设置浏览器的cookie,导致浏览器下次请求再次使用失效的cookie时processAutoLoginCookie发现两边token不一致,抛出cookie被盗异常。这种情况在网络不理想的情况下被用户触发的可能性最大,而Spring Security代码中也没有处理该情况的代码。仅仅因为用户取消请求而抛出cookie被盗的异常并清空该用户在其他浏览器的cookie会造成相当差的用户体验,这也是我决定转为采用TokenBasedRememberMeServices的原因.

?

使用TokenBasedRememberMeServices则相对简单很多,无需考虑并发的情况,只要cookie匹配就可自动登录。

?

后话:我在发现该情况后分别尝试了oschina,csdn和iteye的登录机制,发现他们均使用的是TokenBasedRememberMeServices的方式。

热点排行