Пример #1
0
        public async Task BruteforceBlockIsWorking()
        {
            using (var transaction = Fixture.Connection.BeginTransaction())
            {
                using (var context = Fixture.CreateContext(transaction))
                {
                    Mock <UserManager> userManagerMock = new Mock <UserManager>((new Mock <IUserStore <AppUser> >()).Object, null, null, null, null, null, null, null, null, null);
                    AppUser            returnedUser    = await context.Users.SingleAsync(u => u.Email == "*****@*****.**");

                    userManagerMock.Setup(u => u.FindByNameAsync("JohnDoe"))
                    .ReturnsAsync(returnedUser);
                    BruteforceManager manager = new BruteforceManager(context, (UserManager)userManagerMock.Object);

                    IPAddress ip      = IPAddress.Parse("192.168.5.34");
                    IPAddress otherIp = IPAddress.Parse("192.168.5.35");

                    await manager.MarkInvalidLoginAttemptAsync(ip, "User Agent", "JohnDoe");

                    Assert.False(await manager.IsIpBlockedAsync(ip));
                    Assert.False(await manager.IsUserBlockedAsync(returnedUser));

                    for (int i = 1; i < 10; i++)
                    {
                        await manager.MarkInvalidLoginAttemptAsync(ip, "User Agent", "JohnDoe");
                    }

                    Assert.True(await manager.IsIpBlockedAsync(ip));
                    Assert.False(await manager.IsIpBlockedAsync(otherIp));
                    Assert.True(await manager.IsUserBlockedAsync(returnedUser));
                }
            }
        }
Пример #2
0
        public override async Task <LoginReply> Login(LoginRequest request, ServerCallContext context)
        {
            AppUser?user = await _userManager.FindByNameAsync(request.UserId);

            HttpContext httpContext = context.GetHttpContext();

            IPAddress?ip = httpContext.Connection.RemoteIpAddress;

            if (ip == null)
            {
                return(new LoginReply
                {
                    State = LoginStateEnum.Failed
                });
            }

            StringValues userAgent;

            httpContext.Request.Headers.TryGetValue("User-Agent", out userAgent);

            if (userAgent.Count != 1)
            {
                return(new LoginReply
                {
                    State = LoginStateEnum.Failed
                });
            }

            bool isUserBlocked         = false;
            bool isUserOnTrustedDevice = false;

            if (user != null)
            {
                isUserBlocked = await _bruteforceManager.IsUserBlockedAsync(user);

                string?encryptedDeviceId;
                context.GetHttpContext().Request.Cookies.TryGetValue(DeviceCookieManager.DEVICE_COOKIE_STRING, out encryptedDeviceId);

                if (encryptedDeviceId != null)
                {
                    isUserOnTrustedDevice = await _deviceCookieManager.IsCookieTrustedForUser(
                        new EncryptedDeviceCookie(encryptedDeviceId),
                        user
                        );
                }
            }
            bool isIpBlocked = await _bruteforceManager.IsIpBlockedAsync(ip);

            if (
                !isUserOnTrustedDevice
                &&
                (isUserBlocked || isIpBlocked)
                )
            {
                return(new LoginReply
                {
                    State = LoginStateEnum.Blocked,
                });
            }

            if (user == null)
            {
                await _bruteforceManager.MarkInvalidLoginAttemptAsync(
                    ip,
                    userAgent[0],
                    request.UserId
                    );

                return(new LoginReply
                {
                    State = LoginStateEnum.Failed
                });
            }
            else
            {
                if (user.IsDisabled)
                {
                    return(new LoginReply
                    {
                        State = LoginStateEnum.Disabled
                    });
                }
            }

            Microsoft.AspNetCore.Identity.SignInResult result =
                await _signInManager.PasswordSignInAsync(user, request.Password, false, false);

            if (result.Succeeded)
            {
                return(new LoginReply
                {
                    State = LoginStateEnum.Success
                });
            }
            else if (result.RequiresTwoFactor)
            {
                return(new LoginReply
                {
                    State = LoginStateEnum.TwoFactorRequired
                });
            }

            await _bruteforceManager.MarkInvalidLoginAttemptAsync(
                ip,
                userAgent[0],
                request.UserId
                );

            return(new LoginReply
            {
                State = LoginStateEnum.Failed
            });
        }