нашел ошибку . по крайней мере после исправления пароли восстанавливались без ошибок.
ошибка была в самом YafMembershipProvider в методе изменения пароля (ChangePassword) где при изменении пароля каждый раз генерировалось новое значение для PasswordSalt
Код:
public override bool ChangePassword(string username, string oldPassword, string newPassword)
{
string salt = string.Empty;
string str2 = string.Empty;
if (!this.IsPasswordCompliant(newPassword))
{
return false;
}
UserPasswordInfo info = UserPasswordInfo.CreateInstanceFromDB(this.ApplicationName, username, false, this.UseSalt, this.HashHex, this.HashCase, this.HashRemoveChars, this.MSCompliant);
if (info == null)
{
return false;
}
if (!info.IsCorrectPassword(oldPassword))
{
return false;
}
if (this.UseSalt)
{
salt = GenerateSalt();
}
str2 = EncodeString(newPassword, (int)this.PasswordFormat, salt, this.UseSalt, this.HashHex, this.HashCase, this.HashRemoveChars, this.MSCompliant);
DB.ChangePassword(this.ApplicationName, username, str2, salt, (int)this.PasswordFormat, info.PasswordAnswer);
return true;
}
в нашем случае это здесь: salt = GenerateSalt() а DB.ChangePassword спокойно сохраняет новый сальт для юзера.
Но при этом не меняется закодированный с помощью старого сальта ответ к вопросу.
Таким образом при сравнивании закодированного (с применением старого сальта) ответа с тем ответом который вводится с клавиатуры (а этот естественно кодируется уже новым измененным сальтом) у нас всегда в ответ будет не совпадать с ранее введенным.
а при обновлении пароля в :
Код:
public override string ResetPassword(string username, string answer)
{
string clearString = string.Empty;
string password = string.Empty;
string salt = string.Empty;
if (!this.EnablePasswordReset)
{
ExceptionReporter.ThrowNotSupported("MEMBERSHIP", "RESETNOTSUPPORTED");
}
if (username == null)
{
ExceptionReporter.ThrowArgument("MEMBERSHIP", "USERNAMEPASSWORDNULL");
}
UserPasswordInfo info = UserPasswordInfo.CreateInstanceFromDB(this.ApplicationName, username, false, this.UseSalt, this.HashHex, this.HashCase, this.HashRemoveChars, this.MSCompliant);
if (info == null)
{
return null;
}
if (this.UseSalt && string.IsNullOrEmpty(info.PasswordSalt))
{
salt = GenerateSalt();
}
else
{
salt = info.PasswordSalt;
}
if (!string.IsNullOrEmpty(answer) && !info.IsCorrectAnswer(answer))
{
return null;
}
clearString = GeneratePassword(this.MinRequiredPasswordLength, this.MinRequiredNonAlphanumericCharacters);
password = EncodeString(clearString, (int)this.PasswordFormat, salt, this.UseSalt, this.HashHex, this.HashCase, this.HashRemoveChars, this.MSCompliant);
DB.ResetPassword(this.ApplicationName, username, password, salt, (int)this.PasswordFormat, this.MaxInvalidPasswordAttempts, this.PasswordAttemptWindow);
return clearString;
}
то есть кусок кода ниже будет всегда выбрасывать нулл
Код:
if (!string.IsNullOrEmpty(answer) && !info.IsCorrectAnswer(answer))
{
return null;
}
для исправления в методе ChangePassword стоит
вместо
Код:
if (this.UseSalt)
{
salt = GenerateSalt();
}
поставить
Код:
if (this.UseSalt && string.IsNullOrEmpty(info.PasswordSalt))
{
salt = GenerateSalt();
}
else
{
salt = info.PasswordSalt;
}
и перекомпилировать сборку.