简体   繁体   中英

Implementing the Microsoft AspNet Identity IUserLockoutStore

I am using Microsoft.AspNet.Identity for logging into my c# mvc web application. I have implemented the different User Stores including the Lockout User Store. But I can't get it to work properly. In my Custom User Manager I set the max tries, lockout time etc:

manager.UserLockoutEnabledByDefault = true;
manager.DefaultAccountLockoutTimeSpan = TimeSpan.FromMinutes(30);
manager.MaxFailedAccessAttemptsBeforeLockout = 5;

If I use the above code and parameters my user never gets locked. If I set the manager.MaxFailedAccessAttemptsBeforeLockout to 2, the my User gets locked after one try. Does anyone have a tutorial on how to correctly implement the "IUserLockoutStore" interface? I've been searching Google all morning and am not getting closer to my goal. Here is my current implementation of the "IUserLockoutStore" interface.

    public Task<DateTimeOffset> GetLockoutEndDateAsync(Gebruiker user)
    {
        var lockOutDate = user.LockOutDate.HasValue ? user.LockOutDate.Value : new DateTimeOffset(DateTime.Now.AddMinutes(-5));
        return Task.FromResult(lockOutDate);
    }
    public Task SetLockoutEndDateAsync(Gebruiker user, DateTimeOffset lockoutEnd)
    {
        user.LockOutDate = lockoutEnd;
        user.IsLocked = true;
        return Context.SaveChangesAsync();
    }

    public Task<int> IncrementAccessFailedCountAsync(Gebruiker user)
    {
        user.LoginTry++;
        return Context.SaveChangesAsync();
    }

    public Task ResetAccessFailedCountAsync(Gebruiker user)
    {
        user.LoginTry = 0;
        return Context.SaveChangesAsync();
    }

    public Task<int> GetAccessFailedCountAsync(Gebruiker user) => Task.FromResult(user.LoginTry);

    public Task<bool> GetLockoutEnabledAsync(Gebruiker user) => Task.FromResult(true);

    public Task SetLockoutEnabledAsync(Gebruiker user, bool enabled)=> Task.FromResult(enabled);

My implementation is very similar to yours except for these two things:

In GetLockoutEndDateAsync I use utc time:

... new DateTimeOffset(DateTime.UtcNow.AddMinutes(-5))

Also (and perhaps more significantly), your return value from IncrementAccessFailedCountAsync should return the count (but you are returning the result of SaveChanges ):

public Task<int> IncrementAccessFailedCountAsync(Gebruiker user)
{
    user.LoginTry++;
    Context.SaveChangesAsync();
    return user.LoginTry;
}

It is just a coincidence that SaveChangesAsync also returns an int which is probably why you didn't notice this.

Another note is that you don't have to call Context.SaveChangesAsync() in the first place. This is handled by your implementation of IUserStore . Your IUserLockoutStore (and others like IUserLoginStore and IUserEmailStore etc) don't save to the DB. The infrastructure calls those interfaces to set things, then at the end call IUserStore.UpdateAsync (or .CreateAsync ). So it should simply be:

public Task<int> IncrementAccessFailedCountAsync(Gebruiker user)
{
    user.LoginTry++;
    return Task.FromResult(user.LoginTry);
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM