`
Joo
  • 浏览: 46489 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
文章分类
社区版块
存档分类
最新评论

限制多窗口重复登陆

阅读更多
我们都知道WEB服务器通过识别客户请求中的session id来判断是否返回新的HttpSession,一般情况下这个session ID是保存在客户端cookie中,准确的说是保存在session cookie中。 也就是说一旦关闭浏览器,此session cookie消失,保存其中的session ID也随之消失。再新建的浏览器再次发起请求时,服务器端找不到对应的session ID就会新建一个HttpSession返回给客户。


      现在要求系统防止用户短时间内多次发起同一请求给APP造成业务处理压力,于是在用户登陆后第一次发起此请求时记录当前时间保存到Session中,并且在下次发起相同请求时从Session中去除上次请求时间计算时间差,小于5min时给出提示并驳回请求。但是因为存在上述的问题,聪明(还是狡猾的?)客户利用多次开关浏览器便可以突破这个限制。我现在在想是否能将session ID保存到客户端硬盘的cookie上,即cookie.setMaxAge(N); N>0的方法。但是貌似session ID不能保存到持久化cookie上,不知道各位有没有什么办法?


      另外,如果能顺利地将session ID保存到持久化cookie上,会出现另外一个问题。不同用户在同一台pc上登陆系统,却发送相同的session ID给服务器,显然不对。因此,得让存在持久化cookie上的session ID根据系统登陆用户不同而不同,这需要在把cookie放到HTTP HEAD之前,拿到session ID并根据当前登陆用户做处理。不过对cookie的处理是在服务器端执行reqeust.getSession()的时候直接去cookie中的JSESSIONID属性,我怎么

才能让cookie中保存多个JSESSIONID呢


      顺便提一下,我们生产环境上4台WEB SERVER,配置了Session共享和session粘性,即对客户来说,就跟只有一台WEB一样。另外,我们有SSO,但是cookie.setMaxAge(-1);于是跨浏览器的话Session又是新的了

case0079 写道
URL REWRITE

URL REWRITE前提是服务器端给返回一个JSESSIONID,但如果客户端给过去的jsessionid每次都不同,如何指望返回来的东东的正确性呢。
同上,棘手的不是server side,而是client side

凤舞凰扬 写道
引用
好像服务器就是根据session id来判断是否是同一个用户的,如果是一有的seesion id,则会将请求分流到之前处理这个请求的节点上。现在的问题是session id在每次IE关掉之后在客户端都没有了,服务器没办法进行识别。
不知道我的理解是否正确

   我们常说的session id是服务器判断与之相连接的客户端的会话,实质上,和我们另外一个角度理解的用户是有区别的。你说的没错,如果已经存在session,就转发。不过后面一句就陷进去了。其实我前面说过,你需要传递另外一个东西,jsessionId,你在很多网站都可以看到这种应用(尤其是IBM的),对于转发服务器来说,是否存在http session并不重要,没有创建一个就是。你session中存储的数据并不在其中,而是在你对应的JVM节点中,而它是可以通过jsessionId这样的方式去获取的。
   至于说怎么识别这样的东西,其实所有的支持负载均衡多个JVM节点并存的服务器都支持。或者大不了如楼上所说,自己建立中央缓存,自己在程序中识别这样的request参数。


大概明白您的意思了。即把session id存放在JVM SESSION中而非HTTP SESSION中,跟之前那位兄弟提到的memcache方案基本相似。但关键是,这个seesion id在第一次被HttpSession返回来后,如果想在下次发起请求是将其原样送给服务器,就必须有一个机制在客户端能让其存活下来,而以浏览器为单位的session cookie是做不到的。

也就是说,问题的关键不是服务器端没办法识别jsessionid,而是这个jsessionid在客户端没法持久化。除非...我能通过在客户端JS上自己动手伪造一个跟登录客户ID相关的jsessionid出来

分享到:
评论
30 楼 case0079 2009-12-26  
URL REWRITE
29 楼 凤舞凰扬 2009-12-26  
引用
好像服务器就是根据session id来判断是否是同一个用户的,如果是一有的seesion id,则会将请求分流到之前处理这个请求的节点上。现在的问题是session id在每次IE关掉之后在客户端都没有了,服务器没办法进行识别。
不知道我的理解是否正确

   我们常说的session id是服务器判断与之相连接的客户端的会话,实质上,和我们另外一个角度理解的用户是有区别的。你说的没错,如果已经存在session,就转发。不过后面一句就陷进去了。其实我前面说过,你需要传递另外一个东西,jsessionId,你在很多网站都可以看到这种应用(尤其是IBM的),对于转发服务器来说,是否存在http session并不重要,没有创建一个就是。你session中存储的数据并不在其中,而是在你对应的JVM节点中,而它是可以通过jsessionId这样的方式去获取的。
   至于说怎么识别这样的东西,其实所有的支持负载均衡多个JVM节点并存的服务器都支持。或者大不了如楼上所说,自己建立中央缓存,自己在程序中识别这样的request参数。
28 楼 凤舞凰扬 2009-12-26  
   楼上其实说得是蛮对的,楼主换个思路就可以了。
27 楼 linliangyi2007 2009-12-26  
很简单的问题,为啥会有这么复杂的做法呢,建议楼主跳出现有的思路,重新设计吧。

一个application级的缓存就应该能解决楼主的问题了,如果群集可以借助jbosscache这样的缓存做简单的辅助就好。
26 楼 liupesnap 2009-12-26  
在session这一层写个简单的map实现session缓存吧 这样下次就直接在缓存中查找相应session信息。
25 楼 127.0.0.1 2009-12-25  
不知道可不可以将LZ的需求简化(一个服务器、一个应用)为?:
1、同一个用户ID,禁止其创建多个session会话。
2、同一客户端机器,依然允许登录多个不同的用户ID,但需满足第1点。

如果这样的话,我的方案是:
1、首先在应用层,是有办法可以记录该应用当前所有session会话的;
2、在1的基础上,在应用的最靠前的环节(在该环节,任何一次HTTP请求沿未导致新session会话的建立)设立过滤器(过滤每一次HTTP请求),就是在这过滤环节,判断当前session会话列表中是否包括该用户ID,如果是的话,则作出A和B中的其中一种决策:
   A、终止此次HTTP请求,请将错误信息响应给客户端,后续不再作任何处理;
   B、提示客户端,已有相同的用户ID登录,询问是否注销之前已有的同用户ID的session,并建立新的session会话(简单生硬一点的做法,干脆不“询问”,直接注销旧的session会话,然后放行此次请求)。

当然,这里的“询问”又是一个新的HTTP请求,这个请求主要包含两个关键信息,即“用户ID”及“登录密码”。

----------------------------
PS:LZ说使用到了集群,偶对多个Server间的session如何协同管理的没了解过。
24 楼 Joo 2009-12-25  
凤舞凰扬 写道
   其实楼主换一个思路就能解决这个问题。其实我们理解的session已经包括了两个东西,一个是http session机制,而另外一个是实现servlet规范的JVM session存储对象。楼上如果将这两个理解区分开就能解决这个问题了。
    在很多具有分布式负载均衡的系统中,为了确保一个用户的多次访问都在同一个机器上(如果是不同机器就涉及到session复制),或者说能获取同一个session存储内容,都采取了加上jsessionId这样的url参数方式,它其实就是我前面讲的后者。
    楼主限制重复登录,其实只需要对后者进行管理控制,不需要关心前者是否会被创建.


好像服务器就是根据session id来判断是否是同一个用户的,如果是一有的seesion id,则会将请求分流到之前处理这个请求的节点上。现在的问题是session id在每次IE关掉之后在客户端都没有了,服务器没办法进行识别。
不知道我的理解是否正确
23 楼 凤舞凰扬 2009-12-25  
   其实楼主换一个思路就能解决这个问题。其实我们理解的session已经包括了两个东西,一个是http session机制,而另外一个是实现servlet规范的JVM session存储对象。楼上如果将这两个理解区分开就能解决这个问题了。
    在很多具有分布式负载均衡的系统中,为了确保一个用户的多次访问都在同一个机器上(如果是不同机器就涉及到session复制),或者说能获取同一个session存储内容,都采取了加上jsessionId这样的url参数方式,它其实就是我前面讲的后者。
    楼主限制重复登录,其实只需要对后者进行管理控制,不需要关心前者是否会被创建.
22 楼 melin 2009-12-25  
Joo 写道
但就是不知道集群情况下是否会共享ApplicationContext
没有那么牛叉的功能吧,


在集群环境下同步就更难了,成本更大,memcached使用很简单,是比较好的实现方式。
21 楼 Joo 2009-12-25  
melin 写道


SecurityRegistry 只是一个接口,你可以去实现字节的,例如把数据存储到memcached中或者(tt+tc)
,默认是存储在当前jvm内存中,

我这是只是说了spring security的实现方式,你可以参考,没有必要非要把spring security整合进来


汗,貌似这个工程就大了,有些杀鸡用牛刀的感觉
我们现在是没有分布式缓存机制的。其实之前有同学提出存在ApplicaionContext里面,但就是不知道集群情况下是否会共享ApplicationContext
20 楼 melin 2009-12-25  
Joo 写道
melin 写道
增加一个filter,保存userid和sessionid,

ConcurrentSessionController是一个接口,有两个需要实现的方法:checkAuthenticationAllowed()和registerSuccessfulAuthentication(),Spring Security提供了一个实现类ConcurrentSessionControllerImpl,经过分析缺省的实现类,发现方法allowableSessionsExceeded()处理多次并发会话,在SecurityRegistry中保存每个会话的信息,主要是用户帐号对应的会话ID(sessionId)和最后发起时间,在并发发生时,从SecurityRegistry中取出关于某个用户帐号的所有会话(spring security 可以可以控制同时同一个用户登录几次),如果exceptionIfMaximumExceeded = false,找到最早一个会话,将其释放掉,腾出空间给新会话,如果exceptionIfMaximumExceeded = true,将发出一个异常。

多谢,我去看看这个能否满足要求。我们现在使用的是在Spring源码上扩展后的一个框架,不知道是否有保留Spring Security部分了呵呵
另外,如果是多台WEB集群,每台上面的SecurityRegistry会互相复制吗?


SecurityRegistry 只是一个接口,你可以去实现字节的,例如把数据存储到memcached中或者(tt+tc)
,默认是存储在当前jvm内存中,

我这是只是说了spring security的实现方式,你可以参考,没有必要非要把spring security整合进来
19 楼 Joo 2009-12-25  
kunee 写道
说来说去不就是少了个记录的地方吗

数据库是干什么用的

本来就是为了降低压力才做的控制,发到为了控制每次去db,本末倒置了
18 楼 kunee 2009-12-25  
说来说去不就是少了个记录的地方吗

数据库是干什么用的
17 楼 yonglin4605 2009-12-25  
<div class="quote_title">Joo 写道</div>
<div class="quote_div">
<div class="quote_title">yonglin4605 写道</div>
<div class="quote_div">if(上次登录IP与本次登录IP相同 &amp;&amp; 上次登录时间距离现在不超过5分钟){ <br>  禁止5分钟内进行业务查询 <br>} <br><br>这个方法挺简单的啊 <br>我们没有办法对客户端进行全面的控制(包括session),最好的方法就是在服务器端控制</div>
<p><br>你这个“上次登陆IP”记录在哪? 连Session都不是原来的Session了,还能取到这个“上次登陆IP”吗?</p>
<p>另外,session本身就是服务器端的东东,表混淆了</p>
<p> </p>
</div>
<p>我的意思就是用日志记录你的登录历史啊,每次用户登录的时候记下来,你不计当然没有</p>
<p>或者你不想的话在servletContext里面建一个map,放置每个用户的最新登录记录</p>
16 楼 Joo 2009-12-25  
melin 写道
增加一个filter,保存userid和sessionid,

ConcurrentSessionController是一个接口,有两个需要实现的方法:checkAuthenticationAllowed()和registerSuccessfulAuthentication(),Spring Security提供了一个实现类ConcurrentSessionControllerImpl,经过分析缺省的实现类,发现方法allowableSessionsExceeded()处理多次并发会话,在SecurityRegistry中保存每个会话的信息,主要是用户帐号对应的会话ID(sessionId)和最后发起时间,在并发发生时,从SecurityRegistry中取出关于某个用户帐号的所有会话(spring security 可以可以控制同时同一个用户登录几次),如果exceptionIfMaximumExceeded = false,找到最早一个会话,将其释放掉,腾出空间给新会话,如果exceptionIfMaximumExceeded = true,将发出一个异常。

多谢,我去看看这个能否满足要求。我们现在使用的是在Spring源码上扩展后的一个框架,不知道是否有保留Spring Security部分了呵呵
另外,如果是多台WEB集群,每台上面的SecurityRegistry会互相复制吗?
15 楼 Joo 2009-12-25  
<div class="quote_title">yonglin4605 写道</div>
<div class="quote_div">if(上次登录IP与本次登录IP相同 &amp;&amp; 上次登录时间距离现在不超过5分钟){ <br>  禁止5分钟内进行业务查询 <br>} <br><br>这个方法挺简单的啊 <br>我们没有办法对客户端进行全面的控制(包括session),最好的方法就是在服务器端控制</div>
<p><br>你这个“上次登陆IP”记录在哪? 连Session都不是原来的Session了,还能取到这个“上次登陆IP”吗?</p>
<p>另外,session本身就是服务器端的东东,表混淆了</p>
<p> </p>
14 楼 yonglin4605 2009-12-25  
if(上次登录IP与本次登录IP相同 && 上次登录时间距离现在不超过5分钟){
  禁止5分钟内进行业务查询
}

这个方法挺简单的啊
我们没有办法对客户端进行全面的控制(包括session),最好的方法就是在服务器端控制
13 楼 melin 2009-12-25  
增加一个filter,保存userid和sessionid,

ConcurrentSessionController是一个接口,有两个需要实现的方法:checkAuthenticationAllowed()和registerSuccessfulAuthentication(),Spring Security提供了一个实现类ConcurrentSessionControllerImpl,经过分析缺省的实现类,发现方法allowableSessionsExceeded()处理多次并发会话,在SecurityRegistry中保存每个会话的信息,主要是用户帐号对应的会话ID(sessionId)和最后发起时间,在并发发生时,从SecurityRegistry中取出关于某个用户帐号的所有会话(spring security 可以可以控制同时同一个用户登录几次),如果exceptionIfMaximumExceeded = false,找到最早一个会话,将其释放掉,腾出空间给新会话,如果exceptionIfMaximumExceeded = true,将发出一个异常。
12 楼 Joo 2009-12-25  
yonglin4605 写道
Joo 写道


yonglin4605 写道
验证IP地址不行吗?或者MAC地址

这样会导致一台pc只能限制一个用户登陆使用,这显然是不能说服客户的

你对登录进行日志记录,每次登陆时验证一下就好了

你这种做法技术上可行,但是前后矛盾,命名用IP/MAC来限制了,缺又要针对用户做验证。这样的话,还不如从一开始就不要限制IP/MAC不是更好?
更何况,IP/MAC也不是绝对的标识符,在网络变更或者硬件升级的情况下难不成软件系统也要跟着做一次清理?
11 楼 yonglin4605 2009-12-25  
Joo 写道


yonglin4605 写道
验证IP地址不行吗?或者MAC地址

这样会导致一台pc只能限制一个用户登陆使用,这显然是不能说服客户的

你对登录进行日志记录,每次登陆时验证一下就好了

相关推荐

    C#防用户重复登录的方法.NET

    这主要是为了防止恶意用户通过多次登录尝试绕过系统的安全性,或者是为了保护用户的账户,避免他们意外地在多个窗口或浏览器标签页中保持活动状态,可能导致数据混乱或隐私泄露。以下是一些常见的防止用户重复登录的...

    易语言限制异地重复登陆

    在本案例中,我们讨论的主题是“易语言限制异地重复登陆”,这是一个针对网络应用登录安全性的解决方案。 异地登录限制通常用于防止未经授权的用户在不同地点使用同一账号,比如防止盗号者在其他地区尝试登录。这样...

    asp.net下一个账号不允许多个用户同时在线,重复登陆的代码

    方法一: 复制代码 代码如下: string sKey = username.Text.ToString().Trim(); // 得到Cache中的给定Key的值 string sUser = Convert.ToString(Cache[sKey]); // 检查是否存在 if (sUser == null || sUser == String...

    易语言源码简单的登陆密码验证.7z

    步进、重复...直到)等,用于实现逻辑判断和循环执行。 2. **密码验证原理**: - **用户输入**:程序通常会通过消息框或对话框获取用户的输入,这里是登录密码。 - **比较验证**:将用户输入的密码与预设的正确...

    Asp.net mvc 权限过滤和单点登录(禁止重复登录)

    禁止重复登录是指在单点登录系统中,确保用户在同一时间只能在一个会话中保持登录状态,如果用户试图在一个新的设备或浏览器窗口中登录,系统需要处理好旧会话与新会话的关系,确保旧会话被安全地登出。 在上述代码...

    .net C# 通过session控制重复登录及在线用户统计

    - **强制登出**:销毁当前`Session`,并允许新登录,这样可以防止同一用户在多个设备或浏览器窗口同时登录。 - **多设备支持**:允许用户在多个设备上同时登录,但限制某些操作(如修改密码)只能在一个会话中进行...

    asp.net 防止同一用户同时登陆

    在ASP.NET开发中,确保系统安全性的一个关键方面是防止同一用户在同一时间从多个设备或浏览器窗口登录。这种安全措施不仅可以防止潜在的安全威胁,如账户冒用,还可以避免因多处登录而造成的资源浪费和数据冲突。...

    微信(WeChat)电脑端多开工具源码

    多开工具通过模拟不同的环境或者修改客户端的启动逻辑,绕过了这一限制,使得用户可以同时打开并登录多个微信账户。这通常涉及到进程管理、内存操作和网络通信等多个方面的知识。 在实现上,多开工具可能包含以下...

    SecureCRT远程登陆工具

    10. 会话同步:在多窗口同时打开同一会话时,SecureCRT能同步所有窗口的滚动条,保持查看内容的一致性。 11. 键绑定:可以自定义键绑定,比如将Ctrl+C、Ctrl+V映射为发送特定字符序列,适应不同操作习惯。 12. ...

    中软国际jsp实现网站登陆、注销实例

    【用户重复登录限制】为了防止用户重复登录,可以采用以下策略:一是设置唯一登录会话,当用户在新设备或新窗口尝试登录时,检查其已有会话,若存在则强制注销旧会话;二是使用数据库记录在线状态,登录时检查用户...

    易语言程序的登陆界面(仿制)

    这个“易语言程序的登陆界面(仿制)”项目显然是一个教学或示例程序,旨在教授如何使用易语言创建类似常见应用软件的登录界面。下面将详细讨论易语言、登录界面的构建以及相关知识点。 1. **易语言基础**: - **...

    素材 学生管理系统登陆素材

    描述中的“素材 学生管理系统登陆素材”是对标题的重复,进一步强调了这是一组专门针对学生管理系统登录功能的设计资源。这些素材可能涵盖了登录界面的各种元素,如输入框、按钮、背景图案以及可能的动画效果等,...

    轩溪下载系统 v3.81.rar

    分别为文字 、图片、Flash、弹出窗口以及模态窗口(网页对话框).支持自定义广告内容. (5)、自定义会员的等级,可选会员注册是否开放,可选会员功能是否开启,会员资格时间限制.可选注册时默认超期天数;可选注册立刻激活...

    如何不让别人在你的电脑上登陆QQ.docx

    **解除限制方法:** 如果需要恢复QQ的正常使用,只需要重复以上步骤,在“路径属性”对话框中将“安全级别”更改为“不受限”,然后点击“确定”。 #### 二、文件夹只读法 **步骤1:** 查看QQ安装位置 右键点击...

    轩溪下载系统3.78

    可选下载地址的会员等级限制. (8)、提供多个系统工具:批量修改下载地址,空间占用查看,备份、恢复、压缩数据库. (9)、软件文章采集:自定义采集源,无需学习正则表达式,支持防重复采集,支持内容分页采集.支持...

    爱转发破解版 巅峰时代破解版

    2.自动接受电脑微信登陆(开启后不在家即可电脑登陆) 3.安卓首款突破20秒视频限制转发(全网独家) 4.无限暴力有效添加群和附近人(可分批可设置验证语) 5.24小时自动关键词回复可编辑(全网独家 6.一键...

    十年抽奖系统 V 5.73

    正版软件待抽奖人数不做限制,非常适合工厂企业用来举办抽奖活动,即高效、又公平、更大气!可以自定义公司名称、活动名称、抽奖人员名单…… 由于版本内容更新改动较大,从 V 5.71以后版本的注册码跟以前版本注册...

    十年抽奖系统 V 5.76

    正版软件待抽奖人数不做限制,非常适合工厂企业用来举办抽奖活动,即高效、又公平、更大气!可以自定义公司名称、活动名称、抽奖人员名单… … 由于版本内容更新改动较大,从 V 5.71以后版本的注册码跟以前版本注册...

    十年抽奖系统 V 5.77

    正版软件待抽奖人数不做限制,非常适合工厂企业用来举办抽奖活动,即高效、又公平、更大气!可以自定义公司名称、活动名称、抽奖人员名单… … 由于版本内容更新改动较大,从 V 5.71以后版本的注册码跟以前版本注册...

    十年抽奖系统 V 5.74

    正版软件待抽奖人数不做限制,非常适合工厂企业用来举办抽奖活动,即高效、又公平、更大气!可以自定义公司名称、活动名称、抽奖人员名单… … 由于版本内容更新改动较大,从 V 5.71以后版本的注册码跟以前...

Global site tag (gtag.js) - Google Analytics