如何為 ASP.NET 5 MVC 6 實現 NoSQL 身份提供程序
根本沒有文件。
我知道我必須實現我自己的 IUser、我自己的 IUserSTore 並以某種方式在 startup.cs 中註冊它們。我刪除了對 EntityFramework 的所有引用,因為我想使用 NoSQL 後端。
“公約”理念是非常好的,只要它被記錄和公開。
有什麼提示嗎?
我剛剛做了一個 Identity 2.0 的自定義實現,正如你所說,我沒有找到任何有用的文件。但幸運的是,我成功地實現了我的目標。
假設您使用的是 N 層架構,我將回答您的問題,將您的視圖與您的業務邏輯隔離開來,並將您的業務邏輯與您的數據訪問層隔離開來。並假設使用了一個依賴注入容器,例如 Unity。
我將解釋將身份框架與自定義數據訪問一起使用時必須遵循的步驟:
首先,您必須聲明您的域類,實現 IUser,如果您願意,還可以向其中添加自定義屬性:
//This class is implementing IUser with Guid as type because //I needed to use Guid as default Id. public class CustomUser : IUser<Guid> { public string CustomProperty { get; set; } }然後,在您的業務邏輯層中,您應該有一個類來處理與使用者授權、登錄、密碼恢復等相關的所有任務。這個類必須繼承自 UserManager。結果將如下所示:
// Business layer class must inherit from UserManager with // CustomUser and Guid as types public AuthorizationManager : UserManager<CustomUser, Guid>, IAuthorizationManager { private readonly ICustomUserMongoRepository repository; private readonly ICustomEmailService emailService; private readonly ICustomTokenProvider tokenProvider; // Parameters being injected by Unity. // container.RegisterType<ICustomUserMongoRepository, CustomUserMongoRepository>(); // .. // .. public AuthorizationManager( ICustomUserMongoRepository repository, ICustomEmailService emailService, ICustomTokenProvider tokenProvider ) // calling base constructor passing // a repository which implements // IUserStore, among others. : base(repository) { this.repository = repository; // this.EmailService is a property of UserManager and // it has to be set to send emails by your class this.EmailService = emailService; // this.UserTokenProvider is a property of UserManager and // it has to be set to generate tokens for user password // recovery and confirmation tokens this.UserTokenProvider = tokenProvider; } }從 UserManager 繼承時,它將提供 Identity 使用的一系列方法,它會強制您的類呼叫基建構子傳遞儲存庫,但不是任何儲存庫,儲存庫必須實現介面:IUserStore、IPasswordStore,具體取決於根據您的要求。
這是很酷的事情發生的時候。在您的數據訪問層中,您必須將儲存庫模式的自定義實現連接到 NoSQL 數據庫(假設它是 Mongo)。因此,您的 ICustomUserMongoRepository 應如下所示:
public interface ICustomUserMongoRepository : IUserPasswordStore<CustomUser, Guid>, IUserEmailStore<CustomUser, Guid>, IUserRoleStore<CustomUser, Guid> { }你的 Mongo 儲存庫應該是這樣的
public CustomUserMongoRepository : MongoRepository<CustomUser>, ICustomUserMongoRepository { // Here you must have your custom implementation (using Mongo) of // ICustomUserRepository which is requesting your class to // implement IUserPasswordStore methods as well public Task CreateAsync(CustomUser user) { //Custom Mongo implementation } public Task DeleteAsync(CustomUser user) { //Custom Mongo implementation } public Task GetEmailAsync(CustomUser user) { //Custom Mongo implementation } public Task GetEmailConfirmedAsync(CustomUser user) { //Custom Mongo implementation } // ... }然後你的控制器看起來像這樣:
public class AuthController : Controller { private readonly IAuthorizationManager manager; // Manager being injected by Unity. // container.RegisterType<IAuthorizationManager, AuthorizationManager>(); public AuthController(IAuthorizationManager manager) { this.manager = manager; } // Receives a LogInViewModel with all data needed to allow users to log in [HttpPost] public async Task<ActionResult> LogIn(LogInViewModel viewModel) { // FindAsync it's a method inherited from UserManager, that's // using the Mongo repository passed to the base class // in the AuthorizationManager constructor var user = this.manager.FindAsync(viewModel.Email, viewModel.Password); if(user != null){ // Log in user and create user session } else { // Wrong username or password } } }重要的!
介面 IAuthorizationManager 用於傳遞基於 SOLID 原則的高質量軟體。而且如果你仔細觀察並深入思考,你會注意到這個介面必須具有所有 UserManager 的方法,以允許 AuthController 呼叫 AuthorizationManager 從 UserManager 類繼承的所有方法
對不起,很長的文章。很難用幾行來解釋整個過程。我希望它有所幫助。如果您有任何疑問或問題,請評論此答案,我會盡快回复。