[csharp] view plaincopy
  1. 最近找了一些单点登录的,发现了这篇文章,貌似还是可以实现的,先保存了。  
  2.    
  3. Web 项目中经常遇到的问题就是同一用户名多次登陆的问题,相应的解决办法也很多,总结起来不外乎这几种解决办法:将登陆后的用户名放到数据库表中;登陆后的用户名放到Session中;登陆后的用户名放到Application中;登陆后的用户名放到Cache中。一般的这几种方法都是登陆了之后,如果没有正常退出,第二次登陆将不被允许。这样一般都会存在一个问题:如果用户没有正常退出系统,那么他接下来继续登陆的时候,因为Session没有过期等问题,会被拒绝继续登陆系统,只能等待Session过期后才能登陆。本文介绍的方法是采用类似于MSN登陆的方法,第二次登陆时会把第一次的登陆注销掉,第一次登陆将会类似于MSN弹出:您的帐号已在别处被登陆,您被强迫下线的提示信息。  
  4. 功能实现起来也比较简单:   
  5. 登陆用户名密码验证通过之后输入以下代码:   
  6. Hashtable hOnline = (Hashtable)Application["Online"];  
  7. if(hOnline != null)   
  8. {   
  9. IDictionaryEnumerator idE = hOnline.GetEnumerator();  
  10. string strKey = "";   
  11. while(idE.MoveNext())   
  12. {   
  13. if(idE.Value != null && idE.Value.ToString().Equals(UserID))  
  14. {   
  15. //already login   
  16. strKey = idE.Key.ToString();   
  17. hOnline[strKey] = "XXXXXX";   
  18. break;   
  19. }   
  20. }   
  21. }   
  22. else   
  23. {   
  24. hOnline = new Hashtable();   
  25. }   
  26. hOnline[Session.SessionID] = UserID;   
  27. Application.Lock();   
  28. Application["Online"] = hOnline;   
  29. Application.UnLock();   
  30. 用户登陆的时候将登陆用户名放在一个全局变量Online,Online为Hashtable结构,Key为SessionID,Value为用户名。每次用户登陆时均判断以下要登陆的用户名在Online中是不是已经存在,如果存在该用户名已经被登陆,将第一个人登陆的SessionID对应的用户名强制变更为XXXXXX,表示该登陆将被强制注销。  
  31. 建立一个CommonPage页,系统中所有的页面都继承于CommonPage页,在CommonPage页的后台代码中添加如下代码:  
  32. override protected void OnInit(EventArgs e)  
  33. {   
  34. Hashtable hOnline = (Hashtable)Application["Online"];  
  35. if(hOnline != null)   
  36. {   
  37. IDictionaryEnumerator idE = hOnline.GetEnumerator();  
  38. while(idE.MoveNext())   
  39. {   
  40. if(idE.Key != null && idE.Key.ToString().Equals(Session.SessionID))  
  41. {   
  42. //already login   
  43. if(idE.Value != null && "XXXXXX".Equals(idE.Value.ToString()))  
  44. {   
  45. hOnline.Remove(Session.SessionID);   
  46. Application.Lock();   
  47. Application["Online"] = hOnline;   
  48. Application.UnLock();   
  49. MessageBox("你的帐号已在别处登陆,你被强迫下线!",Login.aspx);  
  50. return false;   
  51. }   
  52. break;   
  53. }   
  54. }   
  55. }   
  56. }   
  57. 继承于CommonPage的页面在刷新时都要执行重载的OnInit中的代码,取出Online,找到该用户对应的SessionID,判断SessionID里对应的用户名是否变更,如果变更,就强迫下线,清掉Session,转到Login画面。  
  58. 最后需要在Session过期或者退出系统时释放资源,在Global.asax文件中的Session_End中添加如下代码:  
  59. Hashtable hOnline = (Hashtable)Application["Online"];  
  60. if(hOnline[Session.SessionID] != null)  
  61. {   
  62. hOnline.Remove(Session.SessionID);   
  63. Application.Lock();   
  64. Application["Online"] = hOnline;   
  65. Application.UnLock();   
  66. }   
  67. 如果用户不正常退出后重登陆,因为重登陆的优先级大,不会影响用户的登陆,而不正常退出的用户占用的资源会在Session过期后自动清除,不会影响系统的性能。   
  68.   
  69. Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=2095105  
  70.   
  71. 关于WEB系统单点登陆问题  
  72. http://hi.baidu.com/fnhamwsc/blog/item/c70afc948c15581ad31b7074.html 2008年01月04日 星期五 08:19  
  73. 为保证WEB系统安全,需要具有单点登陆检测功能,Google了一下下,发现不少方法,最后根据水月神坛 zyc21st的专栏上的一篇文章《Asp.net中实现同一用户名不能同时登陆(单点登陆) 》实现,但使用过程中有个小BUG,所以做了小小修改。   
  74. 1)密码验证后:   
  75.                      Hashtable hOnline = (Hashtable)Application["Online"];   
  76.                      if (hOnline != null)   
  77.                      {   
  78.                       int i = 0;   
  79.                        while (i<hOnline.Count) //因小BUG所以增加此判断,强制查询到底  
  80.                          {   
  81.                          IDictionaryEnumerator idE = hOnline.GetEnumerator();   
  82.                          string strKey = "";   
  83.                          while (idE.MoveNext())   
  84.                          {   
  85.                              if (idE.Value != null && idE.Value.ToString().Equals(this.username.Text))  
  86.                              {   
  87.                                  //already login               
  88.                                  strKey = idE.Key.ToString();   
  89.                                  hOnline[strKey] = "XXXXXX";   
  90.                                  break;   
  91.                              }   
  92.                          }   
  93.                          i = i + 1;  
  94.                          }   
  95.                      }   
  96.                      else   
  97.                      {   
  98.                          hOnline = new Hashtable();   
  99.                      }   
  100.                      hOnline[Session.SessionID] = this.username.Text;   
  101.                      Application.Lock();   
  102.                      Application["Online"] = hOnline;   
  103.                      Application.UnLock();   
  104.                      //用户登陆的时候将登陆用户名放在一个全局变量Online,Online为Hashtable结构,   
  105.                      //Key为SessionID,Value为用户名。每次用户登陆时均判断以下要登陆的用户名在Online中是不是已经存在,  
  106.                      //如果存在该用户名已经被登陆,将第一个人登陆的SessionID对应的用户名强制变更为XXXXXX,表示该登陆将被强制注销  
  107.   
  108.   
  109. 2)建立一个CommonPage页,系统中所有的页面都继承于CommonPage页(public partial class index : CommonPage),在CommonPage页的后台代码中添加如下代码:  
  110. using System;   
  111. using System.Data;   
  112. using System.Configuration;   
  113. using System.Web;   
  114. using System.Web.Security;   
  115. using System.Web.UI;   
  116. using System.Web.UI.WebControls;   
  117. using System.Web.UI.WebControls.WebParts;   
  118. using System.Web.UI.HtmlControls;   
  119. using System.Collections;  
  120. /// <summary>   
  121. /// CommonPage 防止用户多点登陆   
  122. /// </summary>   
  123. public class CommonPage: System.Web.UI.Page   
  124. {   
  125.   
  126.      public CommonPage()   
  127. {   
  128.    //   
  129.    // TODO: 在此处添加构造函数逻辑   
  130.    //   
  131. }   
  132.    override protected void OnInit(EventArgs e)   
  133.      {   
  134.          Hashtable hOnline = (Hashtable)Application["Online"];   
  135.          if (hOnline != null)   
  136.          {   
  137.              IDictionaryEnumerator idE = hOnline.GetEnumerator();   
  138.              while (idE.MoveNext())   
  139.              {   
  140.                  if (idE.Key != null && idE.Key.ToString().Equals(Session.SessionID))  
  141.                  {   
  142.                      //already login   
  143.                      if (idE.Value != null && "XXXXXX".Equals(idE.Value.ToString()))  
  144.                      {   
  145.                          hOnline.Remove(Session.SessionID);   
  146.                          Application.Lock();   
  147.                          Application["Online"] = hOnline;   
  148.                          Application.UnLock();   
  149.                         string js = "<script language=javascript>alert('{0}');window.location.replace('{1}')</script>";  
  150.                          Response.Write(string.Format(js, "帐号已在别处登陆,你将被强迫下线(请保管好自己的用户密码)!""logout.aspx?cname=noadmin"));  
  151.   
  152.                          return;   
  153.                      }   
  154.                      break;   
  155.                  }   
  156.              }   
  157.          }   
  158.      }   
  159.   
  160. }   
  161.   
  162. 继承于CommonPage的页面在刷新时都要执行重载的OnInit中的代码,取出Online,找到该用户对应的SessionID,判断SessionID里对应的用户名是否变更,如果变更,就强迫下线,清掉Session,转到Login画面。  
  163. 3)最后需要在Session过期或者退出系统时释放资源,在Global.asax文件中的Session_End中添加如下代码:  
  164. Hashtable hOnline = (Hashtable)Application["Online"];   
  165.    if(hOnline[Session.SessionID] != null)   
  166.    {   
  167.      hOnline.Remove(Session.SessionID);   
  168.      Application.Lock();   
  169.      Application["Online"] = hOnline;   
  170.      Application.UnLock();   
  171.    }   
  172. 如果用户不正常退出后重登陆,因为重登陆的优先级大,不会影响用户的登陆,而不正常退出的用户占用的资源会在Session过期后自动清除,不会影响系统的性能。  

转自:http://blog.csdn.net/anchenyanyue/article/details/6825036

 posted on 2013-07-10 09:06  纳米程序员  阅读(372)  评论(0编辑  收藏  举报