Подтвердить что ты не робот

Отключить пользователя в ASPNET-идентификаторе 2.0

Я ищу способ отключить пользователя, а не удалять его из системы, чтобы сохранить целостность данных связанных данных. Но похоже, что ASPNET-идентификатор предлагает только Delete Acccount.

Существует новая функция блокировки, но, похоже, блокировка может управляться для отключения пользователя, но только блокирует пользователя после определенного количества попыток неправильного пароля.

Любые другие варианты?

4b9b3361

Ответ 1

Когда вы создаете сайт с установленными битами Identity, ваш сайт будет иметь файл под названием "IdentityModels.cs". В этом файле находится класс ApplicationUser, который наследуется от IdentityUser.

// You can add profile data for the user by adding more properties to your ApplicationUser class, please visit http://go.microsoft.com/fwlink/?LinkID=317594 to learn more.
public class ApplicationUser : IdentityUser

В комментариях есть хорошая ссылка, для облегчения нажмите здесь

В этом учебном пособии вы точно укажете, что вам нужно сделать, чтобы добавить пользовательские свойства для вашего пользователя.

И вообще, даже не смотрите на учебник.

1) добавьте свойство в класс ApplicationUser, например:

public bool? IsEnabled { get; set; }

2) добавьте столбец с тем же именем в таблицу AspNetUsers в вашей БД.

3) бум, что это!

Теперь в вашем AccountController у вас есть действие Register следующим образом:

public async Task<ActionResult> Register(RegisterViewModel model)
        {
            if (ModelState.IsValid)
            {
                var user = new ApplicationUser { UserName = model.Email, Email = model.Email, IsEnabled = true };
                var result = await UserManager.CreateAsync(user, model.Password);
                if (result.Succeeded)

Я добавил IsEnabled = true при создании объекта ApplicationUser. Теперь значение будет сохранено в вашем новом столбце таблицы AspNetUsers.

Затем вам нужно будет обработать это значение как часть процесса входа в систему, переопределив PasswordSignInAsync в ApplicationSignInManager.

Я сделал это следующим образом:

public override Task<SignInStatus> PasswordSignInAsync(string userName, string password, bool rememberMe, bool shouldLockout)
    {
        var user = UserManager.FindByEmailAsync(userName).Result;

        if ((user.IsEnabled.HasValue && !user.IsEnabled.Value) || !user.IsEnabled.HasValue)
        {
            return Task.FromResult<SignInStatus>(SignInStatus.LockedOut);
        }

        return base.PasswordSignInAsync(userName, password, rememberMe, shouldLockout);
    }

Ваш пробег может отличаться, и вы можете не захотеть вернуть этот SignInStatus, но вы получите эту идею.

Ответ 2

Вам не нужно создавать настраиваемое свойство. Фокус в том, чтобы установить LockoutEnabled на пользователе Identity И установите LockoutoutEndDateUtc на будущую дату из вашего кода, чтобы заблокировать пользователя. Затем вызов UserManager.IsLockedOutAsync(user.Id) вернет false.

Оба параметра LockoutEnabled и LockoutoutEndDateUtc должны соответствовать критериям истинной и будущей даты для блокировки пользователя. Если, например, значение LockoutoutEndDateUt c 2014-01-01 00:00:00.000 и LockoutEnabled равно true, вызов UserManager.IsLockedOutAsync(user.Id) по-прежнему будет возвращен true. Я могу понять, почему Microsoft разработала его таким образом, чтобы вы могли установить временной интервал в том, как долго пользователь блокируется.

Однако я бы сказал, что это должно быть, если LockoutEnabled is true, тогда пользователь должен быть заблокирован, если LockoutoutEndDateUtc равно NULL ИЛИ будущей дате. Таким образом, вам не нужно беспокоиться в коде о настройке двух свойств (LockoutoutEndDateUtc is NULL по умолчанию). Вы можете просто установить LockoutEnabled на true, а если LockoutoutEndDateUtc - NULL, пользователь будет заблокирован на неопределенный срок.

Ответ 3

Свойство LockoutEnabled по умолчанию для User не является свойством, указывающим, заблокирован ли пользователь в настоящее время. Это свойство, указывающее, должен ли пользователь подвергаться блокировке или нет, если AccessFailedCount достигает значения MaxFailedAccessAttemptsBeforeLockout. Даже если пользователь заблокирован, его единственная временная мера, которая запрещает пользователю использовать свойство LockedoutEnddateUtc. Таким образом, чтобы окончательно отключить или приостановить учетную запись пользователя, вы можете ввести свой собственный флаг.

Ответ 4

Вам нужно будет ввести свой собственный флаг в пользовательский класс, основанный на IdentityUser, и реализовать/применить свою собственную логику о включении/отключении и предотвращении входа пользователя в систему, если он отключен.

Ответ 5

Вы можете использовать эти классы... Чистая реализация идентификатора ASP.NET... Это мой собственный код. int здесь для первичного ключа, если вам нужен другой тип для первичного ключа, который вы можете изменить.

IdentityConfig.cs

public class ApplicationUserManager : UserManager<ApplicationUser, int>
{
    public ApplicationUserManager(IUserStore<ApplicationUser, int> store)
        : base(store)
    {
    }
    public static ApplicationUserManager Create(IdentityFactoryOptions<ApplicationUserManager> options, IOwinContext context)
    {
        var manager = new ApplicationUserManager(new ApplicationUserStore(context.Get<ApplicationContext>()));
        manager.UserValidator = new UserValidator<ApplicationUser, int>(manager)
        {
            AllowOnlyAlphanumericUserNames = false,
            RequireUniqueEmail = true
        };
        manager.PasswordValidator = new PasswordValidator
        {
            RequiredLength = 6,
            RequireNonLetterOrDigit = true,
            RequireDigit = true,
            RequireLowercase = true,
            RequireUppercase = true,
        };
        manager.UserLockoutEnabledByDefault = false;
        var dataProtectionProvider = options.DataProtectionProvider;
        if (dataProtectionProvider != null)
        {
            manager.UserTokenProvider =
                new DataProtectorTokenProvider<ApplicationUser, int>(
                    dataProtectionProvider.Create("ASP.NET Identity"));
        }
        return manager;
    }
}
public class ApplicationSignInManager : SignInManager<ApplicationUser, int>
{
    public ApplicationSignInManager(ApplicationUserManager userManager, IAuthenticationManager authenticationManager) :
        base(userManager, authenticationManager) { }
    public override Task<ClaimsIdentity> CreateUserIdentityAsync(ApplicationUser user)
    {
        return user.GenerateUserIdentityAsync((ApplicationUserManager)UserManager);
    }
    public static ApplicationSignInManager Create(IdentityFactoryOptions<ApplicationSignInManager> options, IOwinContext context)
    {
        return new ApplicationSignInManager(context.GetUserManager<ApplicationUserManager>(), context.Authentication);
    }
}
public class ApplicationRoleManager : RoleManager<ApplicationRole, int>
{
    public ApplicationRoleManager(IRoleStore<ApplicationRole, int> store)
        : base(store)
    {
    }
}
public class ApplicationRoleStore : RoleStore<ApplicationRole, int, ApplicationUserRole>
{
    public ApplicationRoleStore(ApplicationContext db)
        : base(db)
    {
    }
}
public class ApplicationUserStore : UserStore<ApplicationUser, ApplicationRole, int,
ApplicationLogin, ApplicationUserRole, ApplicationClaim>
{
    public ApplicationUserStore(ApplicationContext db)
        : base(db)
    {
    }
}

IdentityModel.cs

public class ApplicationUser : IdentityUser<int, ApplicationLogin, ApplicationUserRole, ApplicationClaim>
{   
    //your property 
    //flag for users state (active, deactive or enabled, disabled)
    //set it false to disable users
    public bool IsActive { get; set; }
    public ApplicationUser()
    {
    }
    public async Task<ClaimsIdentity> GenerateUserIdentityAsync(UserManager<ApplicationUser, int> manager)
    {
        var userIdentity = await manager.CreateIdentityAsync(this, DefaultAuthenticationTypes.ApplicationCookie);
        return userIdentity;
    }
}
public class ApplicationUserRole : IdentityUserRole<int>
{
}
public class ApplicationLogin : IdentityUserLogin<int>
{
    public virtual ApplicationUser User { get; set; }
}
public class ApplicationClaim : IdentityUserClaim<int>
{
    public virtual ApplicationUser User { get; set; }
}
public class ApplicationRole : IdentityRole<int, ApplicationUserRole>
{
    public ApplicationRole()
    {
    }
}
public class ApplicationContext : IdentityDbContext<ApplicationUser, ApplicationRole, int, ApplicationLogin, ApplicationUserRole, ApplicationClaim>
{
    //web config connectionStringName DefaultConnection change it if required
    public ApplicationContext()
        : base("DefaultConnection")
    {
        Database.SetInitializer<ApplicationContext>(new CreateDatabaseIfNotExists<ApplicationContext>());
    }
    public static ApplicationContext Create()
    {
        return new ApplicationContext();
    }
    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder);
        modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
        modelBuilder.Conventions.Remove<ManyToManyCascadeDeleteConvention>();
        modelBuilder.Conventions.Remove<OneToManyCascadeDeleteConvention>();
    }
}  

Пример кода

Ответ 6

Это все, что я сделал на самом деле:

    var lockoutEndDate = new DateTime(2999,01,01);
    UserManager.SetLockoutEnabled(userId,true);
    UserManager.SetLockoutEndDate(userId, lockoutEndDate);

В основном это означает блокировку (если вы не сделаете это по умолчанию уже, а затем установите дату окончания блокировки в какое-то отдаленное значение.

Ответ 7

Озз прав, но может быть целесообразно взглянуть на базовый класс и посмотреть, сможете ли вы найти метод, который проверяется на все углы входа - я думаю, что это может быть CanSignIn?

Теперь, когда MS с открытым исходным кодом, вы можете увидеть их реализацию:

https://github.com/aspnet/AspNetCore/blob/master/src/Identity/src/Identity/SignInManager.cs

(URL был изменен на:

https://github.com/aspnet/AspNetCore/blob/master/src/Identity/Core/src/SignInManager.cs)

    public class CustomSignInManager : SignInManager<ApplicationUser>  
{
    public CustomSignInManager(UserManager<ApplicationUser> userManager,
        IHttpContextAccessor contextAccessor,
        IUserClaimsPrincipalFactory<ApplicationUser> claimsFactory,
        IOptions<IdentityOptions> optionsAccessor,
        ILogger<SignInManager<ApplicationUser>> logger,
        IAuthenticationSchemeProvider schemes) : base(userManager, contextAccessor, claimsFactory, optionsAccessor, logger, schemes)
    {

    }


    public override async Task<bool> CanSignInAsync(ApplicationUser user)
    {
        if (Options.SignIn.RequireConfirmedEmail && !(await UserManager.IsEmailConfirmedAsync(user)))
        {
            Logger.LogWarning(0, "User {userId} cannot sign in without a confirmed email.", await UserManager.GetUserIdAsync(user));
            return false;
        }
        if (Options.SignIn.RequireConfirmedPhoneNumber && !(await UserManager.IsPhoneNumberConfirmedAsync(user)))
        {
            Logger.LogWarning(1, "User {userId} cannot sign in without a confirmed phone number.", await UserManager.GetUserIdAsync(user));
            return false;
        }

        if (UserManager.FindByIdAsync(user.Id).Result.IsEnabled == false)
        {
            Logger.LogWarning(1, "User {userId} cannot sign because it currently disabled", await UserManager.GetUserIdAsync(user));
            return false;
        }

        return true;
    }
}

Также рассмотрите возможность переопределения PreSignInCheck, который также вызывает CanSignIn:

protected virtual async Task<SignInResult> PreSignInCheck(TUser user)
        {
            if (!await CanSignInAsync(user))
            {
                return SignInResult.NotAllowed;
            }
            if (await IsLockedOut(user))
            {
                return await LockedOut(user);
            }
            return null;
        }

Ответ 8

Чтобы удалить идентификатор, вам необходимо реализовать свой собственный UserStore.

Также этот может вам помочь.