Example #1
0
        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
                });
            }
        }
    }
Example #3
0
 public SessionService(
     ICredentialStore credentialStore,
     ILoginAttemptStore loginAttemptStore,
     ICredentialPenaltyStore credentialPenaltyStore,
     ISessionStore sessionStore)
 {
     this.CredentialStore        = credentialStore;
     this.LoginAttemptStore      = loginAttemptStore;
     this.CredentialPenaltyStore = credentialPenaltyStore;
     this.SessionStore           = sessionStore;
 }