2008-11-04 53 views
3

我試圖實現「編寫信息到用戶數據」部分this article,但它在Cookie是URI的一部分時無法正常工作。無法在無Cookie模式下設置FormsAuthenicationTicket.UserData

我的代碼:

// Create the cookie that contains the forms authentication ticket 
HttpCookie authCookie = FormsAuthentication.GetAuthCookie(userName, createPersistantCookie); 

// Get the FormsAuthenticationTicket out of the encrypted cookie 
FormsAuthenticationTicket ticket = FormsAuthentication.Decrypt(authCookie.Value); 

// Create a new FormsAuthenticationTicket that includes our custom User Data 
FormsAuthenticationTicket newTicket = new FormsAuthenticationTicket(ticket.Version, ticket.Name, ticket.IssueDate, ticket.Expiration, ticket.IsPersistent, "foo"); 

// Update the authCookie's Value to use the encrypted version of newTicket 
authCookie.Value = FormsAuthentication.Encrypt(newTicket); 

// Manually add the authCookie to the Cookies collection 
HttpContext.Current.Response.Cookies.Add(authCookie); 

// Determine redirect URL and send user there 
string redirUrl = FormsAuthentication.GetRedirectUrl(userName, createPersistantCookie); 

HttpContext.Current.Response.Redirect(redirUrl, false); 

當cookie的使用,頁面重定向,但在它的cookie信息沒有得到正確的URI,所以它返回到哪裏Request.IsAuthenticated回報我的登錄頁面假。無盡的循環隨之而來。

如何重定向到正確的URI?

回答

4

我發現這是一個有趣的問題,所以我着手對.net框架源代碼進行一些挖掘,測試和一點調試。

基本上,你試圖做的事情是行不通的。如果瀏覽器不支持cookie,則任何放入Response.Cookies集合的內容都將被忽略。您可以檢查Request.Browser.Cookies以查看是否支持Cookie。

在asp.net中,會話狀態和身份驗證都支持無Cookie模式,但這不會擴展到其他Cookie。實際上,會話和認證似乎甚至可以設置爲不同的操作模式。

認證系統可以將它自己的數據存儲在URI中,但它通過直接操作URI本身來實現。令人遺憾的是,微軟似乎沒有將這些功能暴露給身份驗證模塊之外的代碼。

基本上,如果您使用FormsAuthentication.GetAuthCookie()和FormsAuthentication.SetAuthCookie()方法,那麼認證系統會自動將這些信息放入URI中,但它不允許您爲這些方法提供一個定製的身份驗證票證...所以您被困在默認的身份驗證票證中。在這些情況下,您可以自行存儲任何定製數據。

反正...

真的是沒有太大的優勢,直接在認證憑證存儲自定義數據,如果認證系統已經cookie的......在cookie的模式,像「持續性餅乾」有沒有這意味着無論如何,每次會話至少會重新生成一次數據。

對於無cookie但仍需要像這樣的自定義數據的情況,最常見的建議是啓用無Cookie會話,並將自定義數據存儲爲會話變量。會話ID將被放入URI中,但自定義數據將保留在服務器的內存中。無論您的會話是否爲無Cookie,使用模式都是相同的。

如果你真的想要,你可以想出一個將自定義數據手動存儲在URI中的系統。最簡單的做法是將自定義數據放入查詢字符串或使用pathdata。我看不出任何真正的優勢,除非你只是不願意使用服務器內存(爲服務器添加一點內存是便宜,醜陋的URL並手動編寫代碼來處理它們並不便宜),否則這不會對會話變量產生真正的好處。

1

謝謝你的偉大的解釋,斯蒂芬。在用戶不允許cookies的情況下,我只需要避免UserData並從數據庫加載數據。

上面我會做如下的代碼之前:

if(!HttpContext.Current.Request.Browser.Cookies || !FormsAuthentication.CookiesSupported) 
{ 
    FormsAuthentication.RedirectFromLoginPage(userName, false); 
    return; 
} 
+0

聽起來像是不錯的計劃:) – 2008-11-05 20:10:41