Как создать провайдер членства asp.net вручную?
Я использую веб-сайт как интерфейс, и все пользователи проходят аутентификацию со стандартным членством в ASP.NET. Пароли сохраняются "хэшированными" в SQL-базе данных.
Теперь я хочу написать desktop-client с административными функциями. Среди прочего должен быть метод для reset пароля пользователя. Я могу получить доступ к базе данных с сохраненными данными членства, но как я могу вручную создать пароль-соль и -hash? Использование пространства имен System.Web.Membership кажется неуместным, поэтому мне нужно знать, как вручную создать соль и хэш нового пароля.
Эксперты повышаются!:)
Ответы
Ответ 1
Вы можете абсолютно использовать System.Web.Security
в приложении консоли или winforms.
Здесь представлено простое консольное приложение:
static void Main(string[] args)
{
MembershipProvider provider = Membership.Provider;
MembershipUser myUser = provider.GetUser("myUser", false);
if( myUser != null ) provider.DeleteUser("myUser", true);
MembershipCreateStatus status;
myUser = provider.CreateUser("myUser", "password", "[email protected]", null, null, true, null, out status);
if (status != MembershipCreateStatus.Success)
{
Console.WriteLine("Could not create user. Reason: " + status.ToString());
Console.ReadLine();
return;
}
Console.WriteLine("Authenticating with \"password\": " + provider.ValidateUser("myUser", "password").ToString());
string newPassword = myUser.ResetPassword();
Console.WriteLine("Authenticating with \"password\": " + provider.ValidateUser("myUser", "password").ToString());
Console.WriteLine("Authenticating with new password: " + provider.ValidateUser("myUser", newPassword).ToString());
Console.ReadLine();
}
И app.config:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<connectionStrings>
<add name="MyConnectionString" connectionString="Data Source=localhost;Initial Catalog=MyDatabase;Integrated Security=True" providerName="System.Data.SqlClient" />
</connectionStrings>
<system.web>
<membership defaultProvider="MyMembershipProvider">
<providers>
<clear />
<add name="MyMembershipProvider"
type="System.Web.Security.SqlMembershipProvider"
connectionStringName="MyConnectionString"
applicationName="MyApplication"
minRequiredPasswordLength="5"
minRequiredNonalphanumericCharacters="0"
requiresQuestionAndAnswer="false" />
</providers>
</membership>
</system.web>
</configuration>
Ответ 2
Я использовал рефлектор, чтобы взглянуть на эти методы, которые .NET-Framework использует внутри. Возможно, для этого существуют общедоступные методы, но я их не нашел - если вы знаете, как запросить эти внутренние методы в качестве пользователя, пожалуйста, оставите комментарий!:)
Вот упрощенный исходный код без лишних условий, потому что я хочу только кодировать пароль как SHA1-Hash:
private string GenerateSalt() {
var buf = new byte[16];
(new RNGCryptoServiceProvider()).GetBytes(buf);
return Convert.ToBase64String(buf);
}
private string EncodePassword(string pass, string salt) {
byte[] bytes = Encoding.Unicode.GetBytes(pass);
byte[] src = Convert.FromBase64String(salt);
byte[] dst = new byte[src.Length + bytes.Length];
byte[] inArray = null;
Buffer.BlockCopy(src, 0, dst, 0, src.Length);
Buffer.BlockCopy(bytes, 0, dst, src.Length, bytes.Length);
HashAlgorithm algorithm = HashAlgorithm.Create("SHA1");
inArray = algorithm.ComputeHash(dst);
return Convert.ToBase64String(inArray);
}
Ответ 3
Быстрый грязный метод
Public Shared Function GetSaltKey() As String
Dim saltBytes() As Byte
Dim minSaltSize As Integer = 4
Dim maxSaltSize As Integer = 8
' Generate a random number for the size of the salt.
Dim random As Random
random = New Random()
Dim saltSize As Integer
saltSize = random.Next(minSaltSize, maxSaltSize)
' Allocate a byte array, which will hold the salt.
saltBytes = New Byte(saltSize - 1) {}
' Initialize a random number generator.
Dim rng As RNGCryptoServiceProvider
rng = New RNGCryptoServiceProvider()
' Fill the salt with cryptographically strong byte values.
rng.GetNonZeroBytes(saltBytes)
' Convert plain text into a byte array.
Return Convert.ToBase64String(saltBytes)
End Function
Public Shared Function ComputeHash(ByVal password As String, ByVal salt As String) As String
Return System.Web.Security.FormsAuthentication.HashPasswordForStoringInConfigFile(salt & password, _
System.Web.Configuration.FormsAuthPasswordFormat.SHA1.ToString)
End Function
Несмотря на то, что в пространстве имен членства есть материал, встроенный для этого, как указано в книге Forgotten Semicolon
Ответ 4
Прошло некоторое время с тех пор, как я возился с членством в ASP.Net, но помню, что имел дело с чем-то, что было связано с ним (необходимо настроить все из-за существующей базы данных пользователей). В этих усилиях я перепробовал методы (у существующего пользователя db были хешированные md5 pwds).
Итак, в той же "линии мысли":
Откройте API-интерфейс членства через веб-службу, которую может ссылаться ваше настольное приложение. Таким образом, вы не "воссоздаете" вещи, вы их повторно используете. Вам не нужно переопределять что-либо, вы просто просматриваете существующие методы через веб-службу для своего рабочего стола.
Идет, не говоря, что вам нужно будет закрепить эту конечную точку....
Если вышеприведенное слишком отрывочное для вашего вкуса, вот ссылка на форумы asp.net о некоторых попытках воссоздать хеширование.... Я не могу подтвердить точность, но это должно быть легко проверить
http://forums.asp.net/p/1336657/2899172.aspx