终于找到Membership.CreateUser的实现代码
最近做一个不用membership而手动找回密码的程序
到了最后一步,更新membership表的时候问题产生了
有两个字段,password和passwordsalt 一直在寻找这两个字段是怎么产生的,现在终于在Membership.CreateUser方法的实现中招到了答案,欣喜之际我把代码贴出来分享。
Code
public override MembershipUser CreateUser(string username, string password, string email, string passwordQuestion, string passwordAnswer, bool isApproved, object providerUserKey, out MembershipCreateStatus status)
{
string str3;
MembershipUser user;
if (!SecUtility.ValidateParameter(ref password, true, true, false, 0x80))
{
status = MembershipCreateStatus.InvalidPassword;
return null;
}
// 生成salt值
string salt = base.GenerateSalt();
// 结合salt值对密码进行散列
string objValue = base.EncodePassword(password, (int)this._PasswordFormat, salt);
if (objValue.Length > 0x80)
{
status = MembershipCreateStatus.InvalidPassword;
return null;
}
if (passwordAnswer != null)
{
passwordAnswer = passwordAnswer.Trim();
}
if (!string.IsNullOrEmpty(passwordAnswer))
{
if (passwordAnswer.Length > 0x80)
{
status = MembershipCreateStatus.InvalidAnswer;
return null;
}
str3 = base.EncodePassword(passwordAnswer.ToLower(CultureInfo.InvariantCulture), (int)this._PasswordFormat, salt);
}
else
{
str3 = passwordAnswer;
}
if (!SecUtility.ValidateParameter(ref str3, this.RequiresQuestionAndAnswer, true, false, 0x80))
{
status = MembershipCreateStatus.InvalidAnswer;
return null;
}
if (!SecUtility.ValidateParameter(ref username, true, true, true, 0x100))
{
status = MembershipCreateStatus.InvalidUserName;
return null;
}
if (!SecUtility.ValidateParameter(ref email, this.RequiresUniqueEmail, this.RequiresUniqueEmail, false, 0x100))
{
status = MembershipCreateStatus.InvalidEmail;
return null;
}
if (!SecUtility.ValidateParameter(ref passwordQuestion, this.RequiresQuestionAndAnswer, true, false, 0x100))
{
status = MembershipCreateStatus.InvalidQuestion;
return null;
}
if ((providerUserKey != null) && !(providerUserKey is Guid))
{
status = MembershipCreateStatus.InvalidProviderUserKey;
return null;
}
if (password.Length < this.MinRequiredPasswordLength)
{
status = MembershipCreateStatus.InvalidPassword;
return null;
}
int num = 0;
for (int i = 0; i < password.Length; i)
{
if (!char.IsLetterOrDigit(password, i))
{
num;
}
}
if (num < this.MinRequiredNonAlphanumericCharacters)
{
status = MembershipCreateStatus.InvalidPassword;
return null;
}
if ((this.PasswordStrengthRegularExpression.Length > 0) && !Regex.IsMatch(password, this.PasswordStrengthRegularExpression))
{
status = MembershipCreateStatus.InvalidPassword;
return null;
}
ValidatePasswordEventArgs e = new ValidatePasswordEventArgs(username, password, true);
this.OnValidatingPassword(e);
if (e.Cancel)
{
status = MembershipCreateStatus.InvalidPassword;
return null;
}
try
{
SqlConnectionHolder connection = null;
try
{
connection = SqlConnectionHelper.GetConnection(this._sqlConnectionString, true);
this.CheckSchemaVersion(connection.Connection);
DateTime time = this.RoundToSeconds(DateTime.UtcNow);
SqlCommand command = new SqlCommand("dbo.aspnet_Membership_CreateUser", connection.Connection);
command.CommandTimeout = this.CommandTimeout;
command.CommandType = CommandType.StoredProcedure;
command.Parameters.Add(this.CreateInputParam("@ApplicationName", SqlDbType.NVarChar, this.ApplicationName));
command.Parameters.Add(this.CreateInputParam("@UserName", SqlDbType.NVarChar, username));
command.Parameters.Add(this.CreateInputParam("@Password", SqlDbType.NVarChar, objValue));
command.Parameters.Add(this.CreateInputParam("@PasswordSalt", SqlDbType.NVarChar, salt));
command.Parameters.Add(this.CreateInputParam("@Email", SqlDbType.NVarChar, email));
command.Parameters.Add(this.CreateInputParam("@PasswordQuestion", SqlDbType.NVarChar, passwordQuestion));
command.Parameters.Add(this.CreateInputParam("@PasswordAnswer", SqlDbType.NVarChar, str3));
command.Parameters.Add(this.CreateInputParam("@IsApproved", SqlDbType.Bit, isApproved));
command.Parameters.Add(this.CreateInputParam("@UniqueEmail", SqlDbType.Int, this.RequiresUniqueEmail ? 1 : 0));
command.Parameters.Add(this.CreateInputParam("@PasswordFormat", SqlDbType.Int, (int)this.PasswordFormat));
command.Parameters.Add(this.CreateInputParam("@CurrentTimeUtc", SqlDbType.DateTime, time));
SqlParameter parameter = this.CreateInputParam("@UserId", SqlDbType.UniqueIdentifier, providerUserKey);
parameter.Direction = ParameterDirection.InputOutput;
command.Parameters.Add(parameter);
parameter = new SqlParameter("@ReturnValue", SqlDbType.Int);
parameter.Direction = ParameterDirection.ReturnValue;
command.Parameters.Add(parameter);
command.ExecuteNonQuery();
int num3 = (parameter.Value != null) ? ((int)parameter.Value) : -1;
if ((num3 < 0) || (num3 > 11))
{
num3 = 11;
}
status = (MembershipCreateStatus)num3;
if (num3 != 0)
{
return null;
}
providerUserKey = new Guid(command.Parameters["@UserId"].Value.ToString());
time = time.ToLocalTime();
user = new MembershipUser(this.Name, username, providerUserKey, email, passwordQuestion, null, isApproved, false, time, time, time, time, new DateTime(0x6da, 1, 1));
}
finally
{
if (connection != null)
{
connection.Close();
connection = null;
}
}
}
catch
{
throw;
}
return user;
}
public override MembershipUser CreateUser(string username, string password, string email, string passwordQuestion, string passwordAnswer, bool isApproved, object providerUserKey, out MembershipCreateStatus status)
{
string str3;
MembershipUser user;
if (!SecUtility.ValidateParameter(ref password, true, true, false, 0x80))
{
status = MembershipCreateStatus.InvalidPassword;
return null;
}
// 生成salt值
string salt = base.GenerateSalt();
// 结合salt值对密码进行散列
string objValue = base.EncodePassword(password, (int)this._PasswordFormat, salt);
if (objValue.Length > 0x80)
{
status = MembershipCreateStatus.InvalidPassword;
return null;
}
if (passwordAnswer != null)
{
passwordAnswer = passwordAnswer.Trim();
}
if (!string.IsNullOrEmpty(passwordAnswer))
{
if (passwordAnswer.Length > 0x80)
{
status = MembershipCreateStatus.InvalidAnswer;
return null;
}
str3 = base.EncodePassword(passwordAnswer.ToLower(CultureInfo.InvariantCulture), (int)this._PasswordFormat, salt);
}
else
{
str3 = passwordAnswer;
}
if (!SecUtility.ValidateParameter(ref str3, this.RequiresQuestionAndAnswer, true, false, 0x80))
{
status = MembershipCreateStatus.InvalidAnswer;
return null;
}
if (!SecUtility.ValidateParameter(ref username, true, true, true, 0x100))
{
status = MembershipCreateStatus.InvalidUserName;
return null;
}
if (!SecUtility.ValidateParameter(ref email, this.RequiresUniqueEmail, this.RequiresUniqueEmail, false, 0x100))
{
status = MembershipCreateStatus.InvalidEmail;
return null;
}
if (!SecUtility.ValidateParameter(ref passwordQuestion, this.RequiresQuestionAndAnswer, true, false, 0x100))
{
status = MembershipCreateStatus.InvalidQuestion;
return null;
}
if ((providerUserKey != null) && !(providerUserKey is Guid))
{
status = MembershipCreateStatus.InvalidProviderUserKey;
return null;
}
if (password.Length < this.MinRequiredPasswordLength)
{
status = MembershipCreateStatus.InvalidPassword;
return null;
}
int num = 0;
for (int i = 0; i < password.Length; i)
{
if (!char.IsLetterOrDigit(password, i))
{
num;
}
}
if (num < this.MinRequiredNonAlphanumericCharacters)
{
status = MembershipCreateStatus.InvalidPassword;
return null;
}
if ((this.PasswordStrengthRegularExpression.Length > 0) && !Regex.IsMatch(password, this.PasswordStrengthRegularExpression))
{
status = MembershipCreateStatus.InvalidPassword;
return null;
}
ValidatePasswordEventArgs e = new ValidatePasswordEventArgs(username, password, true);
this.OnValidatingPassword(e);
if (e.Cancel)
{
status = MembershipCreateStatus.InvalidPassword;
return null;
}
try
{
SqlConnectionHolder connection = null;
try
{
connection = SqlConnectionHelper.GetConnection(this._sqlConnectionString, true);
this.CheckSchemaVersion(connection.Connection);
DateTime time = this.RoundToSeconds(DateTime.UtcNow);
SqlCommand command = new SqlCommand("dbo.aspnet_Membership_CreateUser", connection.Connection);
command.CommandTimeout = this.CommandTimeout;
command.CommandType = CommandType.StoredProcedure;
command.Parameters.Add(this.CreateInputParam("@ApplicationName", SqlDbType.NVarChar, this.ApplicationName));
command.Parameters.Add(this.CreateInputParam("@UserName", SqlDbType.NVarChar, username));
command.Parameters.Add(this.CreateInputParam("@Password", SqlDbType.NVarChar, objValue));
command.Parameters.Add(this.CreateInputParam("@PasswordSalt", SqlDbType.NVarChar, salt));
command.Parameters.Add(this.CreateInputParam("@Email", SqlDbType.NVarChar, email));
command.Parameters.Add(this.CreateInputParam("@PasswordQuestion", SqlDbType.NVarChar, passwordQuestion));
command.Parameters.Add(this.CreateInputParam("@PasswordAnswer", SqlDbType.NVarChar, str3));
command.Parameters.Add(this.CreateInputParam("@IsApproved", SqlDbType.Bit, isApproved));
command.Parameters.Add(this.CreateInputParam("@UniqueEmail", SqlDbType.Int, this.RequiresUniqueEmail ? 1 : 0));
command.Parameters.Add(this.CreateInputParam("@PasswordFormat", SqlDbType.Int, (int)this.PasswordFormat));
command.Parameters.Add(this.CreateInputParam("@CurrentTimeUtc", SqlDbType.DateTime, time));
SqlParameter parameter = this.CreateInputParam("@UserId", SqlDbType.UniqueIdentifier, providerUserKey);
parameter.Direction = ParameterDirection.InputOutput;
command.Parameters.Add(parameter);
parameter = new SqlParameter("@ReturnValue", SqlDbType.Int);
parameter.Direction = ParameterDirection.ReturnValue;
command.Parameters.Add(parameter);
command.ExecuteNonQuery();
int num3 = (parameter.Value != null) ? ((int)parameter.Value) : -1;
if ((num3 < 0) || (num3 > 11))
{
num3 = 11;
}
status = (MembershipCreateStatus)num3;
if (num3 != 0)
{
return null;
}
providerUserKey = new Guid(command.Parameters["@UserId"].Value.ToString());
time = time.ToLocalTime();
user = new MembershipUser(this.Name, username, providerUserKey, email, passwordQuestion, null, isApproved, false, time, time, time, time, new DateTime(0x6da, 1, 1));
}
finally
{
if (connection != null)
{
connection.Close();
connection = null;
}
}
}
catch
{
throw;
}
return user;
}
顺便用reflector查了一下MembershipProvider.GenerateSalt()的实现
internal string GenerateSalt() { byte[] data = new byte[0x10]; new RNGCryptoServiceProvider().GetBytes(data); return Convert.ToBase64String(data); } |
EncodePassword 方法也不难,望读者自己查看