ASP.Net Identity and IdentityServer4 Claims



我使用IdentityServer4作为OIDC提供程序和ASP.NET Core 2.0。

我已经浏览了几篇帖子,以确保IdentityServer发布的声明最终出现在ClaimsPrincipal(即Auth Cookie)中,并设法通过ClaimsAction过滤实现了这一点。

然而,我的问题是。。。当使用ASP.NET Identity(和EF后备存储)运行IdentityServer时,如何将ASP.NET Identity属性映射到IDS4返回的声明。默认情况下,IDS4会返回以下声明:。。。

  • "sub":来自IdentityUser.Id
  • "name":来自IdentityUser.UserName
  • "preferred_username":来自IdentityUser.username
  • "电子邮件":来自IdentityUser.email
  • "email_verified":来自IdentityUser.EmailConfirmed

我问这个问题的原因是,我想映射

  • "given_name":来自IdentityUser.FirstName(扩展属性)
  • "family_name":来自IdentityUser.LastName(扩展属性)

因为IDS4在请求PROFILE作用域时默认不会执行此操作。

此外,我想问一下存储用户属性的最佳实践是什么。使用ASP.NET Identity DB时,会创建两个表。。。

  • AspNetUsers
  • AspNetUserClaims

因此,添加其他用户属性作为。。。

  1. IdentityUser上的属性(作为新字段添加到AspNetUsers)或
  2. AspNetUserClaims中的其他声明(可以在注册或登录时使用UserManager.AddClaimAsync()添加这些声明)

如何将用户属性映射到声明

正如您自己回答的那样,应该以编程方式映射扩展属性。

  • 如果要向AspNetUsers表中添加列,请扩展IdentityUser类(例如public class MyApplicationUser : IdentityUser),然后添加自定义属性(例如FirstName)。这从本质上改变了模型。为了确保EF将您的模型更改写入DB表,您需要用新的MyApplicationUser类扩展IdentityDbContext
  • 如果要将用户的自定义声明(例如hair_color)添加到AspNetUserClaims表中,则需要调用userManager.AddClaimAsync()。您可以在注册过程或登录过程中使用表单中的数据,或从谷歌、脸书、推特等外部授权提供商处收到的声明中进行此操作

但是,正如你在我对你的附加问题的回答中所读到的,我认为你不应该绘制它们的地图,而应该立即让它们声明。

存储用户属性的位置

我发现您的附加问题更有趣:要向AspNetUsers添加哪些属性,何时向AspNetUserClaims添加?

编辑:更新的答案

经过一些讨论,我可能会说,主要考虑因素是:

  • ASP.NET标识是用户数据主要来源的属性应为强类型数据库列(通常在AspNetUsers中),并在创建主体时传播到声明(如有必要)
  • 从另一个源导入和更新的属性可以立即传播到DB(AspNetUsersClaims)中的声明

示例:

  • 如果hair_color是用户在此标识界面中输入和更改的属性,则将其存储在强类型数据库列中
  • 如果hair_color是在另一个应用程序中维护并从中更新的属性,我会将其作为记录存储在声明表中

在我编写原始答案(如下)时处理的案例中,要共享的用户数据是从另一个(主要)源间接更新的,但对于身份验证详细信息,ASP.NET Identity是主要源。因此,它产生了相同的分布,但原因不同

原始答案

据我所知,经验法则是:

  • (仅)用于与其他应用程序共享的数据(用户信息)应为受保护的身份资源,因此AspNetUsersClaims中声明了这一点
  • 功能上用于身份验证的数据(身份验证信息)应该是用户(AspNetUsers)的一部分,因此用于身份验证、登录、恢复、2-事实等的数据(例如用户名、密码、电子邮件、电话)

示例:

  • 如果您想添加DateOfBirth,我会将其添加到AspNetUsersClaims(除非您打算以某种方式使用它进行身份验证/登录)
  • 如果要存储帐户/登录相关数据(如accountExpiresDateCreatedFromIP),请将其添加到AspNetUsers(并扩展IdentityUser)

因此,如果使用UserClaimsPrincipalFactory将用户属性添加到用户声明中,则可能只是将该属性添加到了错误的表中!

TLDR

事实上,我发现了你的问题,同时我自己也在思考这个问题。我开始使用上面的经验法则,但问题不断出现,因为很多例子都不遵循这个法则。例如,微软有一个例子建议添加Name和DOB,这似乎与此相矛盾。但是,OpenID已经将这些属性(a.o.)定义为可选profile范围中的标准声明:birthdate, name, family_name, given_name, middle_name, nickname, preferred_username

最新更新