【问题标题】:Does the default Membership Provider's OnValidatingPassword have to be overridden in custom implementations?默认会员提供者的 OnValidatingPassword 是否必须在自定义实现中被覆盖?
【发布时间】:2011-10-04 21:05:41
【问题描述】:

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

【问题讨论】:

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


    【解决方案1】:

    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 可能会更清楚。

    无论如何,您都可以查看Event Design .NET 4 指南。大约在页面的中间,您会发现:

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

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

    【讨论】:

    • 我可能没有说清楚,但是当我重写基本方法时,我的方法确实被调用了。所以这不是方法是否被调用的问题——它似乎什么都不做
    • 对 - 除了引发 ValidatingPassword 事件之外,它什么也不做。 OnValidatingPassword 本身不进行任何验证。
    • 感谢您的回复。 OnValidatingEvent 如何负责引发 ValidatingPassword 事件——它不是响应 ValidatingPassword 事件吗?
    • 创建虚拟方法来引发名为OnSomeEvent(EventArgs args) 的事件然后实际在那里引发事件是很常见的。请参阅此answer。所以OnValidatingEvent 没有响应事件 - 它正在引发它。
    • @pc1oad1etter,请查看我的编辑 - 我添加了有关 OnValidatingPassword 名称的更好信息来源。 HTH。
    猜你喜欢
    • 2011-12-26
    • 1970-01-01
    • 1970-01-01
    • 2023-03-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-02-09
    相关资源
    最近更新 更多