I just made a custom implementation of Identity 2.0, and as you said, I did not find any useful documentation. But, fortunately, I managed to achieve my goal.
I will answer your question, assuming that you are using a multi-level N architecture that isolates your views from business logic and business logic from the level of data access. And provided that you use an injection container for addiction, such as Unity.
I will explain the steps you must follow in order to use the Identity platform with user data access:
First you must declare your domain class, implementing IUser and, if you want, add custom properties to it:
//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; } }
Then, at the business logic level, you should have a class that processes all tasks related to user authorization, logging in, password recovery, and others. This class must inherit from UserManager. The result will be something like this:
// 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; } }
When inheriting from UserManager, it will provide a series of methods used by Identity and force your class to call the base constructor, passing the store, but not any store, for the store, you must have interfaces: IUserStore, IPasswordStore, depending on your requirements.
That's when interesting things happen. In your data access layer, you must have a custom implementation of the repository template connecting to the NoSQL database (let's say this is Mongo). So your ICustomUserMongoRepository should look something like this:
public interface ICustomUserMongoRepository : IUserPasswordStore<CustomUser, Guid>, IUserEmailStore<CustomUser, Guid>, IUserRoleStore<CustomUser, Guid> { }
And your Mongo repository should be something like this
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 } // ... }
Then your controller will look something like this:
public class AuthController : Controller { private readonly IAuthorizationManager manager;
IMPORTANT!
The IAuthorizationManager interface is used to provide quality software based on SOLID principles. And if you take a closer look and delve deeper into it, you will notice that this interface must have all UserManager methods to allow AuthController to call all the inherited AuthorizationManager methods from the UserManager class
Sorry for the long post. It is rather difficult to explain the whole process in a few lines. I hope this helps. If you have any doubts or questions, please comment on this answer and I will answer you as soon as possible.