var user = UserManager.Find(...);
ClaimsIdentity identity = UserManager.CreateIdentity(
user, DefaultAuthenticationTypes.ApplicationCookie );
var claim1 = new Claim(
ClaimType = ClaimTypes.Country, ClaimValue = "Arctica", UserId = user.Id );
identity.AddClaim(claim1);
AuthenticationManager.SignIn(
new AuthenticationProperties { IsPersistent = true }, identity );
var claim2 = new Claim(
ClaimType = ClaimTypes.Country, ClaimValue = "Antartica", UserId = user.Id );
identity.AddClaim(claim2);
都 claim1
和 claim2
仅在当时的请求中持久存在 ClaimsIdentity
用户是 登录。换句话说,当用户 退出 通过电话 SignOut()
, 两个索赔 也被删除,因此下次这个用户 登录,它不再是这些的成员 两个索赔 (我假设了 两个索赔 不再存在了)
这个事实 claim2
在请求中持久存在(即使 身份验证cookie 已经创建了 claim2
被添加到用户)建议 索赔 不要通过请求保持持久性 身份验证cookie,但通过其他方式。
怎么样 索赔 坚持要求?
编辑:
1) 据我所知, 索赔类型 IdentityUserClaim
是 决不 坚持在一个 曲奇饼?
var user = UserManager.Find(...);
/* claim1 won't get persisted in a cookie */
var claim1 = new IdentityUserClaim
{ ClaimType = ClaimTypes.Country, ClaimValue = "Arctica", UserId = user.Id };
user.Claims.Add(claim1);
ClaimsIdentity identity = UserManager.CreateIdentity(
user, DefaultAuthenticationTypes.ApplicationCookie );
AuthenticationManager.SignIn(
new AuthenticationProperties { IsPersistent = true }, identity );
如果我的假设是正确的,那就是原因 IdentityUserClaim
实例不会持久化 曲奇饼 因为它被认为是 这些说法 应存储在 D B 因此可以 后续请求 从一个 D B,而 索赔类型 Claim
通常不存储在 D B 因此,为什么他们需要坚持下去 曲奇饼?
2)
如果您想深入了解一切是如何运作的,请查看
Katana项目的源代码
我想 Asp.net身份2 不是的一部分 Katana项目 (也就是说,我见过有人问微软什么时候会发布 Asp.Net Identity的源代码, 即使 Katana源代码 已经有了)?!
谢谢
好问题。甚至让我做了一个小实验。
这一行:
AuthenticationManager.SignIn(
new AuthenticationProperties { IsPersistent = true }, identity );
不设置cookie。只有套 Identity
对象为后来的回调。
Cookie仅在控件传递给中间件并且调用了一些OWIN内部方法时设置 Response.OnSendingHeaders
。
所以你的代码只是添加 claim2
在...上 identity
存储在内存中以供后续用户使用的对象。从理论上讲,你甚至可以设定 claim1
你做完之后 AuthenticationManager.SignIn
。无论如何它将被保留在cookie中。
如果您尝试在控制器中添加这样的cliam:
public ActionResult AddNonPersistedClaim()
{
var identity = (ClaimsIdentity)ClaimsPrincipal.Current.Identity;
identity.AddClaim(new Claim("Hello", "World"));
return RedirectToAction("SomeAction");
}
此声明不会在Cookie中设置,您将不会在下一个请求中看到它。
如果您想深入了解它是如何工作的,请查看源代码 Katana项目, 旁观 Microsoft.Owin.Security
和 Microsoft.Owin.Security.Cookies
项目。随着 AuthenticationManager
在 Microsoft.Owin.Net45
项目。
更新
回答你的编辑1 - IdentityUserClaim
确实存在于数据库中,这是您可以将持久声明分配给用户的方式。您可以在用户上添加这些内容 UserManager
await userManager.AddClaimAsync(userId, new Claim("ClaimType", "ClaimValue"));
这将在数据库表中创建表示IdentityUserClaim的记录。当用户下次登录时,将从数据库中读取这些声明并将其添加到身份中并可用 ClaimsIdentity.Current
通过财产 .Claims
或通过方法 .HasClaim()
。
IdentityUserClaim
什么都不做 - 只是串行化的方式 Claim
对象进入数据库。您通常不会直接访问这些内容,除非您想要“裸露指关节”并自己写入该表 UserManager
。
换句话说 - Identity不会设置cookie。 OWIN创建cookie。看看吧 这段代码:
public async Task SignInAsync(IAuthenticationManager authenticationManager, ApplicationUser applicationUser, bool isPersistent)
{
authenticationManager.SignOut(
DefaultAuthenticationTypes.ExternalCookie,
DefaultAuthenticationTypes.ApplicationCookie,
DefaultAuthenticationTypes.TwoFactorCookie,
DefaultAuthenticationTypes.TwoFactorRememberBrowserCookie,
DefaultAuthenticationTypes.ExternalBearer);
var identity = await this.CreateIdentityAsync(applicationUser, DefaultAuthenticationTypes.ApplicationCookie);
identity.AddClaim(new Claim(ClaimTypes.Email, applicationUser.Email));
authenticationManager.SignIn(new AuthenticationProperties() { IsPersistent = isPersistent }, identity);
}
这里的身份验证管理器是OWIN的一部分。 Identity
是其一部分 System.Security.Claims
。所有属于Identity项目的都是 CreateIdentityAsync
方法 - 基本上将用户从数据库转换为 ClaimsIdentity
所有持久的角色和声明。
回答你的编辑2:您是对的,AspNet Identity不是Katana项目的一部分,但Identity使用OWIN(Katana的一部分)进行cookie处理和授权。身份项目主要涉及用户/角色/声明 坚持 和用户管理,如锁定,用户创建,发送密码重置电子邮件,2FA等。
令我感到意外的是 ClaimsPrincipal 随着 ClaimsIdentity 和 要求 是.Net框架的一部分,可以在OWIN或Identity之外使用。这些不仅用于Asp.Net,还用于Windows应用程序。好的事情.Net现在有开源,您可以浏览所有这些 - 让您更好地了解它们如何一起工作。此外,如果您正在进行单元测试,那么了解内部结构是非常宝贵的,因此您可以在不使用模拟的情况下存根所有功能。