ASP.NET标识:生成随机密码

是否有任何内置函数可以创建随机密码? Asp.net简单的memebership曾经有过类似的方法

你使用什么框架?

点击这里 :

  string password = Membership.GeneratePassword(12, 1); 

虽然我在聚会上有点晚了,但我想分享一下帮助方法,我把它放在一起以ASP.NET Core兼容的方式处理这些场景。

下面的函数确保了一个合适的char分布,在字符串中随机添加所需的字符类型,而不是改变所需的长度(除非边缘情况具有许多所需的唯一字符,这是设计所指的)。 它还支持RequiredUniqueChars规则,这是ASP.NET Core Identity框架可用的强度要求之一。

  ///  /// Generates a Random Password /// respecting the given strength requirements. ///  /// A valid PasswordOptions object /// containing the password strength requirements. /// A random password public static string GenerateRandomPassword(PasswordOptions opts = null) { if (opts == null) opts = new PasswordOptions() { RequiredLength = 8, RequiredUniqueChars = 4, RequireDigit = true, RequireLowercase = true, RequireNonAlphanumeric = true, RequireUppercase = true }; string[] randomChars = new[] { "ABCDEFGHJKLMNOPQRSTUVWXYZ", // uppercase "abcdefghijkmnopqrstuvwxyz", // lowercase "0123456789", // digits "!@$?_-" // non-alphanumeric }; Random rand = new Random(Environment.TickCount); List chars = new List(); if (opts.RequireUppercase) chars.Insert(rand.Next(0, chars.Count), randomChars[0][rand.Next(0, randomChars[0].Length)]); if (opts.RequireLowercase) chars.Insert(rand.Next(0, chars.Count), randomChars[1][rand.Next(0, randomChars[1].Length)]); if (opts.RequireDigit) chars.Insert(rand.Next(0, chars.Count), randomChars[2][rand.Next(0, randomChars[2].Length)]); if (opts.RequireNonAlphanumeric) chars.Insert(rand.Next(0, chars.Count), randomChars[3][rand.Next(0, randomChars[3].Length)]); for (int i = chars.Count; i < opts.RequiredLength || chars.Distinct().Count() < opts.RequiredUniqueChars; i++) { string rcs = randomChars[rand.Next(0, randomChars.Length)]; chars.Insert(rand.Next(0, chars.Count), rcs[rand.Next(0, rcs.Length)]); } return new string(chars.ToArray()); } 

该函数将PasswordOptions对象作为参数,由Microsoft.AspNetCore.Identity程序集提供,但如果您没有安装该程序包,则可以使用两个int / 4 bool参数组(或POCO类)轻松替换它。

在您可能的情况下,在ASP.NET Core项目中,您可以在定义密码要求时使用Startup类的ConfigureService方法中使用的完全相同的对象:

 [...] // Add ASP.NET Identity support services.AddIdentity( opts => { opts.Password.RequireDigit = true; opts.Password.RequireLowercase = true; opts.Password.RequireUppercase = true; opts.Password.RequireNonAlphanumeric = false; opts.Password.RequiredLength = 7; }) .AddEntityFrameworkStores(); [...] 

有关此辅助函数的其他详细信息,您还可以在我的博客上阅读此文章 。

ASP.NET Identity没有生成密码方法。

我不确定您的确切用例,但我认为首选方法是向用户发送重置密码链接,允许用户输入自己的密码。 这通常被认为比以纯文本forms发送生成的密码更安全。

请参阅本教程中的“重置密码”部分: http : //www.asp.net/identity/overview/features-api/account-confirmation-and-password-recovery-with-aspnet-identity

Membership.GeneratePassword()创建一个不符合Identityvalidation器的密码。

我编写了一个简单的函数,考虑UserManager Validator创建一个正确的随机密码来分配给用户。

它只是生成随机字符并检查字符是否满足Validator要求。 如果不满足要求,则会附加剩余的字符以满足规则。

 private string GeneratePassword(MessagePasswordValidator validator) { if (validator == null) return null; bool requireNonLetterOrDigit = validator.RequireNonLetterOrDigit; bool requireDigit = validator.RequireDigit; bool requireLowercase = validator.RequireLowercase; bool requireUppercase = validator.RequireUppercase; string randomPassword = string.Empty; int passwordLength = validator.RequiredLength; Random random = new Random(); while (randomPassword.Length != passwordLength) { int randomNumber = random.Next(48, 122); // >= 48 && < 122 if (randomNumber == 95 || randomNumber == 96) continue; // != 95, 96 _' char c = Convert.ToChar(randomNumber); if (requireDigit) if (char.IsDigit(c)) requireDigit = false; if (requireLowercase) if (char.IsLower(c)) requireLowercase = false; if (requireUppercase) if (char.IsUpper(c)) requireUppercase = false; if (requireNonLetterOrDigit) if (!char.IsLetterOrDigit(c)) requireNonLetterOrDigit = false; randomPassword += c; } if (requireDigit) randomPassword += Convert.ToChar(random.Next(48, 58)); // 0-9 if (requireLowercase) randomPassword += Convert.ToChar(random.Next(97, 123)); // az if (requireUppercase) randomPassword += Convert.ToChar(random.Next(65, 91)); // AZ if (requireNonLetterOrDigit) randomPassword += Convert.ToChar(random.Next(33, 48)); // symbols !"#$%&'()*+,-./ return randomPassword; } 

并致电:

 string password = GeneratePassword(UserManager.PasswordValidator as MessagePasswordValidator); 

我知道这是一个老问题,并且还有其他人为随机生成密码提供了源代码,但Membership.GeneratePassword的实现方式如下:

幸运的是,这是根据麻省理工学院许可证https://github.com/Microsoft/referencesource/blob/master/LICENSE.txt许可的。

 public class PasswordStore { private static readonly char[] Punctuations = "!@#$%^&*()_-+=[{]};:>|./?".ToCharArray(); private static readonly char[] StartingChars = new char[] { '<', '&' }; /// Generates a random password of the specified length. /// A random password of the specified length. /// The number of characters in the generated password. The length must be between 1 and 128 characters.  /// The minimum number of non-alphanumeric characters (such as @, #, !, %, &, and so on) in the generated password. ///  ///  is less than 1 or greater than 128 -or- is less than 0 or greater than .  public static string GeneratePassword(int length, int numberOfNonAlphanumericCharacters) { if (length < 1 || length > 128) throw new ArgumentException("password_length_incorrect", nameof(length)); if (numberOfNonAlphanumericCharacters > length || numberOfNonAlphanumericCharacters < 0) throw new ArgumentException("min_required_non_alphanumeric_characters_incorrect", nameof(numberOfNonAlphanumericCharacters)); string s; int matchIndex; do { var data = new byte[length]; var chArray = new char[length]; var num1 = 0; new RNGCryptoServiceProvider().GetBytes(data); for (var index = 0; index < length; ++index) { var num2 = (int)data[index] % 87; if (num2 < 10) chArray[index] = (char)(48 + num2); else if (num2 < 36) chArray[index] = (char)(65 + num2 - 10); else if (num2 < 62) { chArray[index] = (char)(97 + num2 - 36); } else { chArray[index] = Punctuations[num2 - 62]; ++num1; } } if (num1 < numberOfNonAlphanumericCharacters) { var random = new Random(); for (var index1 = 0; index1 < numberOfNonAlphanumericCharacters - num1; ++index1) { int index2; do { index2 = random.Next(0, length); } while (!char.IsLetterOrDigit(chArray[index2])); chArray[index2] = Punctuations[random.Next(0, Punctuations.Length)]; } } s = new string(chArray); } while (IsDangerousString(s, out matchIndex)); return s; } internal static bool IsDangerousString(string s, out int matchIndex) { //bool inComment = false; matchIndex = 0; for (var i = 0; ;) { // Look for the start of one of our patterns var n = s.IndexOfAny(StartingChars, i); // If not found, the string is safe if (n < 0) return false; // If it's the last char, it's safe if (n == s.Length - 1) return false; matchIndex = n; switch (s[n]) { case '<': // If the < is followed by a letter or '!', it's unsafe (looks like a tag or HTML comment) if (IsAtoZ(s[n + 1]) || s[n + 1] == '!' || s[n + 1] == '/' || s[n + 1] == '?') return true; break; case '&': // If the & is followed by a #, it's unsafe (eg S) if (s[n + 1] == '#') return true; break; } // Continue searching i = n + 1; } } private static bool IsAtoZ(char c) { if ((int)c >= 97 && (int)c <= 122) return true; if ((int)c >= 65) return (int)c <= 90; return false; } } 

https://msdn.microsoft.com/ru-ru/library/system.guid.newguid(v=vs.110).aspx看看这个。 GUID应该可以正常工作(只需从中删除所有’ – ‘并删除所需的数字,如果字符)