Asp.net中实现同一用户名不能同时登录(单点登录)

最近找了一些单点登录的,发现了这篇文章,貌似还是可以实现的,先保存了。

Web 项目中经常遇到的问题就是同一用户名多次登录的问题,相应的解决办法也很多,总结起来不外乎这几种解决办法:

将登录后的用户名放到数据库表中;

登录后的用户名放到Session中;

登录后的用户名放到Application中;

登录后的用户名放到Cache中。

    一般的这几种方法都是登录了之后,如果没有正常退出,第二次登录将不被允许。这样一般都会存在一个问题:如果用户没有正常退出系统,那么他接下来继续登录的时候,因为Session没有过期等问题,会被拒绝继续登录系统,只能等待Session过期后才能登录。本文介绍的方法是采用类似于MSN登陆的方法,第二次登录时会把第一次的登录注销掉,第一次登录将会类似于MSN弹出:您的帐号已在别处被登录,您被强迫下线的提示信息。
功能实现起来也比较简单:
登录用户名密码验证通过之后输入以下代码:

[csharp] view plaincopyprint?

  1. Hashtable hOnline = (Hashtable)Application["Online"]; 
  2. if(hOnline != null)  
  3. {  
  4. IDictionaryEnumerator idE = hOnline.GetEnumerator(); 
  5. string strKey = "";  
  6. while(idE.MoveNext())  
  7. {  
  8. if(idE.Value != null && idE.Value.ToString().Equals(UserID)) 
  9. {  
  10. //already login  
  11. strKey = idE.Key.ToString();  
  12. hOnline[strKey] = "XXXXXX";  
  13. break;  
  14. }  
  15. }  
  16. }  
  17. else  
  18. {  
  19. hOnline = new Hashtable();  
  20. }  
  21. hOnline[Session.SessionID] = UserID;  
  22. Application.Lock();  
  23. Application["Online"] = hOnline;  
  24. Application.UnLock();  
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页的后台代码中添加如下代码:

[csharp] view plaincopyprint?

  1. override protected
    void OnInit(EventArgs e) 
  2. {  
  3. Hashtable hOnline = (Hashtable)Application["Online"]; 
  4. if(hOnline != null)  
  5. {  
  6. IDictionaryEnumerator idE = hOnline.GetEnumerator(); 
  7. while(idE.MoveNext())  
  8. {  
  9. if(idE.Key != null && idE.Key.ToString().Equals(Session.SessionID)) 
  10. {  
  11. //already login  
  12. if(idE.Value != null &&
    "XXXXXX".Equals(idE.Value.ToString())) 
  13. {  
  14. hOnline.Remove(Session.SessionID);  
  15. Application.Lock();  
  16. Application["Online"] = hOnline;  
  17. Application.UnLock();  
  18. MessageBox("你的帐号已在别处登录,您被强迫下线!",Login.aspx); 
  19. return false;  
  20. }  
  21. break;  
  22. }  
  23. }  
  24. }  
  25. }  
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中添加如下代码:

[csharp] view plaincopyprint?

  1. Hashtable hOnline = (Hashtable)Application["Online"]; 
  2. if(hOnline[Session.SessionID] !=
    null) 
  3. {  
  4. hOnline.Remove(Session.SessionID);  
  5. Application.Lock();  
  6. Application["Online"] = hOnline;  
  7. Application.UnLock();  
  8. }  
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)密码验证后:

[csharp] view plaincopyprint?

  1. Hashtable hOnline = (Hashtable)Application["Online"];  
  2.                   if (hOnline !=
    null)  
  3.                   {  
  4.                    int i = 0;  
  5.                     while (i<hOnline.Count)
    //因小BUG所以增加此判断,强制查询到底 
  6.                       {  
  7.                       IDictionaryEnumerator idE = hOnline.GetEnumerator();  
  8.                       string strKey =
    "";  
  9.                       while (idE.MoveNext())  
  10.                       {  
  11.                           if (idE.Value !=
    null && idE.Value.ToString().Equals(this.username.Text)) 
  12.                           {  
  13.                               //already login            
     
  14.                               strKey = idE.Key.ToString();  
  15.                               hOnline[strKey] =
    "XXXXXX";  
  16.                               break;  
  17.                           }  
  18.                       }  
  19.                       i = i + 1; 
  20.                       }  
  21.                   }  
  22.                   else  
  23.                   {  
  24.                       hOnline = new Hashtable();  
  25.                   }  
  26.                   hOnline[Session.SessionID] = this.username.Text;  
  27.                   Application.Lock();  
  28.                   Application["Online"] = hOnline;  
  29.                   Application.UnLock();  
  30.                   //用户登录的时候将登录用户名放在一个全局变量Online,Online为Hashtable结构,
     
  31.                   //Key为SessionID,Value为用户名。每次用户登录时均判断以下要登录的用户名在Online中是不是已经存在, 
  32.                   //如果存在该用户名已经被登录,将第一个人登录的SessionID对应的用户名强制变更为XXXXXX,表示该登录将被强制注销 
   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页的后台代码中添加如下代码:

[csharp] view plaincopyprint?

  1. using System;  
  2. using System.Data;  
  3. using System.Configuration;  
  4. using System.Web;  
  5. using System.Web.Security;  
  6. using System.Web.UI;  
  7. using System.Web.UI.WebControls;  
  8. using System.Web.UI.WebControls.WebParts;  
  9. using System.Web.UI.HtmlControls;  
  10. using System.Collections; 
  11. /// <summary>  
  12. /// CommonPage 防止用户多点登录  
  13. /// </summary>  
  14. public class CommonPage: System.Web.UI.Page  
  15. {  
  16.      public CommonPage()  
  17. {  
  18.    //  
  19.    // TODO: 在此处添加构造函数逻辑  
  20.    //  
  21. }  
  22.    override protected
    void OnInit(EventArgs e)  
  23.      {  
  24.          Hashtable hOnline = (Hashtable)Application["Online"];  
  25.          if (hOnline !=
    null)  
  26.          {  
  27.              IDictionaryEnumerator idE = hOnline.GetEnumerator();  
  28.              while (idE.MoveNext())  
  29.              {  
  30.                  if (idE.Key !=
    null && idE.Key.ToString().Equals(Session.SessionID)) 
  31.                  {  
  32.                      //already login  
  33.                      if (idE.Value !=
    null && "XXXXXX".Equals(idE.Value.ToString())) 
  34.                      {  
  35.                          hOnline.Remove(Session.SessionID);  
  36.                          Application.Lock();  
  37.                          Application["Online"] = hOnline;  
  38.                          Application.UnLock();  
  39.                         string js =
    "<script language=javascript>alert('{0}');window.location.replace('{1}')</script>"; 
  40.                          Response.Write(string.Format(js,
    "帐号已在别处登录 ,你将被强迫下线(请保管好自己的用户密码)!",
    "logout.aspx?cname=noadmin")); 
  41.  
  42.                          return;  
  43.                      }  
  44.                      break;  
  45.                  }  
  46.              }  
  47.          }  
  48.      }  
  49. }  
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中添加如下代码:

[csharp] view plaincopyprint?

  1. Hashtable hOnline = (Hashtable)Application["Online"];  
  2.    if(hOnline[Session.SessionID] !=
    null)  
  3.    {  
  4.      hOnline.Remove(Session.SessionID);  
  5.      Application.Lock();  
  6.      Application["Online"] = hOnline;  
  7.      Application.UnLock();  
  8.    }   
时间: 2024-09-14 15:27:33

Asp.net中实现同一用户名不能同时登录(单点登录)的相关文章

Asp.net中实现同一用户名不能同时登陆(单点登陆)

asp.net Web项目中经常遇到的问题就是同一用户名多次登陆的问题,相应的解决办法也很多,总结起来不外乎这几种解决办法:将登陆后的用户名放到数据库表中:登陆后的用户名放到Session中:登陆后的用户名放到Application中:登陆后的用户名放到Cache中.一般的这几种方法都是登陆了之后,如果没有正常退出,第二次登陆将不被允许.这样一般都会存在一个问题:如果用户没有正常退出系统,那么他接下来继续登陆的时候,因为Session没有过期等问题,会被拒绝继续登陆系统,只能等待Session过

在 ASP.NET 中实现不同角色的用户使用不同登录界面的方法

很多用户在开发 ASP.NET 应用程序时都有这样的需求:管理员角色的账户使用管理员的登录界面进行登录,普通用户角色的账户使用普通用户的登录界面进行登录.由于ASP.NET的web.config里只能使用一个 authentication mode="Forms"节点,所以,要实现不同用户采用不同的登录界面,一个办法就是创建一个管理员专用的虚拟目录,并设置为应用程序来实现.下面介绍另外一种采用重定向的办法来解决这个问题. 本文介绍的方法原理是根据登录界面的返回地址进行判断,然后重定向到

企业门户应用整合中单点登录(SSO)的技术实现与应用

1 引 言 企业在信息化建设过程中,由于经常采用逐步信息化的方式,因此会造成企业内部各个应用系统的用户目录不完全兼容,各应用系统相互孤立,形成"信息孤岛".信息孤岛的存在,使得信息系统用户需要做重复的登录.因此实际中,需要一个统一的用户登录管理系统平台,来实现用户统一身份验证.用户登录到某一应用系统(通常是门户站点,如办公自动化系统)后,当需要访问其他应用系统时,不必登录就可以直接进入应用系统. 单点登录系统平台采用统一的用户信息数据库,实现用户统一验证.从用户的角度只需进行一次登录就

“.NET研究”SharePoint 2010中的单点登录

在SharePoint 2007时代我们可以通过Microsoft Single Sign-on Service来实现单点登录,但到了SharePoint 2010中不再有Single Sign-on这个服务了,取而代之的则是Secure Store Service简称SSS.与以前的SSO一样,SSS也提供了一个数据库实例来保存用于访问某些外部应用程序或外部数据源的用户凭据信息,所不同的是我们不仅可以使用SSS中保存的凭据信息来实现单点登录,同时BDC.Excel Service等服务应用程序

一起谈.NET技术,SharePoint 2010中的单点登录

在SharePoint 2007时代我们可以通过Microsoft Single Sign-on Service来实现单点登录,但到了SharePoint 2010中不再有Single Sign-on这个服务了,取而代之的则是Secure Store Service简称SSS.与以前的SSO一样,SSS也提供了一个数据库实例来保存用于访问某些外部应用程序或外部数据源的用户凭据信息,所不同的是我们不仅可以使用SSS中保存的凭据信息来实现单点登录,同时BDC.Excel Service等服务应用程序

SharePoint 2010中的单点登录

在SharePoint 2007时代我们可以通过Microsoft Single Sign-on Service来实现单点登录,但到了SharePoint 2010中不再有Single Sign-on这个服务了,取而代之的则是Secure Store Service简称SSS.与以前的SSO一样,SSS也提供了一个数据库实例来保存用于访问某些外部应用程序或外部数据源的用户凭据信息,所不同的是我们不仅可以使用SSS中保存的凭据信息来实现单点登录,同时BDC.Excel Service等服务应用程序

asp.net中登录页面用户名和密码与数据库中数据进行比对出错,求大神指导!!!!

问题描述 asp.net中登录页面用户名和密码与数据库中数据进行比对出错,求大神指导!!!! dr['AID']=112100011TextBox1.Text=1121000177 dr['apassword']=245fghTextBox2.Text=123456 dr['AID']=1121000177TextBox1.Text=1121000177 dr['apassword']= 123456TextBox2.Text=123456 用户名或密码不正确,请重新输入! 这是运行时页面打印出

asp.net中 web.config中连接用户名和密码是用什么加密的求解

问题描述 asp.net中 web.config中连接用户名和密码是用什么加密的求解 <add key="databaseconn_Server" value="173.231.20.198" /> <add key="databaseconn_DB" value="wws" /> <add key="databaseconn_User" value="5AC7376

ASP.NET中的session存储模式运用

在asp.net中的Session存储方式不象asp那样单一,一共提供了三种存储方式,由于最近一个2000多人使用的web软件出现了故障,用户每天早上在某一时刻出现难以登陆现象,接着Session丢值出现,只有重启IIS,或机器.这时程序恢复正常了. 整天都不会出现同样的问题 ,但是第二天依旧!这种现象持续了好几天,我检查了一下日志文件,高峰每秒访问人数大概20人左右,同时大概100多人在线,以后访问人数还会增加,为了解决这个怪问题,先从软件着手,故而三种方式都应用了一番. 打开web.conf