【问题标题】:How to implement a NoSQL Identity provider for ASP.NET 5 MVC 6 [closed]如何为 ASP.NET 5 MVC 6 实现 NoSQL 身份提供程序 [关闭]
【发布时间】:2015-09-13 19:31:20
【问题描述】:

根本没有文档。

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

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

有什么提示吗?

【问题讨论】:

  • 似乎和这个问题很相似stackoverflow.com/questions/31795792/…
  • 谢谢。我正在启发式地学习。注意不要使用旧的身份包。这是我的情况。现在我正在解决我在 AddIdentity().AddUserStore().AddRoleStore().AddDefaultTokenProviders(); 中注册自定义 UserStore 和 RoleStore 后的异常
  • 这是一个很好且有效的示例 (MVC 6) 和实现库,带有 ASP.NET 5 Identity (>= v3) 框架,没有 MongoDB.Driver 实体框架 (>= v2.1.0) github.com/saan800/SaanSoft.AspNet.Identity3.MongoDB
  • 到底为什么这个封闭太宽泛了?这是一个特定的主题。我也在寻找同样的东西。

标签: asp.net asp.net-identity asp.net-core asp.net-core-mvc


【解决方案1】:

我刚刚做了一个 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使用的方法,它会强制你的类调用基础构造函数传递一个repository,但不是任何repository,repository必须实现接口: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类继承的所有方法

抱歉,帖子太长了。很难用几行来解释整个过程。我希望它有所帮助。如果您有任何疑问或问题,请评论此答案,我会尽快回复。

【讨论】:

  • 谢谢!我已经为 Identity 3 实现了我的 Identity 类。它比 Identity 2 容易得多。您只需要覆盖 Identity 3 中的 UserStore 和 RoleStore!
  • 更好。问候
  • 让我问你一个问题,在 GetEmailAsync 之类的方法中,你收到一个用户作为参数,我必须做什么,在 DB 中搜索与参数用户 ID 相同的用户,然后然后返回它的电子邮件???
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-06-07
  • 1970-01-01
  • 1970-01-01
  • 2014-08-25
  • 2015-02-20
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多