2009-10-14 87 views
1

我需要設置一個Asp.Net應用瓦特/窗體身份驗證,使其符合以下標準:ASP.Net - 窗體身份驗證設置特定的安全問題

  1. 用戶應該活動15分鐘後註銷
  2. 用戶應在24小時後註銷,不管活動的

我相信第一個可以像這樣在web.config來完成:

<authentication mode="Forms"> 
    <forms loginUrl="Login.aspx" timeout="15" slidingExpiration="true"/> 
</authentication> 

但是,你將如何去解決第二個要求?

回答

2

有一個詳細的article on MSDN,它解釋了Forms身份驗證的工作方式以及可用的配置選項。 基本上表單身份驗證使用cookie(除非你明確地告訴它不要)。因此,您可以將表單身份驗證Cookie的到期日期設置爲24小時。但有一個問題。您可能需要推出自己的會員代碼,因爲默認情況下,forms元素的timeout屬性也用於設置持久cookie的生命週期。而你不想那樣。您需要將Cookie的到期時間設置爲24小時。

它的工作方式是,在用戶登錄後,會創建表單身份驗證Cookie,然後將其與每個請求一起包括在內,直到其過期。 從鏈接的文章:

FormsAuthenticationTicket ticket = new FormsAuthenticationTicket(1, 
     "cookieName", 
     DateTime.Now, 
     DateTime.Now.AddHours(24), // value of time out property 
     false, 
     String.Empty, 
     FormsAuthentication.FormsCookiePath); 

Forms身份驗證使用:

if (Membership.ValidateUser(userName.Text, password.Text)) 
{ 
    if (Request.QueryString["ReturnUrl"] != null) 
    { 
     FormsAuthentication.RedirectFromLoginPage(userName.Text, false); 
    } 
    else 
    { 
     FormsAuthentication.SetAuthCookie(userName.Text, false); 
    } 
} 
else 
{ 
    Response.Write("Invalid UserID and Password"); 
} 

您可以使用FormsAuthenticationTicket類創建窗體身份驗證票: 成員資格提供驗證用戶時具有類似下面的代碼用於加密和簽署表格認證票證的加密方法:

string encryptedTicket = FormsAuthentication.Encrypt(ticket); 

Cre吃餅乾:

HttpCookie authCookie = new HttpCookie(
          FormsAuthentication.FormsCookieName, 
          encryptedTicket); 

餅乾添加到Cookie集合:

Response.Cookies.Add(authCookie); 

這應該是它。

您可能需要推出自己的Cookie,因爲默認情況下,您爲forms指定的timeout屬性是用於cookie超時的屬性。 所以在你的例子:

<authentication mode="Forms"> 
    <forms loginUrl="Login.aspx" timeout="15" slidingExpiration="true"/> 
</authentication> 

cookie的超時時間爲15分鐘也。 在您的案例中,更簡單的方法可能是使用會話變量來處理強制執行的24小時超時。因爲如果用戶在此期間實際上處於活動狀態(否則它將從Cookie中超時),您只會觸及該狀態。所以你可以終止一個會話,如果已經活動超過24小時。

2

我不認爲ASP.Net中的表單身份驗證有任何內置來處理此問題。

您可以創建一個全球性的應用類(Global.asax中),處理在session_start事件,並存儲日期/時間在會話變量,像這樣:

public void Session_Start(object s, EventArgs e) 
{ 
    Session["LoginDate"] = DateTime.Now; 
} 

然後,您可以處理OnBeginRequest事件檢查會話變量和當前的日期/時間之間的區別:

public void Application_OnBeginRequest(object s, EventArgs e) 
{ 
    if (Session["LoginDate"] != null) 
    { 
     var loginDate = (DateTime)Session["LoginDate"]; 
     if ((DateTime.Now - loginDate).TotalHours >= 24) 
     { 
      Session.Abandon(); 
      Response.Redirect("~/Login.aspx"); 
     } 
    } 
} 

要處理OnBeginRequest事件,您可能需要創建一個自定義的HttpModule - 在這裏看到: http://msdn.microsoft.com/en-us/library/ms227673(VS.85).aspx

+0

Mircea有更好的解決方案! – 2009-10-14 14:06:02

+0

他和你很相似:我最終沿着這些線做了一些事情(實際上是作爲與會話相對的identity.name的一部分存儲的) – John 2009-10-14 14:24:02

1

好吧,作爲一個簡單的解決方案,您可以使用緩存的超時通知功能作爲「提醒」/回調,在創建它24小時後放棄會話。

void Session_Start(object sender, EventArgs e) 
{ 
    Cache.Add(Session.SessionID,Session,null,DateTime.Now.AddHours(24), 
    TimeSpan.Zero, CacheItemPriority.High, OnExpireSession) 
} 

public void OnExpireSession(String k, Object v, CacheItemRemovedReason r) 
{ 
    //uhm.. maybe do some checks if the session was already abandoned? 
    ((SessionState)v).Abandon(); 
}