首页 > 解决方案 > IdentityServer4 FindByNameAsync 始终为空

问题描述

我在 .Net Core 3.1 项目中使用 IdentityServer4 v4.1.1 并遇到 FindByNameAsync 问题 - 它总是返回 null。

这有效并返回用户:

var user = await userStore.Context.Users.FirstOrDefaultAsync(u => u.NormalizedUserName == userManager.NormalizeName(model.Username), default(CancellationToken));

这不会并返回 null:

var user = await userStore.FindByNameAsync(userManager.NormalizeName(model.Username));

这怎么可能?

编辑(为了展示我的研究):
我对此感到非常困惑的原因是我在 .Net Core 源代码中发现了以下内容:https ://github.com/dotnet/aspnetcore/blob/main/src/ Identity/EntityFrameworkCore/src/UserStore.cs#L255
似乎这两个语句都应该做同样的事情。我希望有人能解释为什么他们不这样做。

标签: .net-coreidentityserver4

解决方案


我和@bbales 一起工作,我终于弄明白了。

我们有一个名为 的类MultiTenantIdentityUserStore,我们用它来覆盖一些东西以使应用程序成为多租户。不幸的是,这并不明显被使用。

在其中,我们有一个属性:

public TTenantKey TenantId { get; set; }

这用于覆盖Users公共属性:

public override IQueryable<TUser> Users => base.Users.Where(u => u.TenantId.Equals(TenantId));

一旦我设置了UserStore.TenantId,调用UserStore.Users.ToList()结果从 0 变为 13,正如预期的那样。作为比较,UserStore.Context.Users.ToList()有 22 条记录,因为我们正在将用户从旧版本的 IdentityServer4 迁移到当前版本的 4.1.1。

现在使用上面的第二个查询返回一个用户:

var user = await userStore.FindByNameAsync(userManager.NormalizeName(model.Username));

顺便说一句,这也使UserManagerandSignInManager.UserManager在使用相同方法时按预期工作。(如果你不知道,UserManager并且SignInManager.UserManager是同一个对象。)这是因为UserManager使用UserStore来访问Users. 当您有依赖注入提供这些对象时,它们都正确地相互引用。

似乎此答案仅适用于我们的实例,但是在此堆栈上存在许多具有相同问题的未解决问题,这可能是人们没有发现的普遍问题,或者至少在之后没有更新他们的问题弄清楚。我可能已经阅读了至少一打没有答案的书。我想知道他们中有多少人有同样的问题。


推荐阅读