Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

When implementing your own IUserStore, are the "optional" interfaces on the class actually optional?

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!

like image 430
Rafe Avatar asked Sep 06 '14 19:09

Rafe


1 Answers

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.

like image 172
trailmax Avatar answered Sep 27 '22 23:09

trailmax