IdentityServer4 FindByNameAsync always null

Viewed 157

I am using IdentityServer4 v4.1.1 in a .Net Core 3.1 project and having issues with FindByNameAsync - it always returns null.

This works and returns the user:

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

This does not and returns null:

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

How is this possible?

Edit (in an effort to show my research):
The reason I am really confused about this is that I found the following in the .Net Core source: https://github.com/dotnet/aspnetcore/blob/main/src/Identity/EntityFrameworkCore/src/UserStore.cs#L255
It seems like both of these statements should do the exact same thing. I am hoping that someone can explain why they do not.

1 Answers

I work with @bbales and I finally have figured it out.

We have a class called MultiTenantIdentityUserStore, which we use to override a few things to make the app multi-tenant. It wasn't obvious this was being used, unfortunately.

In it, we have a property:

public TTenantKey TenantId { get; set; }

This is used to override the Users public property:

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

Once I set the UserStore.TenantId, calling UserStore.Users.ToList() went from having 0 results to having 13, as expected. For comparison, UserStore.Context.Users.ToList() has 22 records, since we are migrating users from an old version of IdentityServer4 to the current version of 4.1.1.

Now using the 2nd query above returns a user:

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

As an aside, this also makes the UserManager and SignInManager.UserManager work as expected when using the same methods. (If you didn't know, UserManager and SignInManager.UserManager are the same object.) This is because the UserManager uses the UserStore to access the Users. When you have dependency injection supply those objects, it's all correctly referencing each other.

It may seem as if this Answer is only for our instance, but with as many unresolved Questions with the same stated problem on this Stack, this might be a widespread problem people aren't catching, or at least aren't updating their Question after figuring it out. I've probably read at least a dozen that don't have Answers. I'm wondering how many of them have our same issue.

Related