Membership 重置使用者密碼 "我忘了密碼而且我也忘了安全性答案怎麼辦!?"

Membership 重置使用者密碼 "我忘了密碼而且我也忘了安全性答案怎麼辦!?"

重置密碼只要在Web.config的Membership Provider設定enablePasswordReset=true,在程式碼中呼叫MembershipUser.ResetPassword()就可解決了。
 

但如果又要求新增使用者的時侯必須要提供安全性問題(requiresQuestionAndAnswer=true)時,重置密碼MembershipUser.ResetPassword()函數就必須要多提供一個參數為安全性問題的解答,對於一般使用者告訴你說"我忘了密碼而且我也忘了安全性答案怎麼辦!?"
 

告訴他活該 誰叫你會忘記密碼 而且沒救了~
他就會告訴你怎麼會有這麼爛的系統阿……(這是剛開始使用Membership的經驗 >"<||| )

系統管理者當然也要有重置密碼的功能阿!不然一天到晚再開新帳號也不是辦法。

我們可以用程式碼來做到重置密碼的功能

protected void Button1_Click(object sender, EventArgs e)
    {
        //=== 產生加密用的密碼金鑰 ===
        string salt = GenerateSalt();

        //=== 將明碼密碼加密(此時密碼為"P@ssw0rd" 當然也可亂數產生) ===
        string password = EncryptToHashString("P@ssw0rd", salt, "SHA1");

        SqlConnection conn = new SqlConnection("我是連線字串");

        //=== 在此我們呼叫 Membership 提供者 資料庫裡的預存程序來重置密碼 ===
        SqlCommand cmd = new SqlCommand("aspnet_Membership_SetPassword", conn);
        cmd.CommandType = CommandType.StoredProcedure;

        //=== 目前使用 Membership 提供者的 web 應用程式名稱 ===
        cmd.Parameters.Add(new SqlParameter("@ApplicationName", Membership.ApplicationName));

        //=== 要重置密碼的使用者帳號 ===
        cmd.Parameters.Add(new SqlParameter("@UserName", "jimmy"));

        //=== 加密過的密碼 ===
        cmd.Parameters.Add(new SqlParameter("@NewPassword", password));

        //=== 密碼加密金鑰(一定和使用加密密碼的金鑰一樣,不要再重新產生) ===
        cmd.Parameters.Add(new SqlParameter("@PasswordSalt", salt));
        
        //=== 重置密碼的時間 ===
        cmd.Parameters.Add(new SqlParameter("@CurrentTimeUtc", "GetDate()"));

        //=== 密碼加密的格式(此時是Hash1,注意傳入參數是int型態。) ===
        cmd.Parameters.Add(new SqlParameter("@PasswordFormat", Membership.Provider.PasswordFormat.GetHashCode()));

        //=== 宣告一個可以接收回傳值得參數 ===
        SqlParameter returnValue = new SqlParameter();
        returnValue.ParameterName = "returnValue";
        returnValue.Direction = ParameterDirection.ReturnValue;
        cmd.Parameters.Add(returnValue);

        //=== 執行預存程序 ===
        cmd.ExecuteNonQuery();

        //=== 檢查重置密碼是否成功 ===
        if (returnValue.Value.ToString() == "0")
            Response.Write("重置密碼成功!!");
        else
            Response.Write("重置密碼失敗!!");
    }


 

以下提供GenerateSalt()函數

 

    /// <summary>
    /// 密碼加密鑰
    /// </summary>
    /// <returns></returns>
    public string GenerateSalt()
    {
        byte[] data = new byte[0x10];
        new System.Security.Cryptography.RNGCryptoServiceProvider().GetBytes(data);
        return Convert.ToBase64String(data);
    }

以下提供EncryptToHashString()函數

/// <summary>
    /// 雜湊密碼加密(不可還原)
    /// </summary>
    /// <param name="s">原始字串</param>
    /// <param name="saltKey">Salt加密字串</param>
    /// <param name="hashName">加密格式(MD5, SHA1, SHA256, SHA384, SHA512....)</param>
    /// <returns>加密過的密碼</returns>
    public string EncryptToHashString(string s, string saltKey, string hashName)
    {
        byte[] src = System.Text.Encoding.Unicode.GetBytes(s);
        byte[] saltbuf = Convert.FromBase64String(saltKey);
        byte[] dst = new byte[saltbuf.Length + src.Length];
        byte[] inArray = null;
        System.Buffer.BlockCopy(saltbuf, 0, dst, 0, saltbuf.Length);
        System.Buffer.BlockCopy(src, 0, dst, saltbuf.Length, src.Length);

        System.Security.Cryptography.HashAlgorithm algorithm = System.Security.Cryptography.HashAlgorithm.Create(hashName);
        inArray = algorithm.ComputeHash(dst);

        return Convert.ToBase64String(inArray);
    }