前言:
使用Membership时,涉及密码的操作,一般有:
(1)修改密码:已知旧密码,使用ChangePassword进行;
(2)获得随机密码:使用ResetPassword进行;
(3)修改问题和答案:已知旧密码,使用ChangePasswordQuestionAndAnswer进行;
有时候,客户忘记旧密码,需要强行重置密码。
涉及的关键代码段为:
代码
#region
强制重置密码
// 强制重新设置密码
protected void btn_ForceResetPwd_Click( object sender, EventArgs e)
{
try
{
string connStr = WebConfigurationManager.ConnectionStrings[ " MemberShipSqlConnection " ].ToString();
string username = lblUserName.Text.Trim();
string strPswFormat = " Clear " ; // 默认值
// ==从WebConfig中获取Membership的Format==
MembershipSection m = (MembershipSection)ConfigurationManager.GetSection( " system.web/membership " );
ProviderSettings p = m.Providers[m.DefaultProvider];
NameValueCollection nv = p.Parameters;
if (nv == null || p.Parameters.Count == 0 || string .IsNullOrEmpty(nv[ " passwordFormat " ]))
{
strPswFormat = " Clear " ;
}
else
{
strPswFormat = nv[ " passwordFormat " ];
}
// === 产生加密用的密码密钥 ===
string salt = GenerateSalt();
// === 将明码密码加密(此时密码为"@Pssw0rd" 当然也可随机数生成) ===
string password = EncryptToHashString(txt_ForceNewPassword.Text, salt, " SHA1 " );
if (strPswFormat.Equals( " Clear " ))
{
password = txt_ForceNewPassword.Text;
}
SqlConnection conn = new SqlConnection(connStr);
conn.Open();
// === 在此我们呼叫 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 " , username));
// === 加密过的密码 ===
cmd.Parameters.Add( new SqlParameter( " @NewPassword " , password));
// === 密码加密密钥(一定和使用加密密码的密钥一样,不要再重新产生) ===
cmd.Parameters.Add( new SqlParameter( " @PasswordSalt " , salt));
// === 重置密码的时间 ===
cmd.Parameters.Add( new SqlParameter( " @CurrentTimeUtc " , DateTime.Now));
// === 密码加密的格式(此时是Hash1,注意传入参数是int型态。) ===
if (strPswFormat.Equals( " Clear " ))
{
cmd.Parameters.Add( new SqlParameter( " @PasswordFormat " , "" ));
}
else
{
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();
conn.Close();
// === 检查重置密码是否成功 ===
if (returnValue.Value.ToString() == " 0 " )
lbl_Tips.Text = " 重置密码成功!! " ;
else
lbl_Tips.Text = " 重置密码失败!! " ;
}
catch (Exception ex)
{
throw ex;
}
finally
{
string userName = Request.QueryString[ " UserName " ];
if ( ! String.IsNullOrEmpty(userName))
{
SetUserDetail(userName);
}
}
}
/// <summary>
/// 密码加密钥
/// </summary>
/// <returns></returns>
public string GenerateSalt()
{
byte [] data = new byte [ 0x10 ];
new System.Security.Cryptography.RNGCryptoServiceProvider().GetBytes(data);
return Convert.ToBase64String(data);
}
/// <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);
}
#endregion
// 强制重新设置密码
protected void btn_ForceResetPwd_Click( object sender, EventArgs e)
{
try
{
string connStr = WebConfigurationManager.ConnectionStrings[ " MemberShipSqlConnection " ].ToString();
string username = lblUserName.Text.Trim();
string strPswFormat = " Clear " ; // 默认值
// ==从WebConfig中获取Membership的Format==
MembershipSection m = (MembershipSection)ConfigurationManager.GetSection( " system.web/membership " );
ProviderSettings p = m.Providers[m.DefaultProvider];
NameValueCollection nv = p.Parameters;
if (nv == null || p.Parameters.Count == 0 || string .IsNullOrEmpty(nv[ " passwordFormat " ]))
{
strPswFormat = " Clear " ;
}
else
{
strPswFormat = nv[ " passwordFormat " ];
}
// === 产生加密用的密码密钥 ===
string salt = GenerateSalt();
// === 将明码密码加密(此时密码为"@Pssw0rd" 当然也可随机数生成) ===
string password = EncryptToHashString(txt_ForceNewPassword.Text, salt, " SHA1 " );
if (strPswFormat.Equals( " Clear " ))
{
password = txt_ForceNewPassword.Text;
}
SqlConnection conn = new SqlConnection(connStr);
conn.Open();
// === 在此我们呼叫 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 " , username));
// === 加密过的密码 ===
cmd.Parameters.Add( new SqlParameter( " @NewPassword " , password));
// === 密码加密密钥(一定和使用加密密码的密钥一样,不要再重新产生) ===
cmd.Parameters.Add( new SqlParameter( " @PasswordSalt " , salt));
// === 重置密码的时间 ===
cmd.Parameters.Add( new SqlParameter( " @CurrentTimeUtc " , DateTime.Now));
// === 密码加密的格式(此时是Hash1,注意传入参数是int型态。) ===
if (strPswFormat.Equals( " Clear " ))
{
cmd.Parameters.Add( new SqlParameter( " @PasswordFormat " , "" ));
}
else
{
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();
conn.Close();
// === 检查重置密码是否成功 ===
if (returnValue.Value.ToString() == " 0 " )
lbl_Tips.Text = " 重置密码成功!! " ;
else
lbl_Tips.Text = " 重置密码失败!! " ;
}
catch (Exception ex)
{
throw ex;
}
finally
{
string userName = Request.QueryString[ " UserName " ];
if ( ! String.IsNullOrEmpty(userName))
{
SetUserDetail(userName);
}
}
}
/// <summary>
/// 密码加密钥
/// </summary>
/// <returns></returns>
public string GenerateSalt()
{
byte [] data = new byte [ 0x10 ];
new System.Security.Cryptography.RNGCryptoServiceProvider().GetBytes(data);
return Convert.ToBase64String(data);
}
/// <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);
}
#endregion
其中Webconfig中的配置为:
代码
<
membership defaultProvider
=
"
MembershipProvider
"
userIsOnlineTimeWindow
=
"
15
"
>
< providers >
< clear />
< add name = " MembershipProvider " type = " System.Web.Security.SqlMembershipProvider " connectionStringName = " MemberShipSqlConnection " applicationName = " LivePortal " enablePasswordRetrieval = " true " enablePasswordReset = " true " requiresQuestionAndAnswer = " false " requiresUniqueEmail = " false " passwordFormat = " Clear " minRequiredPasswordLength = " 1 " minRequiredNonalphanumericCharacters = " 0 " maxInvalidPasswordAttempts = " 20 " passwordAttemptWindow = " 10 " />
</ providers >
</ membership >
< providers >
< clear />
< add name = " MembershipProvider " type = " System.Web.Security.SqlMembershipProvider " connectionStringName = " MemberShipSqlConnection " applicationName = " LivePortal " enablePasswordRetrieval = " true " enablePasswordReset = " true " requiresQuestionAndAnswer = " false " requiresUniqueEmail = " false " passwordFormat = " Clear " minRequiredPasswordLength = " 1 " minRequiredNonalphanumericCharacters = " 0 " maxInvalidPasswordAttempts = " 20 " passwordAttemptWindow = " 10 " />
</ providers >
</ membership >