public SessionsController( IIdentityServerInteractionService interaction, IClientStore clientStore, IAuthenticationSchemeProvider schemeProvider, IEventService events, TestUserStore users, ICredentialStore credentialStore, ISessionStore sessionStore, ILoginAttemptStore loginAttemptStore, IRequestInfoService requestInfoService, ILoginAttemptLimitingService loginAttemptLimitingService, ICredentialPenaltyStore credentialPenaltyStore) { // if the TestUserStore is not in DI, then we'll just use the global users collection // this is where you would plug in your own custom identity management library (e.g. ASP.NET Identity) _users = users; _interaction = interaction; _clientStore = clientStore; _schemeProvider = schemeProvider; _events = events; this.CredentialStore = credentialStore; this.SessionStore = sessionStore; this.LoginAttemptStore = loginAttemptStore; this.RequestInfoService = requestInfoService; this.LoginAttemptLimitingService = loginAttemptLimitingService; this.CredentialPenaltyStore = credentialPenaltyStore; }
public async Task <LoginAttemptRateLimiterResult> Check(string fromIp, ILoginAttemptStore attemptStore) { LoginAttempt latestAttempt = await attemptStore.GetLatest(fromIp); if (latestAttempt == null) { return new LoginAttemptRateLimiterResult { IsApproved = true } } ; TimeSpan timeSinceLatestAttempt = DateTime.UtcNow - latestAttempt.AttemptDate; // Cinco minutos es el tiempo de castigo, asique si el ultimo intento fue hace más de 5 minutos no es necesario // verificar nada más, en ese caso sería válido el intento if (timeSinceLatestAttempt < TimeSpan.FromMinutes(5)) { // Pasó menos tiempo que el de castigo asique es posible que EXISTA un castigo a aplicar actualmente. // La regla es "Si se hacen 5 o más intentos fallidos en 5minutos, entonces no se puede volver a intentar sino hasta dentro de otros 5mins". // Entonces: Toma el último intento hecho y le resta 5 minutos, y una vez definida esa ventana temporal, busca todos los intentos que se hayan // hecho en ese tiempo. Si la cuenta da 5 o más, significa que en esos 5 minutos se violó la regla, y ahora mismo el usuario está en penitencia // hasta que se cumplan 5 minutos después del último intento. DateTime fromDt = latestAttempt.AttemptDate.AddMinutes(-5); DateTime toDt = latestAttempt.AttemptDate; int countInLast5minuteWindow = await attemptStore.Count(fromIp, fromDt, toDt); if (countInLast5minuteWindow < 5) { return(new LoginAttemptRateLimiterResult { IsApproved = true }); } else { TimeSpan timeToWait = latestAttempt.AttemptDate.AddMinutes(5) - DateTime.UtcNow; var result = new LoginAttemptRateLimiterResult { IsApproved = false, TimeToWait = timeToWait, ErrorMessage = string.Format("Too many failed login attempts. Please wait {0} seconds before trying again.", timeToWait.TotalSeconds) }; return(result); } } else { return(new LoginAttemptRateLimiterResult { IsApproved = true }); } } }
public SessionService( ICredentialStore credentialStore, ILoginAttemptStore loginAttemptStore, ICredentialPenaltyStore credentialPenaltyStore, ISessionStore sessionStore) { this.CredentialStore = credentialStore; this.LoginAttemptStore = loginAttemptStore; this.CredentialPenaltyStore = credentialPenaltyStore; this.SessionStore = sessionStore; }