Заблокировать ASP. NET пользователя входа в систему на X минут после Y недопустимых попыток и userManager.IsLockedOutAsyn c ложно - PullRequest
0 голосов
/ 11 июля 2020

Я работаю над проектом asp. net web api и пытаюсь реализовать функциональность, которая блокирует вход пользователя в систему на X минут после Y недопустимых попыток.

Я установил это в Identity Config

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

In IdentityConfig.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;
    }

и в 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);
            }
        }

но user.LockoutEnabled false, а userManager.IsLockedOutAsync(user.Id) также возвращает false даже после недействительной попытки. Что я здесь делаю не так?

Я воспользовался помощью этого , но все та же проблема

1 Ответ

1 голос
/ 13 июля 2020

На случай, если кто-нибудь наткнется на эту проблему:

Если вы создали пользователя до реализации функции блокировки, UserLockoutEnabledByDefault будет проигнорирован. Это потому, что значение по умолчанию применяется только тогда, когда значение ( UserLockOut ) равно нулю. Однако для этого свойства установлено значение false.

Поэтому вам нужно будет сделать одноразовое изменение, чтобы установить для блокировки значение true (только для существующих пользователей). e.g await userManager.SetLockoutEnabledAsync(user.Id, true);

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...