實現 UserManager 以使用自定義類和儲存過程
我的應用程序的所有身份驗證和授權過程都是使用儲存過程完成的。我編寫了一個包含我需要的所有功能的類,例如
GetUsers,Login,AddRole,AddMember等。管理使用者、角色和權限的管理頁面也是通過使用這個類來完成的。我只需要添加
authentication(我的意思是那個authorize屬性),用於登錄和註銷的 cookie,並為每個登錄儲存一些伺服器端數據。我想我需要為此實施Identity?在那種情況下,你能指導我實施嗎?似乎您需要做的最基本的事情是實現一個
create將實例傳遞IUserStore給建構子的方法。但是我不需要任何使用者或角色的表,我該如何實現這個方法?這是目前類,如果您需要查看我使用儲存過程的自定義身份驗證類,請告訴我。
public class AppUserManager : UserManager<AppUser> { public AppUserManager(IUserStore<AppUser> store) : base(store) { } public static AppUserManager Create(IdentityFactoryOptions<AppUserManager> options, IOwinContext context) { //AppUserManager manager = new AppUserManager(); //return manager; return null; } }
正如alisabzevari建議的那樣,您必須實現IUserStore。
您甚至不依賴於定義的儲存和表結構。您可以自定義儲存層的每一位。
我做了一些實驗並嘗試實現自己的
UserManager並RoleManager使用不同的儲存,例如Biggy:.NET 的基於文件的文件儲存。
你可以在 GitHub 上找到程式碼。
首先要做的是實現您
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, }; } }然後定義你的
IUserStore實現。您必須實現的主要方法是CreateAsync:public System.Threading.Tasks.Task CreateAsync(User user) { // Saves the user in your storage. return Task.FromResult(user); }它將收到一個
IUser您必須保留在自定義儲存中並返回的資訊。如果您查看我實現的程式碼,您會發現我使用了一些介面
IUserRoleStore,等等,因為我需要使用角色和聲明IUserPasswordStore。IUserClaimStore我也實現了我自己的
SignInManager.一旦你定義了所有的實現,你就可以在啟動時引導一切:
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然後將呼叫另一個方法: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的每個方法中都插入斷點,並查看所有內容如何組合在一起。