Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Store does not implement IUserLockoutStore<TUser>

I'm trying to implement own DAL for asp.net Identity 2.0 with functionality that I need. I don't need Account Lockout functionality. But When I try to call

var result = await SignInManager.PasswordSignInAsync(model.Login, model.Password, model.RememberMe, shouldLockout: false);

I get System.NotSupportedException:Store does not implement IUserLockoutStore<TUser>.

So why should I need to implement IUserLockoutStore if I dont need it?

like image 676
FunctorPrototype Avatar asked Jun 20 '15 17:06

FunctorPrototype


1 Answers

See this answer: When implementing your own IUserStore, are the "optional" interfaces on the class actually optional?

You will need to trick or override the method you are trying to call in your store to implement one that does not use the "optional" lockout store.

You may be unpleasantly surprised to find that you also need to implement the "optional" interface for two-factor. Use the same answer below to do so unless you do have a means of two-factor.

First, though, here's the default implementation:

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;
        }

One answer: create useless stores.

    #region LockoutStore
    public Task<int> GetAccessFailedCountAsync(MyUser user)
    {
        throw new NotImplementedException();
    }

    public Task<bool> GetLockoutEnabledAsync(MyUser user)
    {
        return Task.Factory.StartNew<bool>(() => false);
    }

    public Task<DateTimeOffset> GetLockoutEndDateAsync(MyUser user)
    {
        throw new NotImplementedException();
    }

    public Task<int> IncrementAccessFailedCountAsync(MyUser user)
    {
        throw new NotImplementedException();
    }

    public Task ResetAccessFailedCountAsync(MyUser user)
    {
        throw new NotImplementedException();
    }

    public Task SetLockoutEnabledAsync(MyUser user, bool enabled)
    {
        throw new NotImplementedException();
    }

    public Task SetLockoutEndDateAsync(MyUser user, DateTimeOffset lockoutEnd)
    {
        throw new NotImplementedException();
    }
    #endregion
}

Another solution: override to just not use it.

public virtual async Task<SignInStatus> PasswordSignInAsync(string userName, string password, bool isPersistent, bool shouldLockout)
        {
           ...
            if (false)
            {
                return SignInStatus.LockedOut;
            }
            if (await UserManager.CheckPasswordAsync(user, password).WithCurrentCulture())
            {
                return await SignInOrTwoFactor(user, isPersistent).WithCurrentCulture();
            }
            ...
            return SignInStatus.Failure;
        }

cf/ https://github.com/aspnet/AspNetIdentity/blob/master/src/Microsoft.AspNet.Identity.Owin/SignInManager.cs

like image 133
tacos_tacos_tacos Avatar answered Sep 19 '22 11:09

tacos_tacos_tacos