如何为ASP实现NoSQL身份提供程序.Net 5 MVC 6



根本没有文档。

我知道我必须实现我自己的IUser,我自己的IUserSTore并以某种方式在startup.cs中注册它们。我删除了对EntityFramework的所有引用,因为我想使用NoSQL后端。

"约定"的理念是非常好的,只要它是被记录和公开的。

提示吗?

我刚刚做了一个Identity 2.0的自定义实现,正如您所说,我没有找到任何有用的文档。但幸运的是,我设法实现了我的目标。

我将回答您的问题,假设您正在使用N层架构,将视图与业务逻辑隔离,将业务逻辑与数据访问层隔离。假设有一个依赖注入容器被使用,比如Unity。

我将解释使用具有自定义数据访问的Identity框架必须遵循的步骤:

首先你必须声明你的域类,实现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从UserManager类中调用AuthorizationManager继承的所有方法

很抱歉写了这么久。很难用几句话来解释整个过程。我希望这对你有帮助。如果你有任何疑问或问题,请评论这个答案,我会尽快回复。

相关内容

  • 没有找到相关文章

最新更新