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

在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-18 13:45:04

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

在一台电脑上可以同时登陆多个中华通帐号吗?

  一台电脑可以同时登陆多个中华通账号,只需要点击桌面上中华通网络电话的图标,登陆账号和密码后进行使用; 一个账号只能在一台电脑上登陆,不能同个账号同时在不同的电脑上同时登陆使用.

怎么样才能在一台电脑上完全删除自己使用的痕迹

正常情况下,所有人都不喜欢别人知道自己在电脑上看了什么网页,什么文章.什么电影之类的.个人感觉如果不是做公司的事情的,最最在意的就是我浏览了什么样的网页不能让人知道.这篇文章我们主要分享下清理自己在浏览器痕迹. 1 第一个方法:IE浏览器通用的清理痕迹,也是最好用的. 打开IE浏览器,点击工具 - Internet选项,然后再浏览历史记录,里面删除,记得里面的所有项都要打个. 2 第二种方法:使用360安全浏览器的清理痕迹的方法. 点击工具 - 历史,在历史里面可以选择怎么样清楚里面的网站.里面

如何在一台电脑上访问另一台电脑上的本地WebService文件

问题描述 我在一台电脑上用C#写了一个webService文件存在了本地,("http://localhost:43628/WebSite2/WebService.asmx"),如果在本地我想访问这个文件只需要在浏览器上输入这个URL就可以了.现在我想让另外一台接在同一个局域网下的电脑访问这个webService文件,应该怎么访问,访问的URL应该怎么写? 解决方案 解决方案二:A电脑如果要访问B电脑的webservice只需要在B电脑新建网站挂到IIS上面即可比如网站扔到D:api目

一套金山毒霸能在多台电脑上安装吗

  金山毒霸是单机授权的软件,仅允许在一台电脑上使用.对于毒霸2005以后的版本,如果在多台电脑上安装使用则可能会被服务器提示超过授权人数而锁定.该锁定一周后自动解除,无法人工解锁.

百度云同步盘最多可以在几台电脑上运行?

  百度云同步盘不限制同时运行同一个帐户的电脑数量,您只要在任意一台电脑上对文件进行操作,其他电脑上都会做同样的操作,大大节省用户的工作量.

百度云管家客户端最多可以在几台电脑上运行?

  百度云同步盘不限制同时运行同一个帐户的电脑数量,您只要在任意一台电脑上对文件进行操作,其他电脑上都会做同样的操作,大大节省用户的工作量.

如何在单台电脑上模拟多台电脑向服务器发请求啊?(主要是不一样的IP)

问题描述 如何在单台电脑上模拟多台电脑向服务器发请求啊?(主要是不一样的IP) 解决方案 解决方案二:用LoadRunner等压力测试工具即可解决方案三:如果我是想通过虚拟网卡来实现呢?不借助其他软件.解决方案四:那你添加多个IP,看看会不会用随机的IP去访问.

maven 仓库 使用nexus搭建了私服在局域网另一台电脑上

问题描述 maven 仓库 使用nexus搭建了私服在局域网另一台电脑上 maven 仓库 使用nexus搭建了私服在局域网另一台电脑上,本来正常的,今天要加个依赖,去查找log4j报错 An internal error occurred during: "Repository search". java.lang.OutOfMemoryError: Java heap space 解决方案 刷新下Maven项目,可能是私服地址配置的不对,页可能你加的这个依赖在其它库中,中央仓库里下

&amp;amp;quot;Java&amp;amp;quot;一台电脑上面的java程序如何打开另一台电脑上面的java程序

问题描述 "Java"一台电脑上面的java程序如何打开另一台电脑上面的java程序 就是我在一台电脑上面先编写一个java程序,然后通过这个java程序打开另一台电脑上面的一个*.jar的应用程序,如何实现?请大神赐教!!!!