论坛首页 Java企业应用论坛

spring security 3.0的控制一个帐号只允许一次登录

浏览 15319 次
精华帖 (15) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2010-11-25   最后修改:2010-11-25
spring security 3.0里面明确的说明了:
session-management段里面的concurrency-control是控制一个帐号最多允许登录多少次的,比如<concurrency-control max-sessions="1"/>就是一次,2当然是两次。
所有搜到的帖子,凡是提到concurrency-control这个的,我不知道有没有人试过真的好用吗?
我配置了以后发现根本就控制不住。

打开了springsecurity的debug日志,还是难以发现原因。
因为网上根本搜不到几个这方面的错误,让我误以为是我个人配置问题,就没有看代码;最后不得已挂上了spring security的代码一看,直接晕菜。
org.springframework.security.web.authentication.session.ConcurrentSessionControlStrategy
里面的checkAuthenticationAllowed方法,调用了sessionRegistry.getAllSessions,用authentication.getPrincipal(),也就是UserDetails实现对象。
但是sessionRegistry存储的时候使用的是Hash的数据结构,所以UserDetails实现类必须重写equals和hashCode。

另外网上发帖的基本就是抄来抄去,其实只要你加了concurrency-control配置,即使不写max-sessions属性,在org.springframework.security.web.authentication.session.ConcurrentSessionControlStrategy里面maximumSessions的默认值是1!

写下来省的后人走弯路。
   发表时间:2010-11-26   最后修改:2010-11-26
首先,你需要把下面的监听器添加到你的web.xml文件里,让Spring Security获得session生存周期事件:
<listener>
  <listener-class>
     org.springframework.security.web.session.HttpSessionEventPublisher
  </listener-class>
</listener>
0 请登录后投票
   发表时间:2010-11-26  
楼主说的这个,我试了,管用,网上抄的做法,但是确实起作用,不知道楼主为啥不管用
0 请登录后投票
   发表时间:2010-11-26  
lygivw 写道
首先,你需要把下面的监听器添加到你的web.xml文件里,让Spring Security获得session生存周期事件:
<listener>
  <listener-class>
     org.springframework.security.web.session.HttpSessionEventPublisher
  </listener-class>
</listener>

这些都没问题,严格按照文档做的。
0 请登录后投票
   发表时间:2010-11-26  
peak 写道
楼主说的这个,我试了,管用,网上抄的做法,但是确实起作用,不知道楼主为啥不管用

那就很奇怪了,security代码里面明明是Hash的结构做Key。
0 请登录后投票
   发表时间:2010-11-26   最后修改:2010-11-26
你早说啊,这个问题我在去年10月用springsecurity3时候就发现了,从测试版一直用到正式版,还是没解决,一直以为是bug,后来发现是UserDetails的问题,在实现登录用户时,如果你自己的user实体实现UserDetails,session并发就会失效,使用springsecurity自己的user实现就可以。
你的文章来的太晚了。。。
0 请登录后投票
   发表时间:2010-11-26  
caoyangx 写道
你早说啊,这个问题我在去年10月用springsecurity3时候就发现了,从测试版一直用到正式版,还是没解决,一直以为是bug,后来发现是UserDetails的问题,在实现登录用户时,如果你自己的user实体实现UserDetails,session并发就会失效,使用springsecurity自己的user实现就可以。
你的文章来的太晚了。。。

不好意思我才发现public class User implements UserDetails, CredentialsContainer
还有这么个类。
我一直是自己实现User类的,而且这个项目是使用Email登录,所以也没用username属性。
0 请登录后投票
   发表时间:2010-11-27  
flashing 写道
caoyangx 写道
你早说啊,这个问题我在去年10月用springsecurity3时候就发现了,从测试版一直用到正式版,还是没解决,一直以为是bug,后来发现是UserDetails的问题,在实现登录用户时,如果你自己的user实体实现UserDetails,session并发就会失效,使用springsecurity自己的user实现就可以。
你的文章来的太晚了。。。

不好意思我才发现public class User implements UserDetails, CredentialsContainer
还有这么个类。
我一直是自己实现User类的,而且这个项目是使用Email登录,所以也没用username属性。

弱弱问一下,CredentialsContainer这个接口是做什么?
0 请登录后投票
   发表时间:2010-11-27  
用于清除敏感数据的,我觉得其实也没啥大用,就是定义这么个接口提供这么个机会。
0 请登录后投票
   发表时间:2010-11-27  
flashing 写道
用于清除敏感数据的,我觉得其实也没啥大用,就是定义这么个接口提供这么个机会。

再请教一下,不知道你有没有用RememberMe这个功能,就是利用cookie记录登录信息,不过自从session并发好用后,就再也记不住我的登录信息了。
你遇到过类似的问题吗?
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics