Ejemplo n.º 1
0
        public async Task ValidateLogonAsync(long tenantId, LogonModel model)
        {
            // Do initial model checks (valid email, password required etc)
            _modelValidator.Validate(model);

            // Get user given email address
            string email = model.Email.Trim();
            AuthenticationState state = await _authenticationRepository.ReadAuthenticationStateAsync(tenantId, email);

            // The first condition that causes an invalid user is when user not found due to an invalid email address entered. In this case, state is null.
            if (state == null)
            {
                throw new ValidationErrorException(new ValidationError(null, AuthenticationResource.LogonUserCredentialsInvalidMessage));
            }

            // If user has not been confirmed, they must first set their password before they can be validated
            if (!state.Confirmed)
            {
                throw new ValidationErrorException(new ValidationError(null, AuthenticationResource.LogonUserUnconfirmedMessage));
            }

            // User may have been disabled by an administrator, in which case it will not be possible to validate account
            if (!state.Enabled)
            {
                throw new ValidationErrorException(new ValidationError(null, AuthenticationResource.LogonUserDisabledMessage));
            }

            // If account locked out, check to see when last password failure occured. If lockout duration period expired, undo the lockout.
            if (state.LockedOut)
            {
                TimeSpan lockOutDuration = _authenticationConfigurationService.GetLockOutDuration(tenantId);
                if ((DateTime.UtcNow - (DateTime)state.LastPasswordFailure) > lockOutDuration)
                {
                    await UnlockAsync(tenantId, email, state);
                }
                else
                {
                    throw new UserLockedOutException(new ValidationError(null, AuthenticationResource.LogonUserLockedOutMessage));
                }
            }

            // Finally, check password entered is correct and if not register a password failure which may lock user out
            byte[] userPasswordSalt        = _encryptionService.GetBytes(state.PasswordSalt);
            byte[] userPasswordSaltedHash  = _encryptionService.GetBytes(state.PasswordSaltedHash);
            byte[] logonPasswordSaltedHash = _encryptionService.EncryptPassword(model.Password, userPasswordSalt);
            if (!_encryptionService.ByteArraysEqual(logonPasswordSaltedHash, userPasswordSaltedHash))
            {
                await RegisterPasswordFailureAsync(tenantId, email, state);

                if (state.LockedOut)
                {
                    throw new ValidationErrorException(new ValidationError(null, AuthenticationResource.LogonUserLockedOutMessage));
                }
                else
                {
                    throw new ValidationErrorException(new ValidationError(null, AuthenticationResource.LogonUserCredentialsInvalidMessage));
                }
            }
        }