Asp.net

如何為 ASP.NET 5 MVC 6 實現 NoSQL 身份提供程序

  • January 10, 2019

根本沒有文件。

我知道我必須實現我自己的 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 類繼承的所有方法

對不起,很長的文章。很難用幾行來解釋整個過程。我希望它有所幫助。如果您有任何疑問或問題,請評論此答案,我會盡快回复。

引用自:https://stackoverflow.com/questions/32553714