I am a bit confused as to how I am supposed to implement functions like the following:
GetNormalizedRoleNameAsync(TRole, CancellationToken)
SetNormalizedRoleNameAsync(TRole, String, CancellationToken)
GetNormalizedUserNameAsync(TUser, CancellationToken)
SetNormalizedUserNameAsync(TUser, String, CancellationToken)
GetUserNameAsync(TUser, CancellationToken)
SetUserNameAsync(TUser, String, CancellationToken)
In the ASP.NET Core CustomIdentityProvider Sample and the Actual ASP.NET Core Identity UserStoreBase class they do the following:
public Task SetNormalizedUserNameAsync(ApplicationUser user, string normalizedName, CancellationToken cancellationToken)
{
cancellationToken.ThrowIfCancellationRequested();
if (user == null) throw new ArgumentNullException(nameof(user));
if (normalizedName == null) throw new ArgumentNullException(nameof(normalizedName));
user.NormalizedUserName = normalizedName;
return Task.FromResult<object>(null);
}
public Task<string> GetUserNameAsync(ApplicationUser user, CancellationToken cancellationToken)
{
cancellationToken.ThrowIfCancellationRequested();
if (user == null) throw new ArgumentNullException(nameof(user));
return Task.FromResult(user.UserName);
}
Are these functions about just simply extracting the Normalized Name from an already populated User object and additionally updating the Normalized Name on an already populated User object. I am not seeing the purpose of these functions can someone explain?
Also do I need to actually persist the NormalizedUserName and NormalizedRoleName in my custom User/Role tables or are they not required?
The user store or the identity store is a repository of user accounts and credentials. ArcGIS Server connects to the user store to authenticate a user requesting access to a resource.
ASP.NET Core Identity: Is an API that supports user interface (UI) login functionality. Manages users, passwords, profile data, roles, claims, tokens, email confirmation, and more.
IdentityDbContext() Initializes a new instance of the IdentityDbContext class. IdentityDbContext(DbContextOptions) Initializes a new instance of IdentityDbContext.
The answer can be found in the way the UserManager
and RoleManager
lookup users / roles. Since they both work similarly, I'll focus on the UserManager
.
When calling UserManager.FindByNameAsync
, the UserManager
first normalize the key before passing it to your UserStore
:
public virtual async Task<TUser> FindByNameAsync(string userName)
{
userName = NormalizeKey(userName);
var user = await Store.FindByNameAsync(userName, CancellationToken);
return user;
}
where
// injected via dependency injection
ILookupNormalizer keyNormalizer;
public virtual string NormalizeKey(string key)
{
return (KeyNormalizer == null) ? key : KeyNormalizer.Normalize(key);
}
The goal is probably to ensure that no matter the input, the DB request always uses a consistent key.
Note that Identity framework actually uses UpperInvariantLookupNormalizer
by default (via IdentityServiceCollectionExtensions.AddIdentity<TUser, TRole>
).
That means that when you implement IUserStore<User>.FindByNameAsync(string normalizedUserName, CancellationToken cancellationToken)
, normalizedUserName
is not the string you passed to the UserManager
method, but its upper case version.
So to finally answer your questions:
GetNormalizedUserNameAsync
isn't used anywhere in the Identity framework.SetNormalizedUserNameAsync
is used during creation / update of a user, and is called with the upper case version of your user name. You don't need to persist it, but it might be preferable, since the User lookup is based on the normalized version.GetUserNameAsync
the string that will be normalized before calling GetNormalizedUserNameAsync
. Not used anywhere else in the Identity framework.Final note: you can change the ILookupNormalizer
by adding a scoped service before calling AddIdentity
:
public void ConfigureServices(IServiceCollection services)
{
services.AddScoped<ILookupNormalizer, UpperInvariantLookupNormalizer>();
services
.AddIdentity<User, Role>()
.AddUserStore<MyUserStore>()
.AddRoleStore<MyRoleStore>();
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With