是否必须在自定义实现中覆盖默认的成员资格提供程序的OnValidatingPassword?

时间:2011-10-04 21:05:41

标签: .net asp.net-membership membership-provider custom-membershipprovider

我正在为我的.net应用程序实现自定义成员资格提供程序。我已经设置了最少数量的字符和非字母数字字符的配置,但它似乎无论如何都要通过密码,即使它们违反了规则。

OnValidatingPassword是一种虚拟方法。 example from Microsoft不会覆盖该方法。

question还有同样的问题,但是作者放弃了对他的问题的回答并简单地覆盖了这个功能。这个answer states没有必要覆盖函数才能使它工作。

基本功能没有做任何事情吗?当我重写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 个答案:

答案 0 :(得分:6)

MembershipProvider.OnValidatingPassword的文档仅声明如果注册了处理程序它会引发ValidatingPassword事件,而不是它实际验证密码。

查看Reflector中的方法确认了这一点:

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

令人困惑,但我认为这意味着这为外部逻辑提供了参与密码验证的钩子;自定义提供程序仍需要编写自己的验证逻辑。

如果您查看SQL成员资格提供程序的源代码(下载Provider Toolkit Samples),您将看到它包含验证密码的逻辑,并且还调用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的Event Design指南4.大约在页面的中间位置,您会发现:

  

请使用受保护的虚拟方法来举起每个活动。

     

受保护的虚拟方法的名称应该是   与前缀为On的事件名称相同。例如,受保护   名为“TimeChanged”的事件的虚方法已命名   “OnTimeChanged”。