【问题标题】:ASP.Net Identity and IdentityServer4 ClaimsASP.Net Identity 和 IdentityServer4 声明
【发布时间】:2018-07-20 20:15:32
【问题描述】:

我使用 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
  • “名称”:来自 IdentityUser.UserName
  • “preferred_username”:来自 IdentityUser.UserName
  • “电子邮件”:来自 IdentityUser.Email
  • “email_verified”:来自 IdentityUser.EmailConfirmed

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

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

因为在请求 PROFILE 范围时,IDS4 默认似乎不这样做。

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

  • AspNet 用户
  • AspNetUserClaims

那么最好的做法是添加额外的用户属性...

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

【问题讨论】:

  • 我也有同样的问题。从我所见,如果我将给定名称添加为声明,IdentiyServer 会自动将其发送到 id 令牌中。这让我认为索赔选项更好。除此之外,当并非所有用户都对该属性有价值时,将数据注册为声明具有优势。

标签: asp.net-identity identityserver4 claims


【解决方案1】:

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

正如您回答yourself,扩展属性应该以编程方式映射。

  • 如果您想在AspNetUsers 表中添加列,请扩展IdentityUser 类(例如public class MyApplicationUser : IdentityUser),然后添加您的自定义属性(例如FirstName)。这实质上改变了模型。为确保 EF 将您的模型更改写入 DB 表,您需要使用新的 MyApplicationUser 类扩展 IdentityDbContext 类。
  • 如果您希望将用户的自定义声明(例如hair_color)添加到AspNetUserClaims 表中,您需要调用userManager.AddClaimAsync()。您可以在注册过程或登录过程中使用表单中的数据或从外部身份验证提供商(如 Google、Facebook、Twitter 等)收到的声明执行此操作。

但是,正如您在我对您的附加问题的回答中所读到的那样,我认为您不应该映射它们,而是立即让它们声明。

存储用户属性的位置

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

编辑:更新答案

discussion 之后,我可能会说,主要考虑因素是:

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

例子:

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

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

原答案

据我了解,经验法则是:

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

例子:

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

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

TLDR

我实际上发现了你的问题,同时我自己也对此感到疑惑。我开始使用上面的经验法则,但问题不断出现,因为很多例子不遵循这个规则。 例如。微软有一个例子建议添加Name and DOB,这似乎与此相矛盾。 但是,OpenID 已经在可选的profile scope:birthdate, name, family_name, given_name, middle_name, nickname, preferred_username 中将这些属性 (a.o.) 定义为 standard claims

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-03-20
    • 1970-01-01
    • 2021-04-11
    • 2019-07-19
    • 2019-05-01
    • 1970-01-01
    • 2016-02-18
    • 1970-01-01
    相关资源
    最近更新 更多