如何限制同⼀客户端登录的⽤户数量以及禁⽌同⼀⽤户同时在不
同客户端登录?
在web应⽤系统中,出于安全性考虑,经常需要对同⼀客户端登录的⽤户数量和⼀个客户同时在多个客户端登陆进⾏限制。具体⼀点就是:
1、在同⼀台电脑上⼀次只允许有⼀个⽤户登录系统,
2、⼀个⽤户在同⼀时间只允许在⼀个客户端登录。
我最近做的⼀个系统就遇到了这样的问题,本来系统已经开发完成了,但是安全测评没有通过,就是因为没有做这两个限制。怎么来做这样的限制呢?我在⽹上了很久,发现问这个问题的⼈很多,但是没有到特别清楚的答案。后来⾃⼰摸索着,看了⼀些书,终于到解决办法了。
要解决这个问题实际上不难,对于⾼⼿来说可能都懒得去说了,但是对于不熟悉web编程的⼈来说可能会困扰很久。下⾯我把我的解决办法说出来,供⼤家参考!
先介绍⼀下我那个系统的背景:j2ee,tomcat,没有⽤cookie。
⾸先确定解决这两个问题的基本思路:
1、要解决同⼀台电脑上只允许有⼀个⽤户登录系统,只有⼀个办法。监视每⼀个连接的来源,如果发现有⼀个新的连接与某个已经存在的连接来⾃同⼀台电脑,则终⽌其中的⼀个(当然,也可以提醒⽤户,让他⾃⼰决定终⽌哪⼀个)。
2、要禁⽌⼀个⽤户账号同时在不同的客户端登录,只有监视每⼀个连接的⽤户账号,如果发现⼀个新连接的⽤户账号跟某个已经存在的连接的⽤户账号相同,则⾃动将前⼀个终⽌(同样,也可以让⽤户⾃⼰决定终⽌哪⼀个)。
确定了基本思路以后,就要具体办法了。我最初的想法是在建⽴⼀张表,存放已登录⽤户的⽤户名、物理地址、Session id等信息。当⽤户登录时,与这张表⾥⾯的数据进⾏匹配,如果发现物理地址与表中的某条记录相同,则表⽰是同⼀台客户端上有多个⽤户再登录,如果发现正在登录的⽤户的⽤户名与表中已有记录相同⽽主机名不同,则表⽰是⼀个账号同时在不同的客户端使⽤。
相信很多⼀开始遇到这个问题的⼈都会考虑这种解决办法。但是这种办法有很多问题,最主要的问题有两个:第⼀是效率,每⼀次都要从数据库⾥⾯取数据进⾏匹配。第⼆是⽤户退出时需要删除表中的记录,⽽当⽤户⾮正常退出时,很难及时监测(后来发现其实有办法监测)。
后来在⽹上的某个帖⼦⾥⾯看到⼀位⼤侠提到⽤,只是那位⼤侠说的太含糊,照他说的办法根本⽆法解决。虽然⽆法解决,但是提供了⼀个思路。于是我了⼀本书,仔细看了其中关于的部分。
解决办法就在其中了
的详细介绍见我的下⼀篇博⽂,这⾥先把解决办法告诉⼤家:
可以监听Session及其所包含的属性,即Attribute。
所以我们要做的就是:
1、建⽴⼀个,实现HttpSessionAttributeListener接⼝,监听每⼀个Attribute的增加、编辑、删除事件。中还要建⽴⼀个map,将所有的session放⼊这个map中。
2、在⽤户登录时将⽤户名、物理地址、Session id存到Session中去(可以建⽴⼀个⽤户登录地址数据传输对象,我建⽴了⼀个UserSessionAdd类,⾥⾯包含username,macAdd,sessionId三个属性,⽤户登录时将这个数据对象初始化,并存⼊到session中)。
3、每个新会话开启时,在中对Session包含的属性进⾏判断,如果新增的属性与map中已有session的⽤户登录地址数据相同,则表⽰新会话与我们要做的两个限制相冲突。将与之冲突的会话提取出来,销毁掉!
这么说,还是不够清楚,下⾯看代码:
<listener>
<listener-class>类的路径,如:com.web.MyListener</ listener-class > </listener>
⽤户登录地址数据传输对象:
public class UserSessionAdd {
private String add;
private String sessid;
private String username
public String getUsername(){
return username
}
Public void setUsername(String username){
this.username=username;
}
public String getIp() {
return add;
}
public void setAdd(String add) {
this.add = add;
}
public String getSessid() {
return sessid;
}
public void setSessid(String sessid) {
this.sessid = sessid;
}
}
⽤户登录的代码:
···
String userHost = RemoteHost();
String sessionId = Session().getId();
UserSessionAdd usa = new UserSessionAdd();
usa.setUsername(username);
usa.setSessid(sessionId);
usa.setAdd(userHost);
代码:
public class MyListener implements HttpSessionAttributeListener{
Map<String, HttpSession> map = new HashMap<
String, HttpSession>();
public void attributeAdded(HttpSessionBindingEvent event) {
String name = Name();
if(name.equals("usa")){
UserSessionAdd usa = (Value();
(Add())!=null){
HttpSession sess = (Add());
UserSessionAdd usa1 = (Attribute("usa");              veAttribute("usa");
sess.invalidate();
}
map.Add(), Session());
}
}
public void attributeRemoved(HttpSessionBindingEvent event) {
String name = Name();
if(name.equals("usa")){
session怎么记忆UserSessionAdd usa = (Value();
}
}
public void attributeReplaced(HttpSessionBindingEvent event) {
// TODO Auto-generated method stub        ````
}
}