2010-04-27 73 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