我对如何实现如下功能有点困惑:
GetNormalizedRoleNameAsync(TRole, CancellationToken)
SetNormalizedRoleNameAsync(TRole, String, CancellationToken)
GetNormalizedUserNameAsync(TUser, CancellationToken)
SetNormalizedUserNameAsync(TUser, String, CancellationToken)
GetUserNameAsync(TUser, CancellationToken)
SetUserNameAsync(TUser, String, CancellationToken)
在 ASP.NET Core CustomIdentityProvider 示例和实际 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);
}
这些函数是否只是简单地从已填充的用户对象中提取规范化名称,并在已填充的用户对象上额外更新规范化名称。我没有看到这些功能的目的,有人可以解释一下吗?
另外,我是否需要在我的自定义用户/角色表中实际保留规范化用户名和规范化角色名称,或者它们不是必需的?
答案可以在UserManager
和RoleManager
查找用户/角色的方式中找到。由于它们的工作方式相似,因此我将重点介绍UserManager
。
调用UserManager.FindByNameAsync
时,UserManager
首先规范化密钥,然后再将其传递给您的UserStore
:
public virtual async Task<TUser> FindByNameAsync(string userName)
{
userName = NormalizeKey(userName);
var user = await Store.FindByNameAsync(userName, CancellationToken);
return user;
}
哪里
// injected via dependency injection
ILookupNormalizer keyNormalizer;
public virtual string NormalizeKey(string key)
{
return (KeyNormalizer == null) ? key : KeyNormalizer.Normalize(key);
}
目标可能是确保无论输入如何,数据库请求始终使用一致的键。
请注意,标识框架实际上默认使用UpperInvariantLookupNormalizer
(通过IdentityServiceCollectionExtensions.AddIdentity<TUser, TRole>
(。
这意味着当你实现IUserStore<User>.FindByNameAsync(string normalizedUserName, CancellationToken cancellationToken)
时,normalizedUserName
不是你传递给UserManager
方法的字符串,而是它的大写版本。
所以最后回答你的问题:
GetNormalizedUserNameAsync
不会在标识框架中的任何位置使用。SetNormalizedUserNameAsync
在创建/更新用户期间使用,并使用用户名的大写版本进行调用。您不需要保留它,但它可能更可取,因为用户查找基于规范化版本。GetUserNameAsync
在调用GetNormalizedUserNameAsync
之前将规范化的字符串。未在标识框架中的其他任何位置使用。
最后说明:您可以通过在调用AddIdentity
之前添加作用域服务来更改ILookupNormalizer
:
public void ConfigureServices(IServiceCollection services)
{
services.AddScoped<ILookupNormalizer, UpperInvariantLookupNormalizer>();
services
.AddIdentity<User, Role>()
.AddUserStore<MyUserStore>()
.AddRoleStore<MyRoleStore>();
}