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