正如alisabzevari 所建议的,您必须实施您的IUserStore。
您甚至不依赖于定义的存储和表结构。
您可以自定义存储层的每一位。
我做了一些实验并尝试使用不同的存储实现我自己的UserManager 和RoleManager,例如Biggy:
.NET 的基于文件的文档存储。
您可以在 GitHub 上找到代码 here。
首先要做的是实现您的UserManager,您可以在其中配置密码验证要求:
public class AppUserManager : UserManager<AppUser, int>
{
public AppUserManager (IUserStore<AppUser, int> store): base(store)
{
this.UserLockoutEnabledByDefault = false;
// this.DefaultAccountLockoutTimeSpan = TimeSpan.FromMinutes(10);
// this.MaxFailedAccessAttemptsBeforeLockout = 10;
this.UserValidator = new UserValidator<User, int>(this)
{
AllowOnlyAlphanumericUserNames = false,
RequireUniqueEmail = false
};
// Configure validation logic for passwords
this.PasswordValidator = new PasswordValidator
{
RequiredLength = 4,
RequireNonLetterOrDigit = false,
RequireDigit = false,
RequireLowercase = false,
RequireUppercase = false,
};
}
}
然后定义你的IUserStoreimplementation。你必须实现的主要方法是CreateAsync:
public System.Threading.Tasks.Task CreateAsync(User user)
{
// Saves the user in your storage.
return Task.FromResult(user);
}
它将收到一个IUser,您必须将其保存在您的自定义存储中并返回。
如果您查看我的代码 implemented,您会发现我使用了一些接口 IUserRoleStore、IUserPasswordStore、IUserClaimStore 等,因为我需要使用角色和声明。
我还实现了我的ownSignInManager。
一旦您定义了所有实现,您就可以在startup 引导所有内容:
app.CreatePerOwinContext<Custom.Identity.UserManager>(() => new Custom.Identity.UserManager(new Custom.Identity.UserStore(folderStorage)));
app.CreatePerOwinContext<Custom.Identity.RoleManager>(() => new Custom.Identity.RoleManager(new Custom.Identity.RoleStore(folderStorage)));
app.CreatePerOwinContext<Custom.Identity.SignInService>((options, context) => new Custom.Identity.SignInService(context.GetUserManager<Custom.Identity.UserManager>(), context.Authentication));
您可以查看我的AccountController 我尝试验证用户的位置:
var result = await SignInManager.PasswordSignInAsync(model.Email, model.Password, model.RememberMe, shouldLockout: false);
switch (result)
{
case SignInStatus.Success:
return RedirectToLocal(returnUrl);
case SignInStatus.LockedOut:
return View("Lockout");
case SignInStatus.RequiresVerification:
return RedirectToAction("SendCode", new { ReturnUrl = returnUrl, RememberMe = model.RememberMe });
case SignInStatus.Failure:
default:
ModelState.AddModelError("", "Invalid login attempt.");
return View(model);
}
一旦PasswordSignInAsync 被调用,您会注意到UserManager 的一些方法将被调用。第一个将是FindByNameAsync:
public System.Threading.Tasks.Task<User> FindByNameAsync(string userName)
{
//Fetch your user using the username.
return Task.FromResult(user);
}
我猜你必须实现你的存储过程,你将从数据库中获取你的用户。
那么另一个方法FindByIdAsync 将是called:
public System.Threading.Tasks.Task<User> FindByIdAsync(int userId)
{
// Fetch - again - your user from the DB with the Id.
return Task.FromResult(user);
}
再次,您将不得不使用您的存储过程通过他/她的 id 找到您的用户。
如果您从 github 下载我的项目并使用它,您会注意到其中大多数方法将被多次调用。不要害怕。它就是这样儿的。
我建议您在UserStore 的每个方法中都插入断点,然后看看它们是如何组合在一起的。