コード例 #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));
                }
            }
        }
コード例 #2
0
        /// <summary>
        /// Performs main validation of supplied user credentials. If user credentials not valid, a validation error exception will be thrown by this method.
        /// </summary>
        /// <param name="model">User credentials to validate.</param>
        /// <param name="keyPrefix">Validation key prefix.</param>
        public void ValidateLogon(LogonModel model, string keyPrefix = null)
        {
            // Do initial model checks (valid email, password required etc)
            _modelValidator.Validate(model, keyPrefix);

            // Get user given email address
            User user = _userRepository.ReadUserByEmail(model.TenantId, model.Email.Trim().ToLower());

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

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

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

            // If account locked out, check to see when last password failure occured. If lockout duration period expired, we can undo the lockout.
            if (user.LockedOut)
            {
                TimeSpan lockOutDuration = _authenticationConfigurationService.GetLockOutDuration(model.TenantId);
                if ((DateTime.UtcNow - (DateTime)user.LastPasswordFailure) > lockOutDuration)
                {
                    // Clear password failures associated with a user and sets user's locked out flag to false
                    user.LockedOut           = false;
                    user.LastPasswordFailure = null;
                    user.PasswordFailures    = 0;

                    // Do the update
                    _userRepository.UpdateUser(user);
                }
                else
                {
                    throw new UserLockedOutException(new ValidationError(null, AuthenticationResource.LogonUserLockedOutMessage, keyPrefix));
                }
            }

            // Finally, check password entered is correct and if not register a password failure which may lock user out
            byte[] userPasswordSalt        = _stringService.GetBytes(user.PasswordSalt);
            byte[] userPasswordSaltedHash  = _stringService.GetBytes(user.PasswordSaltedHash);
            byte[] logonPasswordSaltedHash = _securityService.EncryptPassword(model.Password, userPasswordSalt);
            if (!_stringService.ByteArraysEqual(logonPasswordSaltedHash, userPasswordSaltedHash))
            {
                RegisterPasswordFailure(user);
                if (user.LockedOut)
                {
                    throw new ValidationErrorException(new ValidationError(null, AuthenticationResource.LogonUserLockedOutMessage, keyPrefix));
                }
                else
                {
                    throw new ValidationErrorException(new ValidationError(null, AuthenticationResource.LogonUserCredentialsInvalidMessage, keyPrefix));
                }
            }
        }