I'm working with Microsoft's Asp.Net Identity framework version 2, and am implementing my own IUserStore. My new class MyUserStore
implements the IUserStore<MyUserClass,int>
interface and the IUserPasswordStore<MyUserClass,int>
, which is what is required to use it with the UserManager<MyUserClass,int>
class. Or at least that's what I gathered from reading tutorials like this:
"The one required interface in the identity system is IUserStore" - Scott Allen
But this doesn't seem to be the case when I run the code.
I initialize my manager:
var uMan= new UserManager<MyUserClass, int>(new MyUserStore());
var sMan = new SignInManager<MyUserClass, int>(uMan,authCtxFromOwin);
And when sMan.PasswordSignIn(...) on the SignInManager is executed, no matter what, the SignInManager always runs functionality in the UserManager that depends on the optional interfaces. Here's the source for the PasswordSignInAsync method from the SignInManager class:
public virtual async Task<SignInStatus> PasswordSignInAsync(string userName, string password, bool isPersistent, bool shouldLockout)
{
...
if (await UserManager.IsLockedOutAsync(user.Id).WithCurrentCulture())
{
return SignInStatus.LockedOut;
}
if (await UserManager.CheckPasswordAsync(user, password).WithCurrentCulture())
{
return await SignInOrTwoFactor(user, isPersistent).WithCurrentCulture();
}
...
return SignInStatus.Failure;
}
It always calls UserManager.IsLockedOutAsync() before it tries to check the password, so if the store doesn't implement the IUserLockoutStore interface, an exception gets thrown every time no matter what.
Does this mean that to use the default functionality of the UserManager and SignInManager classes, you need to implement every I*Store interface?
It looks the the workaround is to inherit from SignInManager and override the PasswordSignInAsync method. Is that the standard practice?
Thanks!
What I found that Identity framework is not consistent with "optionality" of required I*Store. In some public methods it checks if the required Store is provided, in some other places it just calls for the method. I have not figured out which ones are absolutely required and which ones can be not called. So I'd go with the exception trail and implement whatever the stores are required for your application.
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