原文出處 [Trailmax Tech Max Vasilyev: ASP.Net MVC development in Aberdeen, Scotland ](http://tech.trailmax.info/2014/08/aspnet identity cookie format/) "中 ...
原文出處
Trailmax Tech
Max Vasilyev: ASP.Net MVC development in Aberdeen, Scotland
我的讀者聯繫到我,並向我提出了一系列關於 AspNet Identity的問題。一開始我覺得這些問題都會比較簡單,我能夠輕鬆的回答他,但結果表明,這裡面的每一個問題都值得寫一篇單獨的文章。所以我會寫一個Mini系列關於Identity框架的“Q-A(問與答)”博客。
第一個問題是關於Cookie安全Token以及它是如何被計算(computed)出來的:如果同一個用戶在 Chrome 和Firefox中登陸,那麼Identity Framework 在Cookie中創建token,token包含相同的信息(用戶Id、 Security Stamp、等等),但是為甚麼這兩個Cookie是不同的?
我思考了一下,我猜 cookie創建信息和過期信息被編碼在了cookie中,可能還有cookie的某種簽名信息也被一同保存了。我覺得我猜的很接近答案。
幸運的是,處理cookie的代碼就在開源的 Katana Project 中。
下麵就是用戶登錄是cookie的創建過程
- Identity framework根據你資料庫中的信息創建
ClaimsPrincipal
對象(它對應於ApplicationUser
類) - Identity向principal中添加一些列預設claim,例如ApplicationUser.Id和SecurityStamp
ClaimsPrincipal
被傳遞到CookieAuthenticationHandler
這個OWIN中間件中- Authentication Handler對不同的東西都做了很多檢查,比如,檢查每個cookie是否應該被標記為secure或者persistent,設置過期時間等等很多事情。這一系列檢查(checks,含有操作的意思)的結果就是生成一個
AuthenticationTicket
,這個AuthenticationTicket
擁有一個含有一系列claim和AuthenticationProperties(認證屬性)的ClaimsIdentity
,AuthenticationProperties
是一個包含很多數據的字典(dictionary),裡面的數據可能是 cookie issue 日期,過期日期,是否持久保存cookie,等等 - 認證票據和claims principal接下來被傳遞到
SecureDataFormat
類中,數據將在這個類中序列化、加密、Base64編碼
最後一步包含很多動作,我們再深入些。
認證票據由TicketSerializer
進行序列化。這裡ClaimsIdentity
被寫入記憶體流:包含一些屬性和一個claim列表。然後AuthenticationProperties
(包括cookie 設置,過期日期)也被寫入了記憶體流。然後記憶體流被GZip壓縮,以備接下來的處理。
管道中的下一步就是加密。加密操作由 .Net 類庫中的DpapiDataProtector
提供。你可以在MSDN上閱讀相關文檔。我不確定加密的強度。文檔中說目標參數事實上是一個密碼列表。現在我在OWIN中看到了一個地方你可以在這裡設置你自己的加密密碼,而且我看到這裡主密碼是“Microsoft.Owin.Security.IDataProtector”。所以我的猜測是安全的信息不應該被放進cookie里,比如:別把連接字元串放在claim里!(註:這裡的翻譯可能不准確,建議此段參考閱讀原文)
Next step in the pipeline is encryption. Encryption is borrowed from .Net class DpapiDataProtector. You can read documentation on MSDN. I’m not sure about the strength of the encryption. The documentation says that purpose parameters are effectively a list of passwords. And now here I’ve seen in OWIN where you can set your own encryption password and I can see that the main password is set to “Microsoft.Owin.Security.IDataProtector”. So my guess would be that no secure information should go into cookie, i.e. don’t put your connection strings into user claims!
在加密之後,位元組流使用Base64編碼以易於網路傳輸。最後準備好以等待被設置到Http響應的cookie頭上。
所有的過程如下圖所示
反正,原來的問題:“為什麼在不同瀏覽器中的cookies是不同的?”的答案是:因為簽名中包含cookie的創建信息和過期時間,這在不同瀏覽器中是不同的,所以cookie中的加密信息也是不同的,所以cookie也是不同的。