ASP.NET成员资格提供程序 - 重置密码功能 - 电子邮件确认和密码更改

pel*_*rge 13 c# asp.net asp.net-membership forgot-password password-recovery

有没有人有以下功能的解决方案(示例代码):

  • 创建randomGuid/Cryptographically强随机数
  • 将包含随机数的唯一URL发送到用户的电子邮件地址
  • 确认后,系统会要求用户更改密码

我的提供者目前通过这种方式进行参数化:

enablePasswordRetrieval="false" 
enablePasswordReset="true" 
requiresQuestionAndAnswer="false" 
applicationName="/" 
requiresUniqueEmail="true" 
passwordFormat="Hashed" 
maxInvalidPasswordAttempts="5" 
minRequiredPasswordLength="5" 
minRequiredNonalphanumericCharacters="0" 
passwordAttemptWindow="10" 
passwordStrengthRegularExpression="" 
name="AspNetSqlMembershipProvider"
Run Code Online (Sandbox Code Playgroud)

这种类型的程序的安全问题进行了讨论这里之前.

Ryk*_*Ryk 5

芮,我几天前在类似的船上,而且以前没有大量接触会员提供商,我努力让它得到正确实施,因为我认为你必须实现和使用整个事情,因为或者什么也没有.

好吧,我很快发现你只能使用它的一部分,而不是整个物体.例如,在我的应用程序中,我有自己的用户对象和我自己的密码和登录模块,但我需要让表单身份验证工作.所以我基本上只使用该部分的成员资格提供者.我没有覆盖任何方法或任何东西,只是将它用于FormsAuthentication,然后我使用自己的存储库来更改密码,验证用户名密码等.

这是我在MVC中的登录代码的片段.

   var authTicket =  new FormsAuthenticationTicket(1, user.UniqueName, DateTime.UtcNow, DateTime.UtcNow.AddHours(2), rememberMe, cookieValues);
    var encryptedTicket = FormsAuthentication.Encrypt(authTicket);
    var authCookie = new HttpCookie(FormsAuthentication.FormsCookieName, encryptedTicket) { Expires = DateTime.UtcNow.AddDays(14) };

    httpResponseBase.Cookies.Add(authCookie);
Run Code Online (Sandbox Code Playgroud)

这使我能够使用FormsAuthentication.SignOut(); 会员提供商提供的方法和其他方法.

在你的问题上重新创建一个randomGuid/Cryptographically强大的随机数,这是一个很好的方法,你可以使用,我发现它不久前,我很抱歉,但不记得在网络的哪里

/// <summary>
/// A simple class which can be used to generate "unguessable" verifier values.
/// </summary>
public class UnguessableGenerator
{
    const string AllowableCharacters = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789/^()";
    const string SimpleAllowableCharacters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";

    /// <summary>
    /// Generates an unguessable string sequence of a certain length
    /// </summary>
    /// <param name="length">The length.</param>
    /// <param name="useSimpleCharacterSet">if set to <c>true</c> [use simple character set].</param>
    /// <returns></returns>
    public static string GenerateUnguessable(int length, bool useSimpleCharacterSet = false, string additionalCharacters = "")
    {
        var random = new Random();

        var chars = new char[length];

        var charsToUse = useSimpleCharacterSet ? SimpleAllowableCharacters : AllowableCharacters;
        charsToUse = string.Format("{0}{1}", charsToUse, additionalCharacters);

        var allowableLength = charsToUse.Length;

        for (var i = 0; i < length; i++)
        {
            chars[i] = charsToUse[random.Next(allowableLength)];
        }

        return new string(chars);
    }




    /// <summary>
    /// Generates an ungessable string, defaults the length to what google uses (24 characters)
    /// </summary>
    /// <returns></returns>
    public static string GenerateUnguessable()
    {
        return GenerateUnguessable(24);
    }
}
Run Code Online (Sandbox Code Playgroud)

对于将包含随机数的唯一URL发送到用户的电子邮件地址,您需要在User表或任何表中存储随机ID,然后在电子邮件中的精心制作的URL中使用该URL,用户可以使用校验.

这将要求您创建一个接受该类型的Url的Url,然后您必须从查询字符串中提取所需的部分并更新您的用户对象.

对于确认后,系统会要求用户更改密码,默认情况下,您的表中会有一个强制用户更改密码的位标志,如果您需要强制用户更改密码,这也会在以后派上用场.因此,您的登录代码会查看此位标志是否已打开,如果是,则会先强制更改密码.然后,一旦用户更改了密码,您将关闭此标志.

希望这可以帮助.

  • 在代码示例中对于滥用Thread.Sleep进行了深思熟虑 - 如果您想要真正的随机数据,请使用加密提供程序. (2认同)