2010-04-27 71 views
1

我正在編寫自己的自定義Identity實現IIdentity類。我不需要更改默認方法IsAuthenticated,但現在我想知道默認的IIdentity是如何確定它是否應該返回true或false?Asp.net安全:IIdentity.IsAuthenticated默認實現

我想在我正在使用的FormsAuthenticationTicket中找到答案,但不確定是否正確。

由於提前,

Pickels

回答

6

中有一個ASP.Net處理程序的上下文中沒有 '默認IIdentity'。

有一個GenericIdentity是傳遞給GenericPrincipal這是一個ASP.Net處理器默認User,它的行爲是,如果與非空的用戶名實例化則認證。

例如

public virtual bool IsAuthenticated 
{ 
    get 
    { 
     return !this.m_name.Equals(""); 
    } 
} 

這就是說,IsAuthenticated的確定完全是任意的和實施IIdentity類是用於實現該邏輯負責。

通常情況下,是沒有用例實例化一個沒有認證委託人/身份,因爲這是由asp.net運行時自動完成的,因此,用「愚蠢」 IsAuthenticated返回true應該在適當的執行您的自定義IIdentity在大多數情況下。

此外,雖然全面實施IPrincipalIIdentity是微不足道的,你也可以簡單地從GenericPrincipalGenericIdentity得到降低的代碼,你需要保持量。

FormsAuthentication的情況下,你只能有一票,如果用戶進行身份驗證和User將是RolePrincipal的實例與FormsIdentity類型的身份和它的實施IsAuthenticated是超級複雜;-) ...

public bool IsAuthenticated 
{ 
    get 
    { 
     return true; 
    } 
} 

希望可以幫助清理一下。

+0

從GenericIdentity派生是一個好主意。感謝您花時間寫下這個答案。 – Pickels 2010-04-27 19:38:36

+1

@Pickels - 如果您打算將自定義Principal/Identity與FormsAuthentication一起使用,您可能需要調查從RolePrincipal和FormsIdentity派生出來的可能性,因爲這些是所有內置提供者所期望的基本類型。除非你正在實施你自己的供應商堆棧,在這種情況下,所有的投注都關閉,你可以隨心所欲地做。 – 2010-04-27 19:52:01

+0

我不會使用任何我認爲的提供者。我使用OpenID並試圖將其存儲在MongoDB中。我正在用IIdentity進行一些測試,以輕鬆訪問我的一些用戶屬性(友好標識符,ObjectId,電子郵件,...) – Pickels 2010-04-27 20:14:14

2

我使用自定義UserPrinciple將當前用戶的更多信息嵌入到我的頁面中,而不是標準GenericPrinciple允許的內容。我沒有發現需要實現我自己的IIdentity,因爲您可以輕鬆利用內建的FormsIdentity(與我的時尚類似)(我不確定這是否與Auth for .NET的標準實踐不同,它在實踐中對我自己很有用雖然)。我確實創建了一個自定義的GuestIdentity,它返回一個硬編碼的IsAuthenticated = false或許這可以被替換爲GenericPrinciple如果它是抽象的或不抽象的,我不確定。

public class UserPrincipal : IPrincipal 
{    

    private readonly IIdentity _identity; 

    public UserPrincipal() 
     { 
      _identity = new GuestIdentity(); 

      var guest = //my custom object 
      User = guest; 
     }   
    public UserPrincipal(HttpContext context) 
    { 
     var ident = context.User.Identity as FormsIdentity; 
     string msg1 = "Context.User.Identity is null for authenticated user."; 
     if (ident == null) throw new ApplicationException(msg1); 

     _identity = ident; 
     string msg2 = "Forms Identity Ticket is null"; 
     if (ident.Ticket == null) throw new AccessViolationException(msg2); 

     var userData = ident.Ticket.UserData; 

     ... 

     User = jsonSerializer.Deserialize<User>(userJson); 
    }  
    #region IPrincipal Members 
    public bool IsInRole(string role) 
    { 
     return User.Roles.FirstOrDefault(x => x.RoleName == role) != null; 
    } 

    public IIdentity Identity 
    { 
     get { return _identity; } 
    } 
    #endregion 
} 

隨機不談,你可以緩存在窗體身份驗證票數據,如擴展的UserData,如果按照這種想法,雖然確保您有邏輯的地方,因爲它是存儲在客戶端可以正確過期失效的數據電腦。

+0

如果我理解正確,則將userData存儲爲Json。在我的課堂上使用它也是一個好主意。 – Pickels 2010-04-27 19:37:18

+0

我曾想過從我的代碼中修剪更多,但我意識到這可能對其他人有用。在某些時候,我可能會將我的答案進一步分層並將結果緩存在服務器上,並且僅對票證進行反序列化以獲得過期的緩存值。 – 2010-04-27 21:15:31

+2

@Pickels - 在Cookie中小心JSON。您需要先將UrlEncode整個JSON字符串編碼爲',',並且其他人打破Cookie。好的,這是被覆蓋的,現在你必須記住4k cookie的限制,在加密之前,加密之前大約1.8kb的整個cookie的可用空間。由於Cookie只是被截斷,所以要小心。當你無緣無故地解碼一個曲奇並找到你的錯誤時,你將會在36個小時內看到影子男人。 < - 經驗之談。 – 2010-05-04 21:04:25