1
votes

I am trying to setpassword with for forget password functionality.

public string SetPassWord(string userName, string randomPassword)
{
    string result = string.Empty;
    PrincipalContext ctx = new PrincipalContext(ContextType.Domain);
    UserPrincipal user = UserPrincipal.FindByIdentity(ctx, userName);
    AdUser adUser = new AdUser();
    if (user != null)
    {
        user.SetPassword(randomPassword);
        result = "Success";
    }
    return result;
}

I need to generate the random password which meets the following complexity:

  • Not contain the user's account name or parts of the user's full name that exceed two consecutive characters
  • Be at least six characters in length
  • Contain characters from three of the following four categories:
    • English uppercase characters (A through Z)
    • English lowercase characters (a through z)
    • Base 10 digits (0 through 9)
    • Non-alphabetic characters (for example, !, $, #, %)

Complexity requirements are enforced when passwords are changed or created.

Is there any inbuilt method which serves the above requirements? I have used below method to generate password randomely:

string randomPassword = Membership.GeneratePassword(8, 0).Replace('<','!').Replace('>', '#');

It throws the error when I am trying to set password. Appreciate if there is and validation or inbuilt method to achieve the above requirement.

2
I can't help you on the generate part, but I could give you a regex to validate it. - user557597
You could always randomly generate 1-3 items from each category, then randomly mix them up. Then run them through a validation regex to be sure. IMO, the validation regex is more difficult. And with 6 to 9 length would be un-crackable. - user557597
This Not contain the user's account name or parts of the user's full name that exceed two consecutive characters requires a separate regex or process. The rest can be validated with a single regex. - user557597
i agree . Please provide me the regex validation. Thanks - Savan Patel
I have user below validation. Let me know if you have fast and better validation. Thanks for the idea. Appreciate the help. bool isANameCharRepeats = Regex.Matches(uName, "(?=(..))") .Cast<Match>() .Select(m => m.Groups[1].Value) .Any(y => randomPassword.IndexOf(y) != -1); - Savan Patel

2 Answers

0
votes

See if something like this works for you. I originally wrote this for .Net Identity 2 but it should point you in the right direction. You can see how I'm using it on GitHub

var validator = new PasswordValidator
{
    RequiredLength = 6,
    RequireNonLetterOrDigit = false,
    RequireDigit = true,
    RequireLowercase = true,
    RequireUppercase = true
};

passwords.Add(GeneratePassword(validator));


private static string GeneratePassword(PasswordValidator passwordValidator)
{
    var rnd = new Random();

    while (true)
    {
        var password = Membership.GeneratePassword(passwordValidator.RequiredLength, 0);
        if ((passwordValidator.RequireDigit && !password.Any(char.IsDigit)) || (passwordValidator.RequireLowercase && !password.Any(char.IsLower)) || (passwordValidator.RequireUppercase && !password.Any(char.IsUpper)))
            continue;

        if (!passwordValidator.RequireNonLetterOrDigit) password = Regex.Replace(password, @"[^a-zA-Z0-9]", m => rnd.Next(0, 10).ToString());
        return password;
    }
}
0
votes

I think using ActiveDirectoryMembershipProvider's ResetPassword() method should do exactly what you're looking for. MSDN - ActiveDirectoryMembershipProvider - ResetPassword()