坚持要求的索赔

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); 

只有在ClaimsIdentity用户登录时, ClaimsIdentityclaim2才会在请求中保留。 换句话说,当用户通过调用SignOut() 注销时两个声明也被删除,因此下次该用户登录时 ,它不再是这两个声明的成员(我假设这两个声明不已经存在了)

claim2在请求中持久化的事实(即使在将claim2添加到用户时已经创建了身份validationcookie )这表明声明不会通过身份validationcookie在请求之间claim2 ,而是通过其他方式。

那么请求如何在请求中保持不变?

编辑:

1)据我所知, IdentityUserClaim 类型的声明 永远不会保存在cookie中

 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实例不会持久存储在cookie中的原因是因为假设这些声明应该存储在数据库中 ,因此可以在后续请求中从数据库中检索,而声明类型为 Claim通常不存储在数据库中 ,因此需要将它们保存在cookie中

2)

如果您想深入了解它是如何工作的,请查看Katana项目的源代码

我认为Asp.net Identity 2不是Katana项目的一部分(也就是说,我看到有人问微软什么时候会发布Asp.Net Identity源代码 ,即使Katana源代码已经可用)?!

谢谢

好问题。 甚至让我做了一个小实验。

这一行:

 AuthenticationManager.SignIn( new AuthenticationProperties { IsPersistent = true }, identity ); 

不设置cookie。 仅为后面的回调设置Identity对象。

Cookie仅在控件传递给中间件和一些名为Response.OnSendingHeaders OWIN内部方法时设置。

因此,您的代码只是在identity对象上添加claim2 ,该identity对象存储在内存中供以后用户使用。 理论上,您甚至可以在完成AuthenticationManager.SignIn后设置claim1 。 无论如何它将被保留在cookie中。

如果您尝试在控制器中添加这样的cliam:

  public ActionResult AddNonPersistedClaim() { var identity = (ClaimsIdentity)ClaimsPrincipal.Current.Identity; identity.AddClaim(new Claim("Hello", "World")); return RedirectToAction("SomeAction"); } 

此声明不会在Cookie中设置,您将不会在下一个请求中看到它。

如果您想深入了解它是如何工作的,请查看Katana项目的源代码,查看Microsoft.Owin.SecurityMicrosoft.Owin.Security.Cookies项目。 与Microsoft.Owin.Net45项目中的AuthenticationManager一起使用。

更新

要回答您的编辑1IdentityUserClaim确实持久存储到数据库中,这是您可以将持久声明分配给用户的方式。 您可以通过UserManager将这些添加到用户

 await userManager.AddClaimAsync(userId, new Claim("ClaimType", "ClaimValue")); 

这将在数​​据库表中创建表示IdentityUserClaim的记录。 当下次用户登录时,这些声明将从数据库中读取并添加到标识中, ClaimsIdentity.Current通过属性.Claims或方法.HasClaim()ClaimsIdentity.Current.Claims

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); } 

这里的身份validation管理器是OWIN的一部分。 IdentitySystem.Security.Claims一部分。 所有属于Identity项目的都是CreateIdentityAsync方法 – 它基本上将用户从数据库转换为所有持久角色和声明的ClaimsIdentity

回答你的编辑2 :你是对的,AspNet Identity不是Katana项目的一部分,但Identity使用OWIN(Katana的一部分)进行cookie处理和授权。 身份项目主要处理用户/角色/声明持久性和用户管理,如锁定,用户创建,发送带密码重置的电子邮件,2FA等。

令我感到意外的是, ClaimsPrincipal以及ClaimsIdentity和Claim是.Net框架的一部分,可以在OWIN或Identity之外使用。 这些不仅用于Asp.Net,还用于Windows应用程序。 好的事情.Net现在有开源,您可以浏览所有这些 – 让您更好地了解它们如何一起工作。 此外,如果您正在进行unit testing,那么了解内部结构是非常宝贵的,因此您可以在不使用模拟的情况下存根所有function。