如何描述PasswordValidator规则

时间:2015-09-17 18:26:11

标签: .net security passwords asp.net-identity

Microsoft.AspNet.Identity.PasswordValidator可配置许多参数,这些参数定义了最小密码长度和复杂性规则。如果用户输入的密码不符合条件,则PasswordValidator将抛出描述违规的异常,但它没有提供其他方式来向用户描述规则(例如“密码必须为8-12个字符且必须包含。 ......“等等。

我搜索了StackOverflow和网络,一般认为必须有数百个我需要的例子,但它开始看起来我是唯一一个需要它的人,我知道不是案件。在我编写自己的实现之前,我只需要问......

我完全忽视了这个问题的公认“标准”答案吗?

2 个答案:

答案 0 :(得分:1)

听起来有点hackish但是将一个空字符串发送到PasswordValidator的ValidateAsync()方法将会起作用。具有默认配置的UserManager示例:

var rules = await UserManager.PasswordValidator.ValidateAsync("");

rules.Errors.First() : 
Passwords must be at least 6 characters. 
Passwords must have at least one non letter or digit character. 
Passwords must have at least one digit ('0'-'9'). 
Passwords must have at least one lowercase ('a'-'z'). 
Passwords must have at least one uppercase ('A'-'Z').

你甚至可以列出它们

var list = rules.Errors.First().Split('.'); 

答案 1 :(得分:0)

这是我想出的东西,因为我需要一些工作,并没有找到我正在寻找的罐装标准答案。为了方便起见,我将它实现为PasswordValidator类的扩展,尽管这并不是绝对必要的。

public static string ToDescription(this PasswordValidator validator)
{
    var options = new List<string>();
    if (validator.RequireUppercase) options.Add("upper-case letters");
    if (validator.RequireLowercase) options.Add("lower-case letters");
    if (validator.RequireDigit) options.Add("numbers");
    if (validator.RequireNonLetterOrDigit) options.Add("special characters");

    var result = "Passwords must be at least " 
        + validator.RequiredLength + " characters long"
        + (options.Any() ? ", and include " + options.OxfordJoin() : ".");

    return result;
}

我还添加了OxfordJoin扩展,将需求列表转换为格式良好的句子:

public static string OxfordJoin(this IEnumerable<string> source)
{
    var array = source.ToArray();
    var joined = string.Join(", ", array);
    var result = (array.Length > 2)
        ? joined.ReplaceLast(",", ", and")
        : joined.ReplaceLast(",", " and");

    return result;
}

...最后一个“如此标准它应该只在框架中”已取代“ReplaceLast实现:

public static string ReplaceLast(this string value, string oldValue, string newValue)
{
    var position = value.LastIndexOf(oldValue, StringComparison.InvariantCultureIgnoreCase);
    var result = (position > -1)
        ? value.Substring(0, position) + newValue + value.Substring(position + 1)
        : value;

    return result;
}