上一帖述及使用ConcurrentSessionFilter限制同帐号登录多次的方法,同帐号多次登录限制是运行系统必需的功能,所以作者对其深入测试,在上一帖中也列举了Spring Security的ConcurrentSessionFilter和ConcurrentSessionControllerImpl类的几个限制。做一下简单的总结,下面假设同时使用DigestProcessingFilter和辅助类:
如果exceptionIfMaximumExceeded = true,即第二个发起的会话被禁止,如果一个用户重新启动浏览器,再次登录失败,因为前一个会话没有超时,被当成了多次登录。
如果exceptionIfMaximumExceeded = false,如果两个人使用同一个帐号登录,将出现交互将对方踢出去的现象,实际上并没有禁止任何人登录,只是每次要先将另一个人踢下去。
--------------------------------------------------------------------------------
需求
我想使用exceptionIfMaximumExceeded = true,同时允许同一个用户在同一台机器上连续登录多次,我采取了编写定制的ConcurrentSessionController实现类的方法。
--------------------------------------------------------------------------------
原理
ConcurrentSessionController是一个接口,有两个需要实现的方法:checkAuthenticationAllowed()和registerSuccessfulAuthentication(),Spring Security提供了一个实现类ConcurrentSessionControllerImpl,经过分析缺省的实现类,发现方法allowableSessionsExceeded()处理多次并发会话,在SecurityRegistry中保存每个会话的信息,主要是用户帐号对应的会话ID(sessionId)和最后发起时间,在并发发生时,从SecurityRegistry中取出关于某个用户帐号的所有会话,如果exceptionIfMaximumExceeded = false,找到最早一个会话,将其释放掉,腾出空间给新会话,如果exceptionIfMaximumExceeded = true,将发出一个异常。
所以,需要改进allowableSessionsExceeded(),如果exceptionIfMaximumExceeded = true让程序判断客户地址,如果同一个IP,则允许登录,将最早的会话释放掉,如果不是同一个IP在发出异常。
在SecurityRegistry中,用户帐号信息存在一个对象中,名字是principal,当前是一个Object对象,实际上只是存了一个字符串,所以需要扩展principal,写一个定制的类(我的类含有两个属性:username和userip),里面保存客户IP信息。allowableSessionsExceeded()只是使用SecurityRegistry,SecurityRegistry中的内容是由registerSuccessfulAuthentication()方法写入的,所以,在该方法中需要将原来的pricipal对象替换成定制的Principal类的对象。同时checkAuthenticationAllowed()方法也要修改,因为这个方法要查询SecurityRegistry,查询条件替换成定制的Principal类的对象。
--------------------------------------------------------------------------------
注意事项
定制的Principal类要实现equals()和hashCode()和toString()三个方法,在equals()方法中只要username相同就表示两个对象相同,而在hashCode()中只需要将username的hashcode计算在内,因为SecurityRegistry是以principal为关键字的Map容器,这两个方法决定了对Map的查询。toString()方法可以根据自己的需要写,我只是将username输出。
--------------------------------------------------------------------------------
测试
将定制的ConcurrentSessionController对象编制(wire)到应用系统中,经过测试,能够达到预想目的。
--------------------------------------------------------------------------------
存在的问题
原来想省点劲,只要继承ConcurrentSessionControllerImpl并重载上述三个方法就行了,但是不知道为什么securityRegistery属性一直注入不了,一气之下,写了一个直接实现ConcurrentSessionController接口的新类。实际上也不是从头写,将ConcurrentSessionControllerImpl代码改吧该吧即可,用不了几分钟,这就是开源的好处。
转自 http://www.gooseeker.com/cn/node/517
分享到:
相关推荐
spring_acegi精彩实例,带MYSQL数据库脚本,保证能运行 spring_acegi精彩实例,带MYSQL数据库脚本,保证能运行 spring_acegi精彩实例,带MYSQL数据库脚本,保证能运行 spring_acegi精彩实例,带MYSQL数据库脚本,...
Acegi Security System for Spring
spring+acegi+中文手册spring+acegi+中文手册spring+acegi+中文手册spring+acegi+中文手册spring+acegi+中文手册spring+acegi+中文手册spring+acegi+中文手册spring+acegi+中文手册spring+acegi+中文手册spring+...
Spring源代码解析(十):Spring_Acegi框架授权的实现.doc
Spring Acegi权限控制,安全系统就只包括两个问题: 认证和授权.
Acegi文档 spring acegi 详细文档
Spring Security acegi
NULL 博文链接:https://liaomin789.iteye.com/blog/581234
基于spring的Acegi安全框架认证与授权的分析及扩展.pdf
16. acegi到spring security的转换方式 16.1. Spring Security是什么 16.2. 目标 16.3. 步骤 16.4. 总结 V. 高级话题 17. 领域对象安全(ACLs) 17.1. 概述 17.2. 关键概念 17.3. 开始 18. 预认证...
Spring的ACEGI的应用
pring Security 的前身是 Acegi Security ,是 Spring 项目组中用来提供安全认证服务的框架。 Spring Security 为基于J2EE企业应用软件提供了全面安全服务。特别是使用领先的J2EE解决方案-Spring框架开发的企业软件...
1、搭建基本的Spring Security项目 2、使用数据库管理用户权限 3、自定义认证数据库表结构 4、自定义登录页面 5、使用数据库管理资源 6、控制用户信息 MD5加密 获取当前用户信息 7、自定义访问拒绝页面 8、动态...
这里包括Spring Security2的中文文档和一个基于Dao的开发实例,相信不管是对原来基于Acegi安全框架的开发人员还是现在基于Spring安全框架(Spring Security2实际上是Acegi2)的开发人员都有参考价值.
spring Acegi例子,很简单的一个acegi实例,容易理解
Spring acegi 3 文档 Spring acegi 3 文档Spring acegi 3 文档 Spring acegi 3 文档
Spring ACEGI手册(部份) 博文链接:https://allenj2ee.iteye.com/blog/129321
Spring Security 的前身是 Acegi Security ,是 Spring 项目组中用来提供安全认证服务的框架。
spring -acegi安全验证源码,
包含acegi-security-1.0.7.jar,acegi-security-1.0.7-sources.jar,acegi-security-cas-1.0.7.jar,acegi-security-cas-1.0.7-sources.jar,acegi-security-catalina-1.0.7.jar,acegi-security-catalina-1.0.7-...