Нужно ли переопределять OnValidatingPassword поставщика членства по умолчанию в пользовательских реализациях? - PullRequest
7 голосов
/ 05 октября 2011

Я работаю над реализацией пользовательского поставщика членства для моего приложения .net.Я настроил конфигурацию для минимального количества символов и не алфавитно-цифровых символов, но, похоже, все равно пропускает пароли, даже если они нарушают правила.

OnValidatingPassword - это виртуальный метод.Пример от Microsoft не переопределяет метод.

Этот вопрос сталкивается с той же проблемой, но автор отказался от получения ответа на свой вопрос и просто перебил функцию.Этот ответ гласит , что для работы не требуется переопределять функцию.

Разве базовая функция ничего не делает?Когда я переопределяю OnValidatePassword и просто вызываю базовый класс, моя функция срабатывает, но она никогда не отклоняет мои слишком простые пароли.

Пример кода (с пользовательской функцией CreateUser)

protected override void OnValidatingPassword(ValidatePasswordEventArgs e)
        {                        
             base.OnValidatingPassword(e);
        }
        //
        // MembershipProvider.CreateUser
        //
        public MembershipUser CreateUser(string username, string password, string globalIdentifier, string firstName, string lastName, 
            string birthDate, object providerUserKey, out MembershipCreateStatus status)
        {
            ValidatePasswordEventArgs args = new ValidatePasswordEventArgs(username, password, true);
            OnValidatingPassword(args);

            if (args.Cancel)
            {
                status = MembershipCreateStatus.InvalidPassword;
                return null;
            }

1 Ответ

6 голосов
/ 05 октября 2011

В документации для MembershipProvider.OnValidatingPassword говорится только о том, что оно вызывает событие ValidatingPassword, если обработчик зарегистрирован, но не о том, что оно фактически проверяет пароль.

Просмотр метода в Reflector подтверждает это:

protected virtual void OnValidatingPassword(ValidatePasswordEventArgs e)
{
    if (this._EventHandler != null)
    {
        this._EventHandler(this, e);
    }
}

Это сбивает с толку, но я полагаю, что намерение состоит в том, что это обеспечивает ловушку для внешней логики для участия в проверке пароля; Пользовательскому провайдеру все еще нужно написать собственную логику проверки.

Если вы посмотрите на исходный код провайдера членства SQL (скачайте Примеры инструментария провайдера ), вы увидите, что он включает логику для проверки пароля, а также вызывает OnValidatingPassword , Следующий код взят из метода CreateUser:

if( password.Length < MinRequiredPasswordLength )
{
    status = MembershipCreateStatus.InvalidPassword;
    return null;
}

int count = 0;

for( int i = 0; i < password.Length; i++ )
{
    if( !char.IsLetterOrDigit( password, i ) )
    {
        count++;
    }
}

if( count < MinRequiredNonAlphanumericCharacters )
{
    status = MembershipCreateStatus.InvalidPassword;
    return null;
}

if( PasswordStrengthRegularExpression.Length > 0 )
{
    if( !Regex.IsMatch( password, PasswordStrengthRegularExpression ) )
    {
        status = MembershipCreateStatus.InvalidPassword;
        return null;
    }
}

ValidatePasswordEventArgs e = new ValidatePasswordEventArgs( username, password, true );
OnValidatingPassword( e );

if( e.Cancel )
{
    status = MembershipCreateStatus.InvalidPassword;
    return null;
}

Редактировать

Я думаю, что часть путаницы основана на имени OnValidatingPassword, и это, по-видимому, подразумевает, что он обрабатывает проверку пароля, а не вызывает событие, позволяющее другому коду проверять пароль. Для чего это стоит, я понимаю путаницу - было бы, наверное, понятнее, если бы метод был назван RaiseValidatingPasswordEvent.

В любом случае вы можете проверить рекомендации Event Design для .NET 4. Примерно на полпути вниз по странице вы найдете следующее:

Используйте защищенный виртуальный метод для вызова каждого события.

Имя защищенного виртуального метода должно быть совпадает с именем события с префиксом On. Например, защищенный виртуальный метод для события с именем «TimeChanged» называется "OnTimeChanged".

...