AspNetCore 身份用户缺少 ApplicationUser 自定义属性

AspNetCore Identity User missing ApplicationUser custom properties

我基于带有应用程序内身份验证的内置模板(遵循基本教程)构建了一个简单的 AspNetCore(3.0 预览版)Web 应用程序。

我可以 运行 我的应用程序,当我尝试转到安全页面时,我需要登录。

我注册了,可以正常登录了。我可以在数据库的 AspNetUsers table 中找到我的用户。

我成功地修改了 ApplicationUser 以添加 CustomTag (string) 和 运行 EF 迁移和更新以将此列添加到 AspNetUsers table。我使用 SQL UPDATE AspNetUsers... 命令填充了该列,因此该列现在包含 "Hello World!".

现在我 运行 我的应用程序,但我没有关于经过身份验证的用户的有用数据,除了他已通过身份验证。

我在控制器操作中放置了一个断点以查看经过身份验证的 ApplicationUser,我看到 IdentityServer4 添加了 13 个声明的身份,但我不知道这与我的用户有什么关系?用户已通过身份验证,但名称为 NULL。该用户没有我的自定义 属性 "CustomTag"。我是不是找错地方了?

大量搜索导致了有关如何扩展模型(完成)以及如何 运行 EF 迁移(完成)的深入文章。

大量搜索导致了关于如何覆盖 IdentityServer4 代码的深入文章和 UI,但在我的模板应用程序中有 none,所以我不知道在哪里我应该寻求修改代码。

谁能告诉我如何让我的 ApplicationUser 自定义属性在控制器操作处理程序中可见?

如果您想检索有关当前用户的完整详细信息,您可以在控制器操作中使用如下代码:

var user = await _userManager.GetUserAsync(User); //_userManager is an instance of UserManager<TUser>

如果您希望在登录时将声明加载到 auth cookie 中,那么您可以创建并注册(通过 IdentityBuilder.AddClaimsPrincipalFactory<TFactory>())您自己的 UserClaimsPrincipalFactory<TUser, TRole> 实现,它可以添加您的额外属性正如登录时声明的那样,这意味着您不必访问数据库。

您在这里处理两件不同的事情。 Identity 是一个用户管理系统。它与 ASP.NET Core 中的 authentication/authorization 中间件分开(可以使用或不使用 Identity)。

当您进行身份验证时,会创建一个 ClaimsPrincipal。 Entity Framework 身份提供者根据数据库中 AspNetUsers table 中的内容填充一些声明,但仅限于它本质上知道的内容。它显然没有关于您添加的自定义属性的内置知识,因此不包括在内。 Identity Server 仅充当集中式身份提供者,创建此主体,然后将 that 发送回请求应用程序。

总而言之,您在这里处理的不是 ApplicationUser,而是与根据身份验证创建的特定主体关联的声明集合。

如果需要,您可以随时获取实际关联的 ApplicationUser 以获取任何自定义数据:

var user = await _userManager.FindByIdAsync(User.FindFirstValue(ClaimTypes.NameIdentitifer));

您还可以选择通过派生自 UserClaimsPrincipalFactory<TUser> 和覆盖 CreateAsync 来补充声明集合,以添加来自任何来源(包括数据库)的额外声明。不过,这只能直接在 ASP.NET Core 中使用。对于 Identity Server,您需要实现自定义 IProfileService.