Нужно ли переопределять OnValidatingPassword поставщика членства по умолчанию в пользовательских реализациях?

Я работаю над реализацией пользовательского поставщика членства для моего приложения.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 ответ

Решение

Документация для 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,

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

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

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

Другие вопросы по тегам