Does the default Membership Provider's OnValidatingPassword have to be overridden in custom implementations?
I am working to implement a custom Membership Provider for my .net application. I have set up the configuration for a minimum number of characters and non-alphanumeric characters, but it seems to let passwords through anyway, even when they break the rules.
OnValidatingPassword is a virtual method. The example from Microsoft does not override the method.
This question grapples with the same problem, but the author gave up on getting the answer to his question and simply overrode the function. This answer states that one does not have to override the function to have it work.
Does the base function not do anything? When I override OnValidatePassword, and simply call the base class, my function gets hit, but it never rejects my too-simple passwords.
Code sample (with a custom CreateUser function)
protected override void OnValidating开发者_JS百科Password(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;
}
The documentation for MembershipProvider.OnValidatingPassword only states that that it raises the ValidatingPassword
event if a handler is registered, not that it actually validates the password.
Looking at the method in Reflector confirms this:
protected virtual void OnValidatingPassword(ValidatePasswordEventArgs e)
{
if (this._EventHandler != null)
{
this._EventHandler(this, e);
}
}
It is confusing, but I believe the intent is that this provides a hook for external logic to participate in password validation; A custom provider would still need to write its own validation logic.
If you take a look at the source code for the SQL Membership Provider (download the Provider Toolkit Samples), you'll see that it includes logic to validate the password, and also calls OnValidatingPassword
. The following code is from the CreateUser
method:
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;
}
Edit
I think part of the confusion is based on the name of OnValidatingPassword
, and that it seems to imply that it is handling password validation, rather than raising an event to let other code validate the password. For what it's worth, I understand the confusion - it would probably be clearer if the method had been named RaiseValidatingPasswordEvent
.
In any case, you can check the Event Design guidelines for .NET 4. About halfway down the page, you'll find this:
Do use a protected virtual method to raise each event.
The name of the protected virtual method should be the same as the event name prefixed with On. For example, the protected virtual method for an event named "TimeChanged" is named "OnTimeChanged".
精彩评论