我正在编写自己的自定义Identity实现IIdentity类。我不需要更改默认方法IsAuthenticated,但现在我想知道默认的IIdentity是如何确定它是否应该返回true或false?Asp.net安全:IIdentity.IsAuthenticated默认实现
我想在我正在使用的FormsAuthenticationTicket中找到答案,但不确定是否正确。
由于提前,
Pickels
我正在编写自己的自定义Identity实现IIdentity类。我不需要更改默认方法IsAuthenticated,但现在我想知道默认的IIdentity是如何确定它是否应该返回true或false?Asp.net安全:IIdentity.IsAuthenticated默认实现
我想在我正在使用的FormsAuthenticationTicket中找到答案,但不确定是否正确。
由于提前,
Pickels
中有一个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
在大多数情况下。
此外,虽然全面实施IPrincipal
和IIdentity
是微不足道的,你也可以简单地从GenericPrincipal
和GenericIdentity
得到降低的代码,你需要保持量。
在FormsAuthentication
的情况下,你只能有一票,如果用户进行身份验证和User
将是RolePrincipal
的实例与FormsIdentity
类型的身份和它的实施IsAuthenticated
是超级复杂;-) ...
public bool IsAuthenticated
{
get
{
return true;
}
}
希望可以帮助清理一下。
我使用自定义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,如果按照这种想法,虽然确保您有逻辑的地方,因为它是存储在客户端可以正确过期失效的数据电脑。
如果我理解正确,则将userData存储为Json。在我的课堂上使用它也是一个好主意。 – Pickels 2010-04-27 19:37:18
我曾想过从我的代码中修剪更多,但我意识到这可能对其他人有用。在某些时候,我可能会将我的答案进一步分层并将结果缓存在服务器上,并且仅对票证进行反序列化以获得过期的缓存值。 – 2010-04-27 21:15:31
@Pickels - 在Cookie中小心JSON。您需要先将UrlEncode整个JSON字符串编码为',',并且其他人打破Cookie。好的,这是被覆盖的,现在你必须记住4k cookie的限制,在加密之前,加密之前大约1.8kb的整个cookie的可用空间。由于Cookie只是被截断,所以要小心。当你无缘无故地解码一个曲奇并找到你的错误时,你将会在36个小时内看到影子男人。 < - 经验之谈。 – 2010-05-04 21:04:25
从GenericIdentity派生是一个好主意。感谢您花时间写下这个答案。 – Pickels 2010-04-27 19:38:36
@Pickels - 如果您打算将自定义Principal/Identity与FormsAuthentication一起使用,您可能需要调查从RolePrincipal和FormsIdentity派生出来的可能性,因为这些是所有内置提供者所期望的基本类型。除非你正在实施你自己的供应商堆栈,在这种情况下,所有的投注都关闭,你可以随心所欲地做。 – 2010-04-27 19:52:01
我不会使用任何我认为的提供者。我使用OpenID并试图将其存储在MongoDB中。我正在用IIdentity进行一些测试,以轻松访问我的一些用户属性(友好标识符,ObjectId,电子邮件,...) – Pickels 2010-04-27 20:14:14