session丟失與解決辦法的資料

weixin_34262482發表於2008-04-18

可能的原因1:

win2003 server下的IIS6預設設定下對每個執行在預設應用池中的工作者程式都會經過20多個小時後自動回收該程式,造成儲存在該程式中的session丟失。

因為Session,Application等資料預設儲存在執行該Web應用程式的工作者程式中,如果回收工作者程式,則會造成丟失。

解決辦法:

修改配置,設定為不定時自動回收該工作者程式,比如設定為當超出佔用現有實體記憶體60%後自動回收

該程式。通過使用預設應用程式池,可以確保多個應用程式間互相隔離,保證由於一個應用程式的崩潰不會影響另外的Web應用程式。還可以使一個獨立的應用程式執行在一個指定的使用者帳號特權之下。

如果使用StateServer方式或者Sql Server資料庫方式來儲存Session,則不受該設定的影響。

可能的原因2:

系統要執行在負載平衡的 Web 場環境中,而系統配置檔案web.config中的Session狀態卻設定為InProc(即在本地儲存會話狀態),導至在使用者訪問量大時,Session常經超時的情況。引起這個現象的原因主要是因為使用者通過負載平衡IP來訪問WEB應用系統,某段時候在某臺伺服器儲存了Session的會話狀態,但在其它的WEB前端伺服器中卻沒有儲存Session的會話狀態,而隨著併發量的增大,負載平衡會當作路由隨時訪問空閒的伺服器,結果空閒的伺服器並沒有之前儲存的Session會話狀態。

解決辦法:
1.當您在負載平衡的 Web 場環境中執行 ASP.NET Web 應用程式時,一定要使用 SqlServer 或 StateServer 會話狀態模式,在專案中我們基於效能考慮並沒有選擇SqlServer模式來儲存Session狀態,而是選擇一臺SessionStateServer 伺服器來使用者的Session會話狀態。我們要在系統配置檔案web.config中設定如下:
<sessionState mode="StateServer" cookieless="false" timeout="240" stateConnectionString="tcpip=192.168.0.1:42424" stateNetworkTimeout="14400" />

還要新增一項
<machineKey validationKey="78AE3850338BFADCE59D8DDF58C9E4518E7510149C46142D7AAD7F1AD49D95D4" decryptionKey="5FC88DFC24EA123C" validation="SHA1"/>

2. 我們同時還要在SessionStateServer 伺服器中啟動ASP.NET State Service服務,具體設定:控制皮膚>>管理工具>>服務>>ASP.NET State Service,把它設為自動啟動即可。

3. 每臺前端WEB服務的Microsoft“Internet 資訊服務”(IIS)設定
             要在 Web 場中的不同 Web 伺服器間維護會話狀態,Microsoft“Internet 資訊服務”(IIS) 配置資料庫中 Web 站點的應用程式路徑(例如,\LM\W3SVC\2)與 Web 場中所有 Web 伺服器必須相同。大小寫也必須相同,因為應用程式路徑是區分大小寫的。在一臺 Web 伺服器上,承載 ASP.NET 應用程式的 Web 站點的例項 ID 可能是 2(其中應用程式路徑是 \LM\W3SVC\2)。在另一臺 Web 伺服器上,Web 站點的例項 ID 可能是 3(其中應用程式路徑是 \LM\W3SVC\3)。因此,Web 場中的 Web 伺服器之間的應用程式路徑是不同的。我們必須使Web 場Web 站點的例項 ID 相同即可。你可以在IIS中把某一個WEB配置資訊儲存為一個檔案,其他Web 伺服器的IIS配置可以來自這一個檔案。您如果想知道具體的設定請訪問Microsoft Support網站:

補充一些相關資料:
PRB: Session Variables Are Lost If You Use FRAMESET in Internet Explorer 6.0
http://support.microsoft.com/kb/323752/EN-US/#

PRB: Session Data Is Lost When You Use ASP.NET InProc Session State Mode
http://support.microsoft.com/?id=324772

PRB:如果您使用 SqlServer 或 StateServer 會話模式 Web 場中會丟失會話狀態
http://support.microsoft.com/default.aspx?scid=kb;zh-cn;325056

ASP.NET Session State FAQ
http://www.eggheadcafe.com/articles/20021016.asp

作者:Patrick Y. Ng
原文地址:http://forums.asp.net/7504/ShowPost.aspx
譯者:Tony Qu (來自BluePrint翻譯團隊)

原文最後一次更新:2004年9月21日

本文被分成兩部分:
1.“理解Session State模式”——幫助你理解三種Session State的不同之處
2. FAQ

1.理解Session State模式

儲存位置
InProc:session在伺服器中以活動物件方式儲存(aspnet_wp.exe)

StateServer: session被序列化並儲存在單獨的aspnet_state.exe的記憶體中。StateServer能夠執行在另一臺伺服器上

SQLServer: session被序列化並儲存在SQL Server中

效能:
InProc:最快,但是session資料越多,web伺服器上消耗的記憶體也越多,它可能影響效能。

StateServer:當儲存基本型別(如string,integer等)資料時,在同一個測試環境中它比InProc慢15%。如果你儲存大量物件,序列化和反序列化可能影響到效能

SQLServer:當儲存基本型別(如string,integer等)資料時,在同一個測試環境中它比InProc慢25%。它也有與StateServer一樣的序列化效能問題。

關於Out-of-Proc(OOP,非InProc)模式的效能提示
如果你使用OOP模式(即StateServer或SQLServer),session state中的序列化和反序列化物件將成為你的主要效能消耗之一。對於基本型別,ASP.NET通過一種內部優化方法來完成序列化和反序列化。(基本型別包括所有的數字型別(如Int, Byte, Decimal,String, DateTime, TimeSpan, Guid, IntPtr和UIntPtr等))

如果你有一個session變數(如一個ArrayList物件),且它不是一個基本型別,ASP.NET將使用BinaryFormatter來進行序列化和反序列化,那可能會相對慢一些。

所以出於效能考慮,最好使用上面列出的基本型別來儲存所有的session state資料。例如,如果你需要儲存兩個東西,名字和地址,在session state中你既可以(方法a)使用兩個string session變數來儲存它們,也可以(方法b)建立一個內含兩個string的類來儲存它們,然後把這個類物件儲存在一個session變數中。出於效能考慮,你應該選擇方法a。

為了進一步理解這個主題,請看FAQ中的一個問題:“序列化和反序列化如何在SqlServer和StateServer模式下工作”

健壯性
InProc:如果工作者程式(aspnet_wp.exe)進行資源回收或者應用程式域(appdomain)重啟動,session state就會丟失。這是因為session state是儲存在一個應用程式域的記憶體空間中的。對配置檔案(如web.config和machine.config)的修改或者\bin目錄的任何改變(例如在你使用VS編譯應用程式後產生了一個新的dll)都可能引起重啟動,詳細請見KB324772。在1.0中,也有一個bug可能引起工作者程式重啟動,但這個bug在1.1中已經修復,見KB321792。

如果你使用的是IIS6.0,你可以在IIS Manager中找到Application Pools/DefaultAppPool,其中可以看到回收(Recycling)選項卡與效能(Performace)選項卡中是否有引起IIS工作者程式(w3svc.exe)停止工作的引數。

更多有關應用程式資源回收的內容,可以看我的另一篇FAQ:
http://www.asp.net/Forums/ShowPost.aspx?tabindex=1&PostID=232621

StateServer:解決了InProc模式的session state丟失問題。允許一個webfarm在中央伺服器中儲存session。只能在State Server上出現失敗。

SQLServer:與StateServer相似。session state的資料在SQL Server重啟後仍然保留著,你也可以按照KB311209的步驟使用SQL server failover cluster

警告
InProc:它不能在web garden模式下工作,因為在這個模式下會有多個aspnet_wp.exe在同一臺機器上執行。建議在使用web garden使切換到State Server或SQL Server。僅在InProc模式下支援Session_End事件。

StateServer
- 在web farm中,請確認在所有的web伺服器上有相同的<machineKey>。KB313091描述瞭如何設定它。
- 請確保你的物件是可序列化的。詳見KB312112
- 為了在web farm中的不同web伺服器上維護session state,IIS Metabase中的網站應用程式路徑(如\LM\W3SVC\2)應該在所有的伺服器上保持一致(大小寫敏感)。詳見KB325056

SQLServer
- 在1.0中有一個bug,如果你在連線字串中指定integrity security(如"trusted_connection=true"或 "integrated security=sspi"),且你開啟了asp.net的身份模擬,它將不會工作。這個問題在KB324479中有描述,不幸的是這份文件中的描述和原因部分是錯誤的。不過已經有一個QFE fix對它作了修復,這個fix將包含在1.0 sp3中。這個問題在1.1中已經修復了。
- 請確認你的物件是可序列化的,否則你的請求可能被掛住,詳見KB312112。SQLServer模式的掛起問題已經在1.1中修復,KB324479的QFE fix也修復了這個問題。1.0 sp3也對這個問題作了修復。
- 為了在web farm中的不同web伺服器上維護session state,IIS Metabase中的網站應用程式路徑(如\LM\W3SVC\2)應該在所有的伺服器上保持一致(大小寫敏感)。詳見KB325056

其他資源
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnaspp/html/aspnetsessionstate.asp
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnbda/html/CachingArchch2.asp
http://www.411asp.net/home/tutorial/specific/web/sessions

2. FAQ問題列表
Q: session state在部分瀏覽器上工作,而在其他一些上不工作。為什麼呢?
Q: 在InProc模式中,為什麼我有時會丟失所有的session?
Q: session state在一些web伺服器上工作,但是在其他伺服器上不工作。
Q: 為什麼session state不可用?
Q: 為什麼session_end沒有觸發?
Q: 使用InProc模式時,為什麼我的session變數頻繁丟失?
Q: 在session超時或刪除之後,為什麼SessionID保持不變
Q: 為什麼SessionID每一次請求都會改變
Q: Session.Abandon()和Session.Clear()有什麼區別
Q: session的Timeout屬性是一個滑動超時值嗎?
Q: 我可以在ASP.NET和ASP之間共享session嗎?
Q: 我可以在web應用程式(例如虛擬目錄或者IIS的應用程式)間共享session state嗎?
Q: 在session state中可以儲存哪些型別的物件?
Q: 為什麼我的請求在切換到SQLServer模式之後掛住了?
Q: 為什麼Response.Redirect和Server.Transfer在Session_End中不工作?
Q: 在Session_End中,我可以獲得一個有效的HttpSessionState物件和HttpContext物件嗎?
Q: 在web service中如何使用session?
Q:我正在寫一個HttpHandler,為什麼session stae不工作?
Q: 我正在使用web farm,並且每當我重定向到其他伺服器時,session state就會丟失?
Q: 如果使用cookieless,我該如何從一個HTTP頁面重定向到一個HTTPS頁面?
Q: session state有沒有一個鎖機制來安排對session的訪問順序?
Q: 我該如何檢測一個session過期,然後重定向到另一個頁面
Q: 在Session_End中,我嘗試使用SQL做一些清理工作,但是失敗了,請問為什麼?
Q: 我使用的是SQLServer模式,為什麼我的session不會過期
Q: 我有一個以htm為副檔名的frameset頁面,並且我發覺其中包含的每個幀在第一次請求時都有一個不同的SessionID,這是為什麼?
Q: 我將EnableSessionState設定為ReadOnly,但是在InProc模式下,我仍然可以修改session,為什麼?
Q: 我將cookieless設定為true,在Redirect之後session變數丟失了,為什麼?
Q: 將cookieless設定為true有哪些缺點
Q: 在InProc模式下,我用程式設計方式改變了session的超時時間,它觸發了Session_End,為什麼?
Q: 在SQLServer模式下,我可以把session state儲存在除tempdb之外的資料庫中嗎?
Q: 如何防止將未加密的字串放在我的連線字串彙總?
Q: 在使用SQLServer模式時,我需要怎樣的SQL許可權?
Q: 我可以自己寫定製的session state模式嗎?
Q: 在SQLServer或StateServer模式下,序列化和反序列化如何工作?
Q: 我該如何讓我的state server更安全?
Q: 我能否可以使用非global.asax中的處理程式來訂閱SessionStateModule.End事件?
Q: 不同的應用程式可以把他們的session state儲存在同一個SQL Server上的不同資料庫中嗎?


Q: session state在部分瀏覽器上工作,而在其他一些上不工作。為什麼呢?
A: 估計你沒有使用cookieless,你必須保證你的瀏覽器支援cookie。請參考這份KB:http://support.microsoft.com/default.aspx?scid=kb;EN-US;q316112

Q: 在InProc模式中,為什麼我有時會丟失所有的session?
A: 請見理解session state模式的健壯性部分

Q: session state在一些web伺服器上工作,但是在其他伺服器上不工作。
A: 可能是機器名的問題,見http://support.microsoft.com/default.aspx?scid=kb;EN-US;q316112

Q: 為什麼session state不可用?
A:
- 首先,檢查web.config、machine.config和Page標籤來確認你啟用了session state
參考資料:
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpguide/html/cpconsessionstate.asp
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpgenref/html/cpconpage.asp
- 請注意session state並非在任何地方、任何時間都可以使用,它僅在HttpApplication.AcquireRequestState事件之後可用。例如,在 global.asax中的Application_OnAuthenticateRequest處理程式中,session state不可用
- 請確認System.Web.SessionState.SessionStateModule已包含在配置檔案的< httpModules>節中。一個常見的例子是,出於效能考慮,SharePoint應用程式會把這個模組從web.config檔案中移除,因此導致session不可用

Q: 為什麼session_end沒有觸發?
A: 這是最常見的問題之一
1. 請記住session_end僅在InProc模式中可用
2. 關閉瀏覽器,session_end是不會觸發的。HTTP是一種無狀態協議,伺服器沒有辦法知道你的瀏覽器是否已經關閉。
3. 當有n分鐘(n=timeout值)的無操作或呼叫Session.Abandon時,Session_End才會觸發
4. 對於情況1而言,Session_End將由一個後臺執行緒觸發,這表示:
a. Session_End中的程式碼使用工作者程式賬號執行,如果你訪問如資料庫這樣的資源時,可能會有許可權問題。
b. 如果在Session_End中發生錯誤,程式不會通知發生了什麼
5. 對於情況2而言,為了讓Session_End觸發,session state必須先存在。這意味著你必須在session state中儲存一些資料,並且已經完成了至少一個請求
6. 還是對於情況2而言,Session_End僅在被丟棄的session被找到的時候才會觸發。這樣的話,如果你在同一個請求中建立並丟棄一個 session,由於session沒有被儲存,因此也不會被找到,Session_End將不會被呼叫。這是v1.0和v1.1中的bug。

Q: 使用InProc模式時,為什麼我的session變數頻繁丟失?
A: 有可能是應用程式資源回收引起的,見http://support.microsoft.com/default.aspx?scid=kb;en-us;Q316148
在v1.0中有一個bug可能會導致工作者程式重啟動。在v1.1和v 1.0sp2中已經修復。見http://support.microsoft.com/default.aspx?scid=kb;EN-US;321792

關於應用程式資源回收的詳細資訊,請見我的另一篇:FAQhttp://www.asp.net/Forums/ShowPost.aspx?tabindex=1&PostID=232621

Q: 在session超時或刪除之後,為什麼SessionID保持不變
A: 儘管在超時週期之後session state過期,sessionID將一直保持到瀏覽器session過期為止,也就是說,一個相同的sessionID可以有多次session超時,但是始終對應著一個相同的瀏覽器例項。

Q: 為什麼SessionID每一次請求都會改變
A: 如果你的應用程式從未在session state中儲存過資料。在這種情況下,那麼每次請求都會建立一個新的session state(ID也是新的),但是不會被儲存,因為裡面什麼資料都沒有。

儘管如此,有兩種例外可能產生相同的Session ID
- 如果使用者使用相同的瀏覽器例項來請求另一個使用session state的頁面,那麼你每次獲得的Session ID是相同的。詳見“在session超時或刪除之後,為什麼SessionID保持不變?”
- 如果使用了Session_OnStart事件,即使session為空,asp.net也會儲存session state。

Q: Session.Abandon()和Session.Clear()有什麼區別
A: 主要的區別在於,如果你呼叫Session.Abandon(), Session_End將被觸發(僅在InProcxi下適用),在下一個請求中,Session_Start觸發。而Session.Clear()僅僅是清除資料,但沒有刪除session。

Q: session的Timeout屬性是一個滑動超時值嗎?
A: Session的Timeout是一個滑動過期時間,意思是一旦你的頁面訪問session state,過期時間就會向挪。注意,只要頁面沒有被禁用,在請求時頁面就會自動訪問session

Q: 我可以在ASP.NET和ASP之間共享session嗎?
A:不可以。但是有一篇文章講到了如何來繞過這個問題:http://www.msdn.microsoft.com/library/default.asp?url=/library/en-us/dnaspp/html/ConvertToASPNET.asp

當然也有一些第三方解決方案。

Q: 我可以在web應用程式(例如虛擬目錄或者IIS的應用程式)間共享session state嗎?
A:不能。

Q: 在session state中可以儲存哪些型別的物件?
A:這是由你使用的模式決定的
- 如果你使用的是InProc模式,儲存在session state中的物件是活物件,那麼你就可以儲存你建立的任何物件
- 如果你使用的是SQLServer或State Server模式,當處理一個請求時,session state中的物件物件將被序列化和反序列化,所以請確認你的物件都是可序列化的,而它們的類都作了可序列化標記。如果沒有,session state將不會成功儲存。在v1.0中,有一個bug,當這個問題發生時,如果使用SQLServer模式,請求可能在不知情的情況下被掛起。掛起的問題在v1.1和v1.0 sp3中已經修復。KB324479的QFE fix也包含了對這一問題的修復。

更多資訊請見:http://support.microsoft.com/directory/article.asp?ID=KB;EN-US;q312112

Q: 為什麼我的請求在切換到SQLServer模式之後掛住了?
A:請看問題“在session state中可以儲存哪些型別的物件?”的答案

Q: 為什麼Response.Redirect和Server.Transfer在Session_End中不工作?
A:Session_End是在伺服器內部觸發的,它基於一個內部的計時器。因此,在事件觸發時,與任何HttpRequest物件無關。這也是為什麼Response.Redirect 和Server.Transfer不工作的原因。

Q: 在Session_End中,我可以獲得一個有效的HttpSessionState物件和HttpContext物件嗎?
A: 你可以獲得httpSessionState物件,你可以使用'Session'來訪問該物件。但是你無法訪問HttpContext,因為這個事件和請求沒有任何關係。

Q: 在web service中如何使用session?
A: 需要在呼叫方使用一些技巧,你必須儲存web服務使用的cookie。請見關於HttpWebClientProtocol.CookieContainer的MSDN文件。

儘管如此,如果你是通過代理物件從你的頁面呼叫web服務,由於架構限制,web服務和你的頁面無法共享session state。


如果你通過redirect呼叫web服務,這是可以完成的


Q:我正在寫一個HttpHandler,為什麼session stae不工作?

A: 你的HttpHandler介面必須實現標記介面IRequiresSessionState或IReadOnlySessionState,方能使用session state。


Q: 我正在使用web farm,並且每當我重定向到其他伺服器時,session state就會丟失?
A: 為了在web farm中的不同伺服器之間維護session state,IIS Metabase中的網站應用程式路徑(例如 \LM\W3SVC\2)應該在所有的web伺服器上保持一致(大小寫敏感)。詳見KB325056


Q: 如果使用cookieless,我該如何從一個HTTP頁面重定向到一個HTTPS頁面?
A: 嘗試使用下面的程式碼:
String originalUrl = "/fxtest3/sub/foo2.aspx";
String modifiedUrl = "https://localhost" + Response.ApplyAppPathModifier(originalUrl);
Response.Redirect(modifiedUrl);


Q: session state有沒有一個鎖機制來安排對session的訪問順序?
A:session state實現了讀寫鎖定機制:
- 對session state有寫許可權(如<%@ Page EnableSessionState="True" %> )的頁面或幀將獲得這個session的寫鎖,直到請求結束。
- 對session state有讀許可權(如<%@ Page EnableSessionState="ReadOnly" %> )的頁面或幀將獲得這個session的讀鎖,直到請求結束。
- 讀鎖會阻塞寫鎖;讀鎖不會阻塞讀鎖;寫鎖會阻塞所有的讀鎖和寫鎖
- 這也是為什麼當兩個幀同時擁有session的訪問許可權時,一個幀必須等待另一幀先完成


Q: 我該如何檢測一個session過期,然後重定向到另一個頁面
A: 這是經常要遇到的問題,但不幸的是沒有很簡單的方法來完成它。我們將期待在一個主要版本中實現它。同時,如果你使用cookie,你可以在cookie中儲存一個標誌,這樣你就可以區分新瀏覽器+新session及舊瀏覽器+過期session,下面的程式碼在session過期時會重定向到一個過期頁面。
void Session_OnStart(Object sender, EventArgs e) {
    HttpContext context = HttpContext.Current;
    HttpCookieCollection cookies = context.Request.Cookies;

    if (cookies["starttime"] == null) {
        HttpCookie cookie = new HttpCookie("starttime", DateTime.Now.ToString());
        cookie.Path = "/";
        context.Response.Cookies.Add(cookie);
    }
    else {
        context.Response.Redirect("expired.aspx");
    }
}

Q: 在Session_End中,我嘗試使用SQL做一些清理工作,但是失敗了,請問為什麼?
A: 首先,session_End僅在InProc模式下支援。
第二,Session_End是用執行工作者程式(aspnet_wp.exe)的帳號執行的,這個賬號可以在machine.config中指定。因此,在你的Session_End中,如果使用integrity security連線SQL,它將使用工作者程式賬號身份連線,這可能會引起登入失敗,這要看你的SQL安全設定了。


Q: 我使用的是SQLServer模式,為什麼我的session不會過期
A: 在SQLServer模式下,session過期是由SQL Agent使用一個註冊任務完成的,請確認你的SQL Agent是否已經執行。

Q: 我有一個以htm為副檔名的frameset頁面,並且我發覺其中包含的每個幀在第一次請求時都有一個不同的SessionID,這是為什麼?
A: 原因是你的frameset頁面是一個htm檔案而不是一個aspx頁面

在通常情況下,如果一個frameset頁為一個aspx檔案,當你請求該頁面時,會首先發請求給web伺服器,你會收到一個asp.net session cookie(其中儲存著session id),然後瀏覽器會為frame傳送一個單獨的請求,而每個請求將擁有相同的session id。

然而,因為你的頁面是一個htm檔案,第一個請求就不會獲得任何session cookie,因為頁面是由asp處理的而非asp.net,然後瀏覽器會為每個幀傳送單獨的請求。但是,這次每個單獨的請求將不會持有任何 session id,這樣的話每個幀將建立自己的session。這也是為什麼你在每個幀中看到的session id都不同。最後一個請求將贏得勝利,因為它將覆蓋前兩個請求寫入的cookie。如果你重新整理一次,你將看到它們擁有了相同的session id。

這個行為是設計所決定的,簡單的解決方法就是將frameset頁面改稱aspx

Q: 我將EnableSessionState設定為ReadOnly,但是在InProc模式下,我仍然可以修改session,為什麼?
A: 儘管那些EnableSessionState被設定為ReadOnly,但是在InProc模式中,使用者仍然可以修改session。唯一的區別在於session在請求中不會被鎖住,這一限制是設計所決定的。對於這一點沒有在msdn中提到我表示抱歉。

Q: 我將cookieless設定為true,在Redirect之後session變數丟失了,為什麼?
A: 如果你使用的是cookieless,你必須使用相對路徑(如..\hello.aspx),而不是絕對路徑(如\foo\bar\hello.aspx)。如果你使用的是絕對路徑,ASP.NET不會將session id儲存在url中。

Q: 將cookieless設定為true有哪些缺點
A: 設定cookieless=true表示一些潛在的規則,主要有:
1. 你不能在你的頁面中使用絕對路徑
2. 在http和https之間切換的話,你必須做一些額外的動作
3. 如果你的客戶傳送了一個連結到一個朋友,URL將包含session id,兩個使用者可以在同一時間使用相同的session id

Q: 在InProc模式下,我用程式設計方式改變了session的超時時間,它觸發了Session_End,為什麼?
A: 這是InProc的一個bug。如果你更改session的timeout值為另一個值,Session_End將被呼叫(但不會呼叫Session_Start)。我們期待在v2.0中能夠修復這個錯誤。

Q: 在SQLServer模式下,我可以把session state儲存在除tempdb之外的資料庫中嗎?
A: 是的。見KB311209。

Q: 如何防止將未加密的字串放在我的連線字串彙總?
A: 見sql trusted connection或者將連線字串以加密資料形式儲存在登錄檔中。詳情請見,KB329250和KB329290。

Q: 在使用SQLServer模式時,我需要怎樣的SQL許可權?
A: 呼叫者需要對下面的儲存過程擁有EXEC許可權,
dbo.TempGetAppID
dbo.TempGetStateItem
dbo.TempGetStateItemExclusive
dbo.TempReleaseStateItemExclusive
dbo.TempInsertStateItemLong
dbo.TempInsertStateItemShort
dbo.TempUpdateStateItemLong
dbo.TempUpdateStateItemShort
dbo.TempUpdateStateItemShortNullLong
dbo.TempUpdateStateItemLongNullShort
dbo.TempRemoveStateItem
dbo.TempResetTimeout
在v1.1中,你也需要對下面的儲存過程擁有EXEC許可權
dbo.TempGetStateItem2
dbo.TempGetStateItemExclusive2


請注意儲存過程的擁有者必須對session state表(dbo.ASPStateTempSessions和 dbo.ASPStateTempApplications)擁有SELECT/INSERT/UPDATE/DELETE 許可權。通常,擁有者是執行installsqlstate.sql(或者持久版本,見KB311209)的帳號來安裝sql session state需要的表、儲存過程、資料庫


也請注意,如果你的session state表在tempdb中(預設情況下)如果你對SQL Server進行資源回收,所有在這張表上的許可權設定將丟失。

Q: 我可以自己寫定製的session state模式嗎?
A:(待翻譯)

Q: 在SQLServer或StateServer模式下,序列化和反序列化如何工作?
A: (待翻譯)

Q: 我該如何讓我的state server更安全?
A:如果state server和web server執行在一臺機器上,通過設定HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\ aspnet_state\Param ters\AllowRemoteConnection的dword項為0,可以讓state server僅在本地執行。這樣就可以防止遠端客戶端連見到state server上。這一特性在v1.1中可用,在v1.0 sp3中也有。

state server必須受防火牆保護,以防止外部連線以保證真正安全。預設的埠是TCP 42424,你可以設定HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\ aspnet_state\Param ters\Port來改變它。如果是本地模式,除了127.0.0.1以外,遮蔽所有外來連線;如果是遠端模式,顯式的禁用所有的地址,除了對wev伺服器的連線。


使用IPSec是另一種保護state server的方式。


Q: 我能否可以使用非global.asax中的處理程式來訂閱SessionStateModule.End事件?
A: 答案是否定的。當SessionStateModule觸發End事件時,只有定義在global.asax中的方法才會被觸發

這是出於安全原因考慮的才對此進行限制。假設asp.net允許使用者使用的其他的處理程式來處理End事件。在這種情況下,使用者通常使用一個頁面方法作為處理程式,當你在事件訂閱時傳入處理程式,處理程式將與你的程式執行在的HttpApplication例項關聯。請注意, HttpApplication例項會被回收來處理其他請求。這樣的話,當End事件觸發時,asp.net將呼叫處理程式,而與之關聯的 HttpApplication例項已經被另一個請求所使用,這樣的情況將引發各種各樣的問題。為了避免這種危險,在v1.0中決定進呼叫 Global.asax中定義的方法。希望你們都可以忍受這一限制。

Q: 不同的應用程式可以把他們的session state儲存在同一個SQL Server上的不同資料庫中嗎?
A: 答案是肯定的。詳情請見:http://support.microsoft.com/default.aspx?scid=kb;EN-US;836680

相關文章