首先,您需要禁用 Identity 的内置验证机制:
services.AddIdentity<ApplicationUser, IdentityRole>(options =>
{
// disable the built-in validation
options.User.RequireUniqueEmail = false;
})
.AddEntityFrameworkStores<ApplicationDbContext>()
.AddDefaultTokenProviders();
然后,假设您正在使用带有标识模板的 ASP.NET Core 注册用户,您可以这样做:
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Register(RegisterViewModel model, string returnUrl = null)
{
ViewData["ReturnUrl"] = returnUrl;
if (ModelState.IsValid)
{
return View(model);
}
// check for duplicates
bool combinationExists = await _context.Users
.AnyAsync(x => x.UserName == model.UserName
&& x.Email == model.Email
&& x.TenantId == model.TenantId);
if (combinationExists)
{
return View(model);
}
// create the user otherwise
}
如果您不想在控制器中进行这种检查并希望保留身份流,则可以非常简单地创建自己的 IUserValidator<ApplicationUser>:
public class MultiTenantValidator : IUserValidator<ApplicationUser>
{
public async Task<IdentityResult> ValidateAsync(UserManager<ApplicationUser> manager, ApplicationUser user)
{
bool combinationExists = await manager.Users
.AnyAsync(x => x.UserName == user.UserName
&& x.Email == user.Email
&& x.TenantId == user.TenantId);
if (combinationExists)
{
return IdentityResult.Failed(new IdentityResult { Description = "The specified username and email are already registered in the given tentant" });
}
// here the default validator validates the username for valid characters,
// let's just say all is good for now
return IdentityResult.Success;
}
}
然后你会告诉 Identity 使用你的验证器:
services.AddIdentity<ApplicationUser, IdentityRole>()
.AddUserValidator<MultiTenantValidator>()
.AddEntityFrameworkStores<ApplicationDbContext>()
.AddDefaultTokenProviders();
这样,当您调用UserManager.CreateAsync 时,将在创建用户之前进行验证。