I'm very new to ASP.NET Identity and please bear with me if this question seems silly.
When I read the definition for the UserStore
and the UserManager
classes on the Microsoft website which are in the links below, it looks like both classes define operations around users (like Add, Find, Delete and Modify).
So when do I use one over the other?
https://msdn.microsoft.com/en-us/library/dn315446(v=vs.108).aspx https://msdn.microsoft.com/en-us/library/dn613290(v=vs.108).aspx
The ASP.NET Identity UserManager class is used to manage users e.g. registering new users, validating credentials and loading user information. It is not concerned with how user information is stored. For this it relies on a UserStore (which in our case uses Entity Framework).
A user store is the database where information about the users and user roles is stored, including log-in name, password, first name, last name, and e-mail address. The user stores of all WSO2 Carbon-based products are embedded H2 databases except for WSO2 Identity Server, which has an embedded LDAP as its user store.
The security stamp is a Guid stored in the database against the user. It gets updated when certain actions take place within the Identity UserManager class and provides a way to invalidate old tokens when an account has changed.
The IUserStore<TUser> interface is the only interface you must implement in the user store.
Things are quite complicated there and could have been easier.
UserManger
is the ... manager. It does not really interact with the storage, the database. That's what the UserStore
does.
In fact UserManager has a constructor which needs a UserStore.
Why would you have to different object to manage users? Well, the main reason is you can decide not to use EF and create your own user store.
Things get clearer when you try to implement your own storage provider. I did it and my code can be downloaded from github.
This is the UserManager. As you can see there's not much in there. Just a few lines of code to configure the validator.
UserStore on the contrary, is quite big. In that example I've implemented a few interfaces and overridden a few methods. That's what you would do if you want to customize the interaction with the database and/or extend your classes.
You don't normally interact with the UserStore
and in fact it's hidden. You just create it and pass it to the UserManager
and ... forget about it.
You can always customize your UserManager and expose the UserStore:
public class UserManager : UserManager<User, int> { public UserManager(IUserStore<User, int> store): base(store) { this.Store = store; } public IUserStore<User, int> Store { get; set; } }
and, maybe, ovveride some of the methods:
public class UserManager : UserManager<User, int> { public UserManager(IUserStore<User, int> store): base(store) { this.Store = store; } public IUserStore<User, int> Store { get; set; } public override System.Threading.Tasks.Task<IdentityResult> CreateAsync(User user) { return base.CreateAsync(user); } }
but that would be pointless unless you have to do some peculiar customization.
Let's say you want to create a user using the store instead of the manager. You can do something like this:
await this.UserManager.Store.CreateAsync(new Custom.Identity.User() { UserName = "LeftyX" });
and it would work.
In the class above, as you can see, I've overridden the CreateAsync
in the UserManager.
That method calls UserStore.CreateAsync()
and in fact, you have to call the base method CreateAsync:
public override System.Threading.Tasks.Task<IdentityResult> CreateAsync(User user) { return base.CreateAsync(user); }
If you don't do that and, for example, return null instead, the UserStore.CreateAsync
wouldn't be called and the user wouldn't be created.
It makes sense at the end.
I guess the best way to understand how this framework works is to try and customize/implement your solution with your own storage and see how all the classes interact with each other.
The sample project does not interact with a database but uses a json storage. It's very easy to debug. Give it a go and things will be clearer at some point.
I was watching Identity tutorial on YouTube, and I think this screenshot might help:
So UserManager is the actual class that you should work with but it does not know how to store and retrieve data from database. it even does not know where the data is going to and coming from.
For those things it uses UserStore and says to it for example "Hey UserStore I have a new User that needs to be saved for future use, I don't know where you're going to save it and how you're going to do it, just save it for me"
Then the UserStore does the actual work such as where should the data be saved? which database? and how? the default one uses EF and SQL Server so if you want to use some other database for example MySQL you're going to need a different UserStore.
This is one of the features that were added to Identity compared to Membership that only worked with SQL Server.
The same concept is true for RoleManager and RoleStore.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With