在ASPNET标识2.0中禁用用户

anI*_*Mer 34 asp.net asp.net-identity

我正在寻找一种方法来禁用用户而不是从系统中删除它们,这是为了保持相关数据的数据完整性.但似乎ASPNET身份只提供删除帐户.

有一个新的锁定功能,但似乎可以控制锁定以禁用用户,但只有在尝试了一定数量的错误密码后才能锁定用户.

还有其他选择吗?

ozz*_*ozz 63

当您创建一个安装了标识位的站点时,您的站点将有一个名为"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
Run Code Online (Sandbox Code Playgroud)

这里的评论中有一个很好的链接,为了方便点击这里

本教程将准确告诉您为用户添加自定义属性需要执行的操作.

实际上,甚至不用费心去看教程.

1)向ApplicationUser类添加属性,例如:

public bool? IsEnabled { get; set; }
Run Code Online (Sandbox Code Playgroud)

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)
Run Code Online (Sandbox Code Playgroud)

我在创建ApplicationUser对象时添加了IsEnabled = true.该值现在将保留在AspNetUsers表的新列中.

然后,您需要通过覆盖ApplicationSignInManager中的PasswordSignInAsync来处理检查此值作为登录过程的一部分.

我做了如下:

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);
    }
Run Code Online (Sandbox Code Playgroud)

您的里程可能会有所不同,您可能不想退回SignInStatus,但您明白了.

  • 您是否需要检查用户是否存在以防止 user.IsEnabled 上出现 NRE?我有以下内容: `if (user!= null &amp;&amp; !user.IsEnabled) { return Task.FromResult&lt;SignInStatus&gt;(SignInStatus.LockedOut); }`。我不检查 HasValue 的原因是因为我将 IsEnabled 设置为必填字段 (3认同)
  • 是否建议重写 CanSignIn 方法?覆盖 passwordsignin 方法不检查其他登录方法?您可以在此处查看整个登录管理器 https://github.com/aspnet/AspNetCore/blob/master/src/Identity/src/Identity/SignInManager.cs (2认同)

use*_*261 20

a的默认LockoutEnabled属性User不是指示用户当前是否被锁定的属性.它是一个属性,指示一旦AccessFailedCount达到该MaxFailedAccessAttemptsBeforeLockout值,用户是否应该被锁定.即使用户被锁定,它也只是暂时阻止用户持续使用LockedoutEnddateUtc财产的一种措施.因此,要永久禁用或暂停用户帐户,您可能需要引入自己的标志属性.


小智 18

您无需创建自定义属性.诀窍是LockoutEnabled在Identity用户上设置 属性并将LockoutoutEndDateUtc代码设置为将来锁定用户的日期.然后,调用UserManager.IsLockedOutAsync(user.Id)将返回false.

无论是LockoutEnabledLockoutoutEndDateUtc必须符合真实和未来日期的准则来闭锁用户.如果,例如,LockoutoutEndDateUtC值2014-01-01 00:00:00.000LockoutEnabledtrue,调用UserManager.IsLockedOutAsync(user.Id)仍然会返回true.我可以看到为什么Microsoft以这种方式设计它,以便您可以设置用户被锁定的时间跨度.

但是,我认为应该是如果LockoutEnabled是,true那么如果LockoutoutEndDateUtc是NULL或未来日期,则应该锁定用户.你不必在你的代码担心设置两个属性的方式(LockoutoutEndDateUtcNULL默认情况下).你可以只设置LockoutEnabledtrue,如果LockoutoutEndDateUtcNULL用户被无限期锁定.

  • 它已被大量推崇,但这个答案是错误的,因为正如其他人所说,你误解了LockoutEnabled属性.它指示用户是否"可以锁定".应该是一个内置的属性,简称为"LockedOut"或类似.更多信息:http://www.jamessturtevant.com/posts/ASPNET-Identity-Lockout/ (19认同)

Bro*_*len 9

您需要将自己的标志引入自定义IdentityUser派生类,并实现/实施您自己的关于启用/禁用的逻辑,并防止用户在禁用时登录.


t_p*_*lus 6

这就是我所做的一切:

    var lockoutEndDate = new DateTime(2999,01,01);
    UserManager.SetLockoutEnabled(userId,true);
    UserManager.SetLockoutEndDate(userId, lockoutEndDate);
Run Code Online (Sandbox Code Playgroud)

这基本上是为了启用锁定(如果您默认情况下还没有这样做,然后将锁定结束日期设置为某个较远的值。


Den*_*sır 5

您可以使用这些类... ASP.NET Identity 的干净实现...这是我自己的代码。int 用于主键,如果您想要不同的主键类型,您可以更改它。

身份配置文件

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)
    {
    }
}
Run Code Online (Sandbox Code Playgroud)

身份模型.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>();
    }
}  
Run Code Online (Sandbox Code Playgroud)


Wat*_*son 5

Ozz 是正确的,但是建议查看基类并查看是否可以找到针对所有登录角度检查的方法 - 我认为它可能是 CanSignIn?

现在 MS 是开源的,您可以看到它们的实现:

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

(网址已更改为:

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's currently disabled", await UserManager.GetUserIdAsync(user));
            return false;
        }

        return true;
    }
}
Run Code Online (Sandbox Code Playgroud)

还要考虑覆盖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;
        }
Run Code Online (Sandbox Code Playgroud)