web-dev-qa-db-fra.com

Identité ASP.net Désactiver Utilisateur

Utilisation de la nouvelle identité ASP.net dans MVC 5, comment empêcher un utilisateur de se connecter? Je ne veux pas les supprimer, peut-être simplement désactiver leur compte pour une période donnée.

Quelqu'un a-t-il une idée à ce sujet car je ne vois pas de colonne d'état ni quoi que ce soit dans la table ASPNetUsers?.

27
Loren.Dorez

Update: Comme le souligne CountZero, si vous utilisez la version 2.1 +, vous devriez essayer d'utiliser la fonctionnalité de verrouillage qu'ils ont ajoutée en premier, avant d'essayer la solution ci-dessous. Voir leur article de blog pour un échantillon complet: http://blogs.msdn.com/b/webdev/archive/2014/08/05/announcing-rtm-of-asp-net-identity-2-1-0 .aspx


La version 2.0 possède l'interface IUserLockoutStore que vous pouvez utiliser pour verrouiller les utilisateurs, mais l'inconvénient est qu'il n'existe aucune fonctionnalité OOB permettant de l'exploiter au-delà des méthodes de transfert exposées par la classe UserManager. Par exemple, ce serait bien s'il incrémentait réellement le nombre de verrouillages dans le cadre du processus de vérification standard du nom d'utilisateur/mot de passe. Cependant, sa mise en œuvre est assez simple.

Step # 1: Créez un magasin d'utilisateurs personnalisé qui implémente IUserLockoutStore.

// I'm specifying the TKey generic param here since we use int's for our DB keys
// you may need to customize this for your environment
public class MyUserStore : IUserLockoutStore<MyUser, int>
{
    // IUserStore implementation here

    public Task<DateTimeOffset> GetLockoutEndDateAsync(MyUser user)
    {
        //..
    }

    public Task SetLockoutEndDateAsync(MyUser user, DateTimeOffset lockoutEnd)
    {
        //..
    }

    public Task<int> IncrementAccessFailedCountAsync(MyUser user)
    {
        //..
    }

    public Task ResetAccessFailedCountAsync(MyUser user)
    {
        //..
    }

    public Task<int> GetAccessFailedCountAsync(MyUser user)
    {
        //..
    }

    public Task<bool> GetLockoutEnabledAsync(MyUser user)
    {
        //..
    }

    public Task SetLockoutEnabledAsync(MyUser user, bool enabled)
    {
        //..
    }
}

Étape n ° 2: au lieu de UserManager, utilisez la classe suivante dans vos actions de connexion/déconnexion, en lui transmettant une instance de votre magasin d'utilisateurs personnalisé.

public class LockingUserManager<TUser, TKey> : UserManager<TUser, TKey>
    where TUser : class, IUser<TKey> 
    where TKey : IEquatable<TKey> 
{
    private readonly IUserLockoutStore<TUser, TKey> _userLockoutStore;

    public LockingUserManager(IUserLockoutStore<TUser, TKey> store)
        : base(store)
    {
        if (store == null) throw new ArgumentNullException("store");

        _userLockoutStore = store;
    }

    public override async Task<TUser> FindAsync(string userName, string password)
    {
        var user = await FindByNameAsync(userName);

        if (user == null) return null;

        var isUserLockedOut = await GetLockoutEnabled(user);

        if (isUserLockedOut) return user;

        var isPasswordValid = await CheckPasswordAsync(user, password);

        if (isPasswordValid)
        {
            await _userLockoutStore.ResetAccessFailedCountAsync(user);
        }
        else
        {
            await IncrementAccessFailedCount(user);

            user = null;
        }

        return user;
    }

    private async Task<bool> GetLockoutEnabled(TUser user)
    {
        var isLockoutEnabled = await _userLockoutStore.GetLockoutEnabledAsync(user);

        if (isLockoutEnabled == false) return false;

        var shouldRemoveLockout = DateTime.Now >= await _userLockoutStore.GetLockoutEndDateAsync(user);

        if (shouldRemoveLockout)
        {
            await _userLockoutStore.ResetAccessFailedCountAsync(user);

            await _userLockoutStore.SetLockoutEnabledAsync(user, false);

            return false;
        }

        return true;
    }

    private async Task IncrementAccessFailedCount(TUser user)
    {
        var accessFailedCount = await _userLockoutStore.IncrementAccessFailedCountAsync(user);

        var shouldLockoutUser = accessFailedCount > MaxFailedAccessAttemptsBeforeLockout;

        if (shouldLockoutUser)
        {
            await _userLockoutStore.SetLockoutEnabledAsync(user, true);

            var lockoutEndDate = new DateTimeOffset(DateTime.Now + DefaultAccountLockoutTimeSpan);

            await _userLockoutStore.SetLockoutEndDateAsync(user, lockoutEndDate);
        }
    }
}

Exemple:

    [AllowAnonymous]
    [HttpPost]
    public async Task<ActionResult> Login(string userName, string password)
    {
        var userManager = new LockingUserManager<MyUser, int>(new MyUserStore())
        {
            DefaultAccountLockoutTimeSpan = /* get from appSettings */,
            MaxFailedAccessAttemptsBeforeLockout = /* get from appSettings */
        };

        var user = await userManager.FindAsync(userName, password);

        if (user == null)
        {
            // bad username or password; take appropriate action
        }

        if (await _userManager.GetLockoutEnabledAsync(user.Id))
        {
            // user is locked out; take appropriate action
        }

        // username and password are good
        // mark user as authenticated and redirect to post-login landing page
    }

Si vous souhaitez verrouiller manuellement une personne, vous pouvez définir le drapeau dans lequel vous archivez MyUserStore.GetLockoutEnabledAsync().

9
Chris Staley
await userManager.SetLockoutEnabledAsync(applicationUser.Id, true);
await userManager.SetLockoutEndDateAsync(DateTime.Today.AddYears(10));
32
Helder Gurgel

Vous pouvez avoir une nouvelle classe, qui devrait être dérivée de la classe IdentityUser. Vous pouvez ajouter une propriété booléenne à la nouvelle classe et utiliser cette nouvelle propriété de prendre soin par vérification du processus de connexion. Je l'ai aussi très bien fait. Je pourrais vouloir jeter un oeil à: blog

0
Rahul Garg