简体   繁体   English

在 Y 次无效尝试和 userManager.IsLockedOutAsync 为 false 后锁定 ASP.NET 登录用户 X 分钟

[英]Lock ASP.NET login user for X minutes after Y invalid attempts and userManager.IsLockedOutAsync is false

I am working on asp.net web api project and trying to implement the functionality that would lock the user login for X minutes after Y invalid attempts.我正在研究 asp.net web api 项目并尝试实现在 Y 次无效尝试后将用户登录锁定 X 分钟的功能。

I have set this in Identity Config我在身份配置中设置了这个

        // Enable Lock outs
        manager.MaxFailedAccessAttemptsBeforeLockout = 1;
        manager.DefaultAccountLockoutTimeSpan = new TimeSpan(0, 5, 0);
        manager.UserLockoutEnabledByDefault = true;

In IdentityConfig.csIdentityConfig.cs

public static ApplicationUserManager Create(IdentityFactoryOptions<ApplicationUserManager> options, IOwinContext context)
    {
        var manager = new ApplicationUserManager(new UserStore<ApplicationUser>(context.Get<ApplicationDbContext>()));
        // Configure validation logic for usernames
        manager.UserValidator = new UserValidator<ApplicationUser>(manager)
        {
            AllowOnlyAlphanumericUserNames = false,
            RequireUniqueEmail = true,
             
        };
        // Enable Lock outs

        manager.MaxFailedAccessAttemptsBeforeLockout = 1;
        manager.DefaultAccountLockoutTimeSpan = new TimeSpan(0, 5, 0);
        manager.UserLockoutEnabledByDefault = true;
        // Configure validation logic for passwords
        manager.PasswordValidator = new PasswordValidator
        {
            RequiredLength = 6,
            RequireNonLetterOrDigit = true,
            RequireDigit = true,
            RequireLowercase = true,
            RequireUppercase = true,
        };

        manager.EmailService = new EmailServiceCustom();
        int Token = 24;
        if (ConfigurationManager.AppSettings["TokenLifespan"] != null
         )
        {
            Token = Convert.ToInt32(ConfigurationManager.AppSettings["TokenLifespan"]);
        }

        var dataProtectionProvider = options.DataProtectionProvider;
        if (dataProtectionProvider != null)
        {
            manager.UserTokenProvider = new DataProtectorTokenProvider<ApplicationUser>(dataProtectionProvider.Create("ASP.NET Identity"))
            {
                TokenLifespan = System.TimeSpan.FromHours(Token)
            };
        }
        return manager;
    }

and in OAuthProvider.cs Class并在OAuthProvider.cs Class

   public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)
        {
            //context.OwinContext.Response.Headers.Add("Access-Control-Allow-Origin", new[] { "*" });
            var userManager = context.OwinContext.GetUserManager<ApplicationUserManager>();


            var user = await userManager.FindByNameAsync(context.UserName).ConfigureAwait(false);

            //var user= await context.OwinContext.GetUserManager<ApplicationUserManager>()
            //    .FindAsync(context.UserName, context.Password).ConfigureAwait(false);
            if (user == null)
            {
                context.SetError("invalid_grant", "The user name is incorrect.");
                return;
            }
            
            if (await userManager.IsLockedOutAsync(user.Id))
            {
                context.SetError("locked_out", "User is locked out");
                return;
            }

            if (!await userManager.IsEmailConfirmedAsync(user.Id))
            {
                context.SetError("invalid_grant", "You need to confirm your email.");
                return;
            }

            var check = await userManager.CheckPasswordAsync(user, context.Password);

            if (!check)
            {
                await userManager.AccessFailedAsync(user.Id);
                context.SetError("invalid_grant", "The password is incorrect."); //wrong password
                return;
            }
            ClaimsIdentity oAuthIdentity = await (await userManager.FindAsync(context.UserName, context.Password).ConfigureAwait(false)).GenerateUserIdentityAsync(userManager, "JWT").ConfigureAwait(false);
            
            var userForCheck = this.userService.GetUserById((await userManager.FindAsync(context.UserName, context.Password).ConfigureAwait(false)).Id);
            AuthenticationTicket ticket;

            if ((oAuthIdentity.IsAuthenticated && userForCheck == null) ||
                oAuthIdentity.IsAuthenticated && userForCheck.status)
            {
                var claims = new List<Claim>();

                var roles = await userManager.GetRolesAsync((await userManager.FindAsync(context.UserName, context.Password).ConfigureAwait(false)).Id).ConfigureAwait(false);
                claims.AddRange(roles.Select(role => new Claim("role", role)));

                claims.Add(new Claim("unique_name", (await userManager.FindAsync(context.UserName, context.Password).ConfigureAwait(false)).UserName));
                claims.Add(new Claim("email", (await userManager.FindAsync(context.UserName, context.Password).ConfigureAwait(false)).Email));

                oAuthIdentity.AddClaims(claims);
                ticket = new AuthenticationTicket(oAuthIdentity, null);
                context.Validated(ticket);
            }
        }

but user.LockoutEnabled is false and userManager.IsLockedOutAsync(user.Id) is also returning false even after invalid attempt.但是user.LockoutEnabled是 false 并且userManager.IsLockedOutAsync(user.Id)即使在无效尝试之后也返回 false 。 What am i am doing wrong here?我在这里做错了什么?

I took help of this one but still same issue我得到了这个帮助,但仍然是同样的问题

In case anyone stumbles upon this issue:如果有人偶然发现这个问题:

If you've created a user before implementing the lockout functionality UserLockoutEnabledByDefault will be ignored.如果您在实施锁定功能之前创建了用户,则UserLockoutEnabledByDefault将被忽略。 This is because default only apply when the value ( UserLockOut ) is null.这是因为默认值仅在值 ( UserLockOut ) 为 null 时适用。 However this property is set to false.但是,此属性设置为 false。

Therefore you'll need to do a one time change to set lockout to true (for existing users only).因此,您需要进行一次性更改以将锁定设置为 true(仅适用于现有用户)。 eg await userManager.SetLockoutEnabledAsync(user.Id, true);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 在五次失败的登录尝试后锁定用户,并在MVC3 Asp.net中显示错误 - Lock user after five failed login attempts and show an error in MVC3 Asp.net 在使用asp.net登录5次失败后,如何锁定用户帐户30分钟? - How User account be locked for 30 min after 5 unsuccessful login attempts with asp.net? 在ASP.NET中尝试3次无效密码后如何阻止用户名 - How To Block The UserName After 3 Invalid Password Attempts IN ASP.NET 尝试三次不成功后注销用户 - ASP.NET - Logout user after three unsuccesfull attempts - ASP.NET 在 asp.net 核心成功登录后,User.Identity.IsAuthenticated 在非身份验证方法中为 false - User.Identity.IsAuthenticated is false in a non-auth methods after successful login in asp.net core 在Asp.Net核心标识中创建没有UserManager的用户 - Create user without UserManager in Asp.Net Core Identity 3次登录尝试后出现401未经授权的访问错误,如何重新加载页面? 在asp.net - How to reload page after 3 login attempts with 401 unauthorised access error? in asp.net 通过 ASP.NET Identity 2 中的 UserManager.Update() 更新用户 - Updating user by UserManager.Update() in ASP.NET Identity 2 登录后的ASP.NET身份用户为null - ASP.NET Identity user null after login 用户登录后,Asp.net登录状态未显示注销 - Asp.net Login status not saying logout after user logs in
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM