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

pc1*_*ter 7 .net asp.net-membership membership-provider custom-membershipprovider

我正在为我的.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;
            }
Run Code Online (Sandbox Code Playgroud)

Jef*_*ata 6

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

查看Reflector中的方法证实了这一点:

protected virtual void OnValidatingPassword(ValidatePasswordEventArgs e)
{
    if (this._EventHandler != null)
    {
        this._EventHandler(this, e);
    }
}
Run Code Online (Sandbox Code Playgroud)

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

如果您查看SQL成员资格提供程序的源代码(下载Provider Toolkit示例),您将看到它包含验证密码的逻辑,以及调用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;
}
Run Code Online (Sandbox Code Playgroud)

编辑

我认为部分混淆是基于名称OnValidatingPassword,并且它似乎暗示它正在处理密码验证,而不是引发事件让其他代码验证密码.对于它的价值,我理解了这种混淆 - 如果该方法已被命名,它可能会更清楚RaiseValidatingPasswordEvent.

在任何情况下,您都可以查看.NET 4 的事件设计指南.大约在页面的中间位置,您会发现:

使用受保护的虚拟方法来引发每个事件.

受保护的虚拟方法的名称应与前缀为On的事件名称相同.例如,名为"TimeChanged"的事件的受保护虚拟方法名为"OnTimeChanged".