ASP.NET Identity UserStore中的GetNormalizedUserNameAsync和SetNormalizedUserNameAsync函数的说明

Bla*_*ell 8 c# asp.net asp.net-mvc asp.net-identity asp.net-core

关于我应该如何实现如下函数,我有点困惑:

GetNormalizedRoleNameAsync(TRole, CancellationToken)
SetNormalizedRoleNameAsync(TRole, String, CancellationToken)
GetNormalizedUserNameAsync(TUser, CancellationToken)
SetNormalizedUserNameAsync(TUser, String, CancellationToken)
GetUserNameAsync(TUser, CancellationToken)
SetUserNameAsync(TUser, String, CancellationToken)
Run Code Online (Sandbox Code Playgroud)

在ASP.NET Core CustomIdentityProvider Sample和Actual ASP.NET Core Identity UserStoreBase类中,它们执行以下操作:

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);
}
Run Code Online (Sandbox Code Playgroud)

这些功能只是简单地从已填充的用户对象中提取规范化名称,并在已填充的用户对象上另外更新规范化名称.我没有看到这些功能的目的可以解释一下吗?

我还需要在自定义用户/角色表中实际保留NormalizedUserName和NormalizedRoleName,还是不需要?

Mét*_*ule 7

答案可以在途中发现UserManagerRoleManager查找用户/角色。由于它们的工作方式相似,因此我将重点介绍UserManager.

调用时UserManager.FindByNameAsyncUserManager首先将密钥规范化,然后再将其传递给您UserStore

public virtual async Task<TUser> FindByNameAsync(string userName)
{
    userName = NormalizeKey(userName);
    var user = await Store.FindByNameAsync(userName, CancellationToken);
    return user;    
}
Run Code Online (Sandbox Code Playgroud)

在哪里

// injected via dependency injection
ILookupNormalizer keyNormalizer; 

public virtual string NormalizeKey(string key)
{
    return (KeyNormalizer == null) ? key : KeyNormalizer.Normalize(key);
}
Run Code Online (Sandbox Code Playgroud)

目标可能是确保无论输入如何,数据库请求始终使用一致的键。

请注意,Identity 框架实际上UpperInvariantLookupNormalizer默认使用(通过IdentityServiceCollectionExtensions.AddIdentity<TUser, TRole>)。

这意味着当您实现时IUserStore<User>.FindByNameAsync(string normalizedUserName, CancellationToken cancellationToken), ,normalizedUserName不是您传递给UserManager方法的字符串,而是它的大写版本。

所以最后回答你的问题:

  • GetNormalizedUserNameAsync 未在 Identity 框架中的任何地方使用。
  • SetNormalizedUserNameAsync在创建/更新用户期间使用,并使用您的用户名的大写版本调用。您不需要保留它,但它可能更可取,因为用户查找基于规范化版本。
  • GetUserNameAsync在调用之前将被规范化的字符串GetNormalizedUserNameAsync。未在身份框架中的其他任何地方使用。

最后一点:您可以ILookupNormalizer通过在调用之前添加范围服务来更改AddIdentity

public void ConfigureServices(IServiceCollection services)
{
    services.AddScoped<ILookupNormalizer, UpperInvariantLookupNormalizer>();
    services
        .AddIdentity<User, Role>()
        .AddUserStore<MyUserStore>()
        .AddRoleStore<MyRoleStore>();
}
Run Code Online (Sandbox Code Playgroud)