2008年5月11日

IPrincipal vs Session Identity Persistence 的思考

為了家總的案子,終於把這一段給弄清楚了...

簡單講IPrincipal的架構:HttpContext.User就是一個IPrincipal,IPrincipal負責標示Role(有個IsInRole的method要實現),也就是負責授權。IPrincipal下面有一個Identity,可以存真正獲得這個Principal的Identity(:IIdentity)。

每次的HttpRequest, Asp.Net都會自動幫我們把IPrincipal與IIdentity處理出來。標準狀況下(使用Forms Authentication,且使用FormsAuthentication.SetAuthCookie的情況下),每個Request獲得的User是一個GenericPrincipal,Identity則是一個FormsIdentity。這往往不是我們要的,所以,我們有兩種作法:

1. 在系統拿到IPrincipal與IIdentity的時候,自己根據取得的IIdentity.Name去把我們要的類別代換。比如我有CDLPrincipal:IPrincipal, CDLIdentity:IIdentity,在Authentication_End的時候,執行

string currentUserId=HttpContext.User.Identity.Name;
HttpContext.Current.User=new CDLPrincipal(currentUserId);

這裡的new CDLPrincipal,基本上就是從Identity Store裡,取出我們要的CDLPrincipal,以及附贈的CDLIdentity。也就是說,在這個過程裡面,HttpContext.Current.User發生了兩次指定的工作:一次是系統做的,一次是我們做的。

2. 如果要只想做一次這個動作,只能我們自己寫Authentication Module。在這種時候,我們要用authentication cookie把所有IPrincipal的內容Serialize(並Encrypt)成一個string,然後指定cookie name,傳給browser。這也是Msdn的標準作法,SetAuthCookie只是這個作法的一個簡易版。這種作法的問題很多,主要authentication cookie這下子可能變得很長,影響頻寬。

第一種作法,可以用HttpModule解決或是用Page_Init,第二種方式就一定是用HttpModule處理。

另外,這跟使用Session比起來有何好處?老實說,除了可以Impersonate之外,我看不出任何好處。但多了一個Auth. Cookie,在頻寬上是有影響的。session的偽冒問題,IPrincipal的作法同樣透過cookie,也不可避免。

這是個值得進一步思考的問題。

沒有留言:

張貼留言