限制在同一台电脑上只允许有一个用户登录系统

在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的用户登录地址数据相同,则表示新会话与我们要做的两个限制相冲突。将与之冲突的会话提取出来,销毁掉!

这么说,还是不够清楚,下面看代码:

web.xml

<listener>
        <listener-class>监听器完整路径</listener-class>
    </listener>

用户登录地址数据传输对象:

public class UserSession {

private String addr;

private String sessid;

private String username;

public String getAddr() {
        return addr;
    }

public void setAddr(String addr) {
        this.addr = addr;
    }

public String getSessid() {
        return sessid;
    }

public void setSessid(String sessid) {
        this.sessid = sessid;
    }

public String getUsername() {
        return username;
    }

public void setUsername(String username) {
        this.username = username;
    }

}

用户登录的代码:

HttpSession session = request.getSession();
                
                    String userHost = request.getRemoteHost();  
                      
                    String sessionId = request.getSession().getId();  
                      
                    UserSession userSession = new UserSession();  
                      
                    userSession.setUsername(user.getUsername());  
                      
                    userSession.setSessid(sessionId);  
                      
                    userSession.setAddr(userHost);  
                      
                    request.getSession().setAttribute("userSession",userSession);

监听器代码:

import java.util.HashMap;
import java.util.Map;

import javax.servlet.http.HttpSession;
import javax.servlet.http.HttpSessionAttributeListener;
import javax.servlet.http.HttpSessionBindingEvent;

public class LoginListenner implements HttpSessionAttributeListener {

Map<String, HttpSession> map = new HashMap<String, HttpSession>();

public void attributeAdded(HttpSessionBindingEvent event) {
        String name = event.getName();

if (name.equals("userSession")) {

UserSession userSession = (UserSession) event.getValue();

if (map.get(userSession.getUsername()) != null) {

HttpSession session = map.get(userSession.getUsername());

session.removeAttribute("userSession");

session.invalidate();
            }
            map.put(userSession.getUsername(), event.getSession());
        }

}

public void attributeRemoved(HttpSessionBindingEvent event) {
        String name = event.getName();

if (name.equals("userSession")) {

UserSession userSession = (UserSession) event.getValue();

map.remove(userSession.getUsername());

}
    }

public void attributeReplaced(HttpSessionBindingEvent event) {
        // TODO Auto-generated method stub

}

}

时间: 2024-10-15 14:01:02

限制在同一台电脑上只允许有一个用户登录系统的相关文章

在同一台电脑上同时安装Python2和Python3

目前Python的两个版本Python2和Python3同时存在,且这两个版本同时在更新与维护. 到底是选择Python2还是选择Python3,取决于当前要使用的库.框架支持哪个版本. 例如:HTMLTestRunner.locustio支持Python2,但是不支持Python3. 所以很多时候,一台电脑上需要同时安装Python2和Python3. 本篇内容主要讲一下,在同一台电脑上如何同时安装Python2和Python3,且均可以正常使用pip. 一.安装Python2(以及pip)

复制虚拟机到另一台电脑上

1.鼠标放在虚拟机上,会自动显示该虚拟机的存储位置.  2.找到该文件夹,直接将其复制到另外一台电脑上,然后点击打开虚拟机,找到.VMX文件打开即可使用. 3.最后你复制过去的虚拟机可能无法上网,只需要将之前的网络适配器移除,然后再添加一个新的网络适配器,这样就可以上网了. 原文地址:https://www.cnblogs.com/nsw0419/p/11616950.html

单台电脑上启动多个Modelsim图形环境窗口的简单办法(windows)

1 http://blog.21ic.com/user1/3128/archives/2010/73447.html 单台电脑上启动多个Modelsim图形环境窗口的简单办法(windows) Modelsim由于License限制,一般一个PC机只能启动一个窗口程序,打开第二个时候就会出错退出,很不方便调试使用.后来发现,结合一个叫zDesk的软件使用可以很好的解决这个问题.这个软件有点像linux下的多窗口,切换到第二个窗口下,就可以打开一个新的Modelsim图形环境.软件可以启动很多个窗

关于C++编译的程序无法在新一台电脑上运行总结

最近在调用一个SDK调试一个主板的DPIO. 可是编译好的程序在开发电脑上运行没问题,到了新主板建立的电脑系统上就出问题. 总结了下要注意一下几方面. 1:程序本身要没有问题.至少在开发电脑系统环境下要运行的起来.这个不多说了. 2:程序的依赖文件要有,比如调用的DLL要在正确的目录下. 3:C++运行库.这个好像不同Studio版本开发的所需要的也不一样.但是有一个简便方法. a.在你所开发的使用的VS图标,属性->打开文件位置. b.找到如下目录C:\Program Files (x86)\

一台电脑上配置多个tomcat

很多时候我们要配置多个tomcat 但是启动时候就会好多错误和冲突 要么startup的时候就把两个tomcat全给起了...不好控制 下面给出解决方案 一台电脑同时运行多个tomcat配置方法: 1.使用压缩版的tomcat不能使用安装版的. 2.第一个tomcat的配置不变. 3.增加环境变量CATALINA_HOME2,值为新的tomcat的地址. 4.修改新的tomcat中的startup.bat,把其中的CATALINA_HOME改为CATALINA_HOME2. 5.修改新的tomc

如何在同一台电脑上同时运行2个tomcat

前段时间做的项目,由于是给手机客户端做服务器,所以客户端在开发过程中需要访问我的服务器. 问题是我也在开发,并且没有加入热部署,那么势必会造成服务器频繁重启,这也对客户端开发会产生一定的影响. 此时就需要跑两个tomcat了,一个我开发用,一个给客户端用.那么问题来了,如何在同一台电脑上同时运行2个tomcat呢? 如果什么都不配置,我们来运行两个tomcat试试: 出错了,提示我们端口号8005被占用.tomcat默认使用8005端口来监听关闭tomcat的请求 所以该端口号不能重复,那么我们

在一台电脑上运行两个或多个tomcat

在一台电脑上运行多个tomcat 在本例中,使用两个tomcat做示例 工具/原料 tomcat 安装好jdk,并且配置好环境变量 方法/步骤 首先去apache下载一个tomcat,下载解压版的,比较方便 把这个tomcat,解压两次,为了方便显示,我把解压出来的tomcat重命名成tomcat11111和tomcat22222 修改其中一个tomcat中的某些参数,为了避免启动tomcat时出现冲突,编辑bin/startup.bat, 在文件第一行添加如下两行 SET JAVA_HOME=

完全备份ORACLE数据库 并在另一台电脑上恢复

由于最近有oracle的项目,需要把数据库在另外一台电脑里面配置一个一样的数据库用来测试开发用,之前是一直使用mssql,只需要附加或者还原就行,但是在oracle里面,就没有这么简单,但是也不难,操作如下: 1.在服务器电脑里面: 开始-运行-cmd 然后进到一个相对空间比较大的盘符及目录,执行以下: exp 数据库用户名/密码 file=生成的文件名.dmp log=日志.dmp full=y这样会在你进的那个目录下生成一个dmp文件,将数据库文件跟数据库日记文件拷过去就需要附加oracle

使用TCP在同一台电脑上可以建立连接,在两台电脑上却连接失败的原因分析

最近在用unity做联机游戏,在网络方面费了不少劲,总是在代码没问题的时候出一些莫名奇妙的BUG,不过后来都决定了.如果感觉代码没问题,八成就是防火墙的问题. 用unity发布后的游戏,如果涉及网络,在第一次运行时会出现这个界面--windows 安全警报. 我清楚记得我点了允许访问,可后来还是出现了用TCP连接不上的问题,于是我把游戏复制到了另外一文件夹下,运行后就又出现了这个界面,我点了允许,运行后却可以顺利的实现TCP连接,然后我就感觉特别奇怪,我已经被各种奇怪的BUG困惑好几次了,比如说