Asp.Netで同じユーザ名を実現しても同時にログインできない(単点ログイン)


最近いくつかの単点登録を探して、この文章を発見して、やはり実現することができるようで、先に保存しました.
Webプロジェクトでよく遭遇する問題は、同じユーザー名が複数回ログインする問題であり、対応する解決策も多く、これらの解決策にほかならない.
ログイン後のユーザー名をデータベーステーブルに配置します.
ログイン後のユーザー名はセッションに入れます.
ログイン後のユーザー名をアプリケーションに入れます.
ログインしたユーザー名をCacheに入れます.
一般的にこれらの方法はすべてログインした後、正常に終了しなければ、2回目のログインは許可されません.このように一般的には、ユーザーが正常にシステムを終了していない場合、彼がログインを継続している間に、Sessionが期限切れになっていないなどの問題があり、ログインシステムの継続を拒否され、Sessionが期限切れになってからログインするしかないという問題があります.本明細書で説明する方法は、MSNログインと同様の方法を採用し、2回目のログイン時に1回目のログインをログアウトし、1回目のログインは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はユーザ名にします.ユーザーがログインするたびに、以下のログインするユーザー名がオンラインに既に存在するか否かを判断し、そのユーザー名が既にログインされている場合は、第一人者がログインした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画面に移る.
最後に、GlobalでSessionが期限切れまたはシステムを終了するときにリソースを解放する必要がある.asaxファイルのセッション_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)最後に、GlobalでSessionが期限切れまたはシステムを終了するときにリソースを解放する必要がある.asaxファイルのセッション_Endに次のコードを追加します.
Hashtable hOnline = (Hashtable)Application["Online"]; 
   if(hOnline[Session.SessionID] != null) 
   { 
     hOnline.Remove(Session.SessionID); 
     Application.Lock(); 
     Application["Online"] = hOnline; 
     Application.UnLock(); 
   }