![](/img/trans.png)
[英]Asp.Net Identity Generate Password Reset Token from one Application Pool Identity and Verify on another
[英]ASP.NET Identity : Generate random password
是否有任何内置函数可以创建随机密码? asp.net simple memebership 以前也有类似的方法
虽然我参加聚会有点晚,但我想分享我放在一起的辅助方法,以兼容 ASP.NET Core 的方式处理此类场景。
下面的函数确保了一个合适的字符分布,在字符串中随机添加所需的字符类型而不改变所需的长度(除非有大量所需的唯一字符的边缘情况,这是设计的意思)。 它还支持RequiredUniqueChars
规则,这是ASP.NET Core Identity框架可用的强度要求之一。
/// <summary>
/// Generates a Random Password
/// respecting the given strength requirements.
/// </summary>
/// <param name="opts">A valid PasswordOptions object
/// containing the password strength requirements.</param>
/// <returns>A random password</returns>
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<char> chars = new List<char>();
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 / 四个 bool参数组(或 POCO 类) .
在可能的情况下,您在 ASP.NET Core 项目中拥有它,您可以在定义密码要求时使用在Startup类的ConfigureService
方法中使用的完全相同的对象:
[...]
// Add ASP.NET Identity support
services.AddIdentity<ApplicationUser, IdentityRole>(
opts =>
{
opts.Password.RequireDigit = true;
opts.Password.RequireLowercase = true;
opts.Password.RequireUppercase = true;
opts.Password.RequireNonAlphanumeric = false;
opts.Password.RequiredLength = 7;
})
.AddEntityFrameworkStores<ApplicationDbContext>();
[...]
有关此辅助函数的更多详细信息,您还可以阅读我博客上的这篇文章。
如果您使用 .NET Framework 并且System.Web.Security.Membership
可用:
检查这里:
string password = Membership.GeneratePassword(12, 1);
请注意,此类在 .NET Standard 或 .NET Core 中不可用。
ASP.NET Identity 没有生成密码的方法。
我不确定您的确切用例,但我相信首选方法是向用户发送一个重置密码链接,允许用户输入自己的密码。 这通常被认为比以纯文本形式发送生成的密码更安全。
请参阅本教程中的重置密码部分: http : //www.asp.net/identity/overview/features-api/account-confirmation-and-password-recovery-with-aspnet-identity
我知道这是一个老问题,还有其他人发布了随机生成密码的源代码,但Membership.GeneratePassword是这样实现的:
幸运的是,这是在 MIT 许可证下获得许可的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[] { '<', '&' };
/// <summary>Generates a random password of the specified length.</summary>
/// <returns>A random password of the specified length.</returns>
/// <param name="length">The number of characters in the generated password. The length must be between 1 and 128 characters. </param>
/// <param name="numberOfNonAlphanumericCharacters">The minimum number of non-alphanumeric characters (such as @, #, !, %, &, and so on) in the generated password.</param>
/// <exception cref="T:System.ArgumentException">
/// <paramref name="length" /> is less than 1 or greater than 128 -or-<paramref name="numberOfNonAlphanumericCharacters" /> is less than 0 or greater than <paramref name="length" />. </exception>
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 (e.g. 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;
}
}
Membership.GeneratePassword()
创建一个不符合身份验证器的密码。
我编写了一个简单的函数,考虑使用 UserManager 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)); // a-z
if (requireUppercase)
randomPassword += Convert.ToChar(random.Next(65, 91)); // A-Z
if (requireNonLetterOrDigit)
randomPassword += Convert.ToChar(random.Next(33, 48)); // symbols !"#$%&'()*+,-./
return randomPassword;
}
并调用:
string password = GeneratePassword(UserManager.PasswordValidator as MessagePasswordValidator);
https://msdn.microsoft.com/ru-ru/library/system.guid.newguid(v=vs.110).aspx看看这个。 GUID 应该可以正常工作(只需从中删除所有 '-' 并剪切所需的数字,如果是字符)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.