如何为 ASP.NET 5 MVC 6 实施 NoSQL 身份提供程序
How to implement a NoSQL Identity provider for ASP.NET 5 MVC 6
根本没有文档。
我知道我必须实现我自己的 IUser、我自己的 IUserSTore 并以某种方式在 startup.cs 中注册它们。我删除了对 EntityFramework 的所有引用,因为我想使用 NoSQL 后端。
"convention" 哲学非常好,只要它被记录在案并且 public。
有什么提示吗?
我刚刚自定义实现了 Identity 2.0,正如您所说,我没有找到任何有用的文档。但幸运的是,我设法实现了我的目标。
我会假设您使用 N 层架构来回答您的问题,将您的视图与业务逻辑隔离开来,并将业务逻辑与数据访问层隔离开来。并假设还使用了依赖注入容器,例如 Unity。
我将解释使用具有自定义数据访问权限的身份框架必须遵循的步骤:
首先,您必须声明您的域 class,实施 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; }
}
然后,在您的业务逻辑层中,您应该有一个 class 来处理与用户授权、登录、密码恢复等相关的所有任务。这个class 必须继承自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 使用的一系列方法,它会强制你的 class 调用基础构造函数传递一个存储库,但不是任何存储库,存储库必须实现接口: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 继承的所有方法 class
抱歉这么久 post。很难用几行来解释整个过程。我希望它有所帮助。如果您有任何疑问或问题,请评论此答案,我会尽快回复。
根本没有文档。
我知道我必须实现我自己的 IUser、我自己的 IUserSTore 并以某种方式在 startup.cs 中注册它们。我删除了对 EntityFramework 的所有引用,因为我想使用 NoSQL 后端。
"convention" 哲学非常好,只要它被记录在案并且 public。
有什么提示吗?
我刚刚自定义实现了 Identity 2.0,正如您所说,我没有找到任何有用的文档。但幸运的是,我设法实现了我的目标。
我会假设您使用 N 层架构来回答您的问题,将您的视图与业务逻辑隔离开来,并将业务逻辑与数据访问层隔离开来。并假设还使用了依赖注入容器,例如 Unity。
我将解释使用具有自定义数据访问权限的身份框架必须遵循的步骤:
首先,您必须声明您的域 class,实施 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; }
}
然后,在您的业务逻辑层中,您应该有一个 class 来处理与用户授权、登录、密码恢复等相关的所有任务。这个class 必须继承自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 使用的一系列方法,它会强制你的 class 调用基础构造函数传递一个存储库,但不是任何存储库,存储库必须实现接口: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 继承的所有方法 class
抱歉这么久 post。很难用几行来解释整个过程。我希望它有所帮助。如果您有任何疑问或问题,请评论此答案,我会尽快回复。