Asp.net中实现同一用户名不能同时登录(单点登录)
Web 项目中经常遇到的问题就是同一用户名多次登录的问题,相应的解决办法也很多,总结起来不外乎这几种解决办法:
将登录后的用户名放到数据库表中;
登录后的用户名放到Session中;
登录后的用户名放到Application中;
登录后的用户名放到Cache中。
一般的这几种方法都是登录了之后,如果没有正常退出,第二次登录将不被允许。这样一般都会存在一个问题:如果用户没有正常退出系统,那么他接下来继续登录的时候,因为Session没有过期等问题,会被拒绝继续登录系统,只能等待Session过期后才能登录。本文介绍的方法是采用类似于MSN登陆的方法,第二次登录时会把第一次的登录注销掉,第一次登录将会类似于MSN弹出:您的帐号已在别处被登录,您被强迫下线的提示信息。
功能实现起来也比较简单:
登录用户名密码验证通过之后输入以下代码:

Hashtable hOnline = (Hashtable)Application["Online"];
if(hOnline != null)
{
IDictionaryEnumerator idE = hOnline.GetEnumerator();
string strKey = "";
while(idE.MoveNext())
{
if(idE.Value != null && idE.Value.ToString().Equals(UserID))
{
//already login
strKey = idE.Key.ToString();
hOnline[strKey] = "XXXXXX";
break;
}
}
}
else
{
hOnline = new Hashtable();
}
hOnline[Session.SessionID] = UserID;
Application.Lock();
Application["Online"] = hOnline;
Application.UnLock();

用户登录的时候将登录用户名放在一个全局变量Online,Online为Hashtable结构,Key为SessionID,Value为用户名。每次用户登录时均判断以下要登录的用户名在Online中是不是已经存在,如果存在该用户名已经被登录,将第一个人登录的SessionID对应的用户名强制变更为XXXXXX,表示该登录将被强制注销。
建立一个CommonPage页,系统中所有的页面都继承于CommonPage页,在CommonPage页的后台代码中添加如下代码:

override protected void OnInit(EventArgs e)
{
Hashtable hOnline = (Hashtable)Application["Online"];
if(hOnline != null)
{
IDictionaryEnumerator idE = hOnline.GetEnumerator();
while(idE.MoveNext())
{
if(idE.Key != null && idE.Key.ToString().Equals(Session.SessionID))
{
//already login
if(idE.Value != null && "XXXXXX".Equals(idE.Value.ToString()))
{
hOnline.Remove(Session.SessionID);
Application.Lock();
Application["Online"] = hOnline;
Application.UnLock();
MessageBox("你的帐号已在别处登录,您被强迫下线!",Login.aspx);
return false;
}
break;
}
}
}
}

继承于CommonPage的页面在刷新时都要执行重载的OnInit中的代码,取出Online,找到该用户对应的SessionID,判断SessionID里对应的用户名是否变更,如果变更,就强迫下线,清掉Session,转到Login画面。
最后需要在Session过期或者退出系统时释放资源,在Global.asax文件中的Session_End中添加如下代码:

Hashtable hOnline = (Hashtable)Application["Online"];
if(hOnline[Session.SessionID] != null)
{
hOnline.Remove(Session.SessionID);
Application.Lock();
Application["Online"] = hOnline;
Application.UnLock();
}

如果用户不正常退出后重登录,因为重登录的优先级大,不会影响用户的登录,而不正常退出的用户占用的资源会在Session过期后自动清除,不会影响系统的性能。
为保证WEB系统安全,需要具有单点登录检测功能,Google了一下做了小小修改。
1)密码验证后:

Hashtable hOnline = (Hashtable)Application["Online"];
if (hOnline != null)
{
int i = 0;
while (i<hOnline.Count) //因小BUG所以增加此判断,强制查询到底
{
IDictionaryEnumerator idE = hOnline.GetEnumerator();
string strKey = "";
while (idE.MoveNext())
{
if (idE.Value != null && idE.Value.ToString().Equals(this.username.Text))
{
//already login
strKey = idE.Key.ToString();
hOnline[strKey] = "XXXXXX";
break;
}
}
i = i + 1;
}
}
else
{
hOnline = new Hashtable();
}
hOnline[Session.SessionID] = this.username.Text;
Application.Lock();
Application["Online"] = hOnline;
Application.UnLock();
//用户登录的时候将登录用户名放在一个全局变量Online,Online为Hashtable结构,
//Key为SessionID,Value为用户名。每次用户登录时均判断以下要登录的用户名在Online中是不是已经存在,
//如果存在该用户名已经被登录,将第一个人登录的SessionID对应的用户名强制变更为XXXXXX,表示该登录将被强制注销

2)建立一个CommonPage页,系统中所有的页面都继承于CommonPage页(public partial class index : CommonPage),在CommonPage页的后台代码中添加如下代码:

using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.Collections;
/// <summary>
/// CommonPage 防止用户多点登录
/// </summary>
public class CommonPage: System.Web.UI.Page
{
public CommonPage()
{
//
// TODO: 在此处添加构造函数逻辑
//
}
override protected void OnInit(EventArgs e)
{
Hashtable hOnline = (Hashtable)Application["Online"];
if (hOnline != null)
{
IDictionaryEnumerator idE = hOnline.GetEnumerator();
while (idE.MoveNext())
{
if (idE.Key != null && idE.Key.ToString().Equals(Session.SessionID))
{
//already login
if (idE.Value != null && "XXXXXX".Equals(idE.Value.ToString()))
{
hOnline.Remove(Session.SessionID);
Application.Lock();
Application["Online"] = hOnline;
Application.UnLock();
string js = "<script language=javascript>alert('{0}');window.location.replace('{1}')</script>";
Response.Write(string.Format(js, "帐号已在别处登录 ,你将被强迫下线(请保管好自己的用户密码)!", "logout.aspx?cname=noadmin")); return;
}
break;
}
}
}
}
}

继承于CommonPage的页面在刷新时都要执行重载的OnInit中的代码,取出Online,找到该用户对应的SessionID,判断SessionID里对应的用户名是否变更,如果变更,就强迫下线,清掉Session,转到Login画面。
3)最后需要在Session过期或者退出系统时释放资源,在Global.asax文件中的Session_End中添加如下代码:

Hashtable hOnline = (Hashtable)Application["Online"];
if(hOnline[Session.SessionID] != null)
{
hOnline.Remove(Session.SessionID);
Application.Lock();
Application["Online"] = hOnline;
Application.UnLock();
}

Asp.net中实现同一用户名不能同时登录(单点登录)的更多相关文章
- (转) Asp.net中实现同一用户名不能同时登录
最近找了一些单点登录的,发现了这篇文章,貌似还是可以实现的,先保存了. Web 项目中经常遇到的问题就是同一用户名多次登录的问题,相应的解决办法也很多,总结起来不外乎这几种解决办法: 将登录后的用 ...
- Asp.net中实现同一用户名同时登陆,注销先前用户(转)
Web 项目中经常遇到的问题就是同一用户名多次登陆的问题,相应的解决办法也很多,总结起来不外乎这几种解决办法:将登陆后的用户名放到数据库表中:登陆后的用 户名放到Session中:登陆后的用户名放到A ...
- ASP.NET中ajax验证用户名和邮箱是否重复
这个是前台显示的页面代码↓ <%@ Page Language="C#" AutoEventWireup="true" CodeFile="De ...
- 通过SessionID和用户名来保证同一个用户不能同时登录(单点登录)
可以通过SessionID和用户名来保证同一个用户不能同时登录的问题,下面程序模仿了QQ的登录,当登录后判断当前帐号是否已经登录,如果登录.则踢掉以前登录的用户. 1.通过Application全局变 ...
- 在Tomcat中配置单点登录
单点登录:Single Sign-On .概述 一旦你设置了realm和验证的方法,你就需要进行实际的用户登录处理.一般说来,对用户而言登录系统是一件很麻烦的事情,你必须尽量减少用户登录验证的次数.作 ...
- asp.net项目与开源单点登录项目CAS的结合
这段时间搞的一个asp.net mvc项目,采用了单点登录. 这个单点登录就是CAS,一个开源的JAVA项目.当然,这并不影响ASP.NET项目结合它来进行登录.因为各自分工不同:单点登录(管它是不是 ...
- 使用 CAS 在 Tomcat 中实现单点登录 http://www.ibm.com/developerworks/cn/opensource/os-cn-cas/
developerWorks 中国 技术主题 Open source 文档库 使用 CAS 在 Tomcat 中实现单点登录 单点登录(Single Sign On , 简称 SSO )是目前比较流行 ...
- ASP.NET中登录时记住用户名和密码(附源码下载)--ASP.NET
必需了解的:实例需要做的是Cookie对象的创建和对Cookie对象数据的读取,通过Response对象的Cookies属性创建Cookie,通过Request对象的Cookies可以读取Cookie ...
- asp.net中使用基于角色role的Forms验证
http://www.cnblogs.com/yao/archive/2006/06/24/434783.html asp.net中使用基于角色role的Forms验证,大致经过几下四步:1.配置系统 ...
随机推荐
- SingalR--demo
原文链接 : http://www.asp.net/signalr/overview/getting-started/tutorial-getting-started-with-signalr-and ...
- c++控制台程序实现定时器
#include "stdafx.h" #include <iostream> #include <Windows.h> using namespace s ...
- ubuntu16.4下用jexus部署asp.net core rtm
上篇文章介绍了下用vs发布部署到iis环境,今天说下ubuntu 下部署asp.net core,不需要安装.net core sdk,自带运行时方式部署,利用jexus服务器转发请求到asp.net ...
- 背水一战 Windows 10 (9) - 资源: 资源限定符概述, 资源限定符示例
[源码下载] 背水一战 Windows 10 (9) - 资源: 资源限定符概述, 资源限定符示例 作者:webabcd 介绍背水一战 Windows 10 之 资源 资源限定符概述 资源限定符示例 ...
- 【Java每日一题】20161121
package Nov2016.use01; class Test { public String getString(){ return "123"; } } package N ...
- flask-cors
https://github.com/corydolphin/flask-cors/blob/master/examples/app_based_example.py ""&quo ...
- java的spilt(“,”)方法bug处理
java split方法以逗号分隔如字符串",,,,,," 这样会得到一个空的数组 String str ={1,2,3,,,,, } String[] str1 =spilt(& ...
- 使用PDF.JS在线查看PDF
过程简单粗暴. 第一步:下载源码https://github.com/mozilla/pdf.js 第二步:将源码拷贝进项目中,可以新建一个PDFShow文件夹存放代码 第三步:修改viewer.js ...
- Scalaz(17)- Monad:泛函状态类型-State Monad
我们经常提到函数式编程就是F[T].这个F可以被视为一种运算模式.我们是在F运算模式的壳子内对T进行计算.理论上来讲,函数式程序的运行状态也应该是在这个运算模式壳子内的,也是在F[]内更新的.那么我们 ...
- HDU 5703 Desert 水题 找规律
已知有n个单位的水,问有几种方式把这些水喝完,每天至少喝1个单位的水,而且每天喝的水的单位为整数.看上去挺复杂要跑循环,但其实上,列举几种情况之后就会发现是找规律的题了= =都是2的n-1次方,而且这 ...