If the password validator does not have the validation rules that you need for your project then it is easily extendable. You can create your own ValidationHander
derived classes and set add them via the PasswordValdiationSettings
class.
ValidationHandler
The ValidationHandler
class is an abstract base class which is extended in the Xander.PasswordValidator framework itself to provide the various built in validation routines. (You can see examples of some of them here on GitHub)
You can create your own by simply creating a class and setting Xander.PasswordValidator.ValidationHandler
as the base class and overriding the Validate()
method.
The Validate
method simply accepts the password as the parameter and returns a Boolean. Return true to indicate that the password passes the validation, false if it fails the validation.
For example, here is a very simple validator that rejects passwords that look like dates:
using System; using Xander.PasswordValidator; namespace Demo.ValidationHandlers { public class NoDatesValidationHandler : ValidationHandler { public override bool Validate(string password) { DateTime date; var parseResult = DateTime.TryParse(password, out date); return !parseResult; } } }
To set this up so that the validator calls it, it needs to be added as part of the settings. You pass in the type of the handler. The Validation framework will create an instance of the handler for you, if it needs it. If validation fails before it gets a chance to run your validator then your validator will not run.
var settings = new PasswordValidationSettings(); settings.CustomValidators.Add(typeof(NoDatesValidationHandler));
CustomValidationHandler<TData>
This derives from ValidationHandler
and is used when you need to pass some additional data or objects into your validation handler for it to work properly.
The Validate method works as before, except you now have access to an additional property from the base class that contains your custom data, called CustomData
. CustomData
is the object passed in through the settings.
To pass in the data through the settings you use the CustomSettings
property on the PasswordValidationSettings
class. For example:
settings = new PasswordValidationSettings(); settings.MinimumPasswordLength = 6; settings.CustomValidators.Add(typeof(PasswordHistoryValidationHandler)); settings.CustomSettings.Add(typeof(PasswordHistoryValidationHandler), new Repository());
The key passed into CustomSettings
is a type that refers to the ValidationHandler
type that the settings are to be sent to.
The ValidationHandler
looks something like this:
using System.Linq; using System.Web; using Xander.PasswordValidator; namespace Demo.ValidationHandlers { public class PasswordHistoryValidationHandler : CustomValidationHandler { public override bool Validate(string password) { var user = HttpContext.Current.User; var history = CustomData.GetPasswordHistory(user.Identity.Name); return !history.Any(h => string.Compare(password, h, true) == 0); } } }
In the above example, the settings pass in a repository which is passed on to the ValidationHandler
when the Validator
is run. The repository is used to get a history of passwords (It is a dummy repository in this example – In real life you should never have access to the plain text passwords like this) and the history can be checked against the current password to ensure that it does not match any of the historical passwords.
There is a slightly updated set of assemblies for this as I made some changes to way the CustomValidationHandler
works: PasswordValidator.0.2.0.0.zip