7

我正在为我的 .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;
            }
4

1 回答 1

6

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

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

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

这很令人困惑,但我相信这样做的目的是为外部逻辑提供一个参与密码验证的钩子;自定义提供者仍需要编写自己的验证逻辑。

如果您查看 SQL Membership Provider 的源代码(下载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 4 的事件设计指南。大约在页面的中间,您会发现:

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

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

于 2011-10-04T21:37:46.703 回答