将现有用户从 MVC 4 SimpleMembership 迁移到 MVC 5 ASP.NET Identity
本文关键字:MVC ASP Identity NET 迁移 用户 SimpleMembership | 更新日期: 2023-09-27 18:37:26
我有一个目前实现SimpleMember的MVC 4站点。在网站的下一次迭代中,我想升级到MVC 5并 ASP.NET Identity。这两个站点在 web.config 中具有相同的计算机密钥。SimpleMembership SQL 表有一个用于 Password 和PaswordSalt 的列,ASP.NET Identity 表有一个用于PasswordHash
的列,这似乎是 Password + PasswordSalt 的组合。
我尝试从旧站点将密码和密码板条连接在一起,但这不起作用。
我的问题是,
如何将现有用户的密码从旧站点迁移到新站点?
根据 http://www.asp.net/identity/overview/migrations/migrating-an-existing-website-from-sql-membership-to-aspnet-identity
:应用程序用户的密码被加密并存储在数据库中。SQL 成员身份中使用的加密算法与新标识系统中的加密算法不同。要重用旧密码,我们需要在老用户使用 SQL 成员资格算法登录时有选择地解密密码,同时在新用户的 Identity 中使用加密算法。
UserManager 类有一个属性"PasswordHasher",它存储实现"IPasswordHasher"接口的类的实例。这用于在用户身份验证事务期间加密/解密密码。在步骤 3 中定义的 UserManager 类中,创建一个新类 SQLPasswordHasher 并复制以下代码。
因此,您必须使用以下代码创建新的哈希器类:
public class SQLPasswordHasher : PasswordHasher
{
public override string HashPassword(string password)
{
return base.HashPassword(password);
}
public override PasswordVerificationResult VerifyHashedPassword(string hashedPassword, string providedPassword)
{
string[] passwordProperties = hashedPassword.Split('|');
if (passwordProperties.Length != 3)
{
return base.VerifyHashedPassword(hashedPassword, providedPassword);
}
else
{
string passwordHash = passwordProperties[0];
int passwordformat = 1;
string salt = passwordProperties[2];
if (String.Equals(EncryptPassword(providedPassword, passwordformat, salt), passwordHash, StringComparison.CurrentCultureIgnoreCase))
{
return PasswordVerificationResult.SuccessRehashNeeded;
}
else
{
return PasswordVerificationResult.Failed;
}
}
}
//This is copied from the existing SQL providers and is provided only for back-compat.
private string EncryptPassword(string pass, int passwordFormat, string salt)
{
if (passwordFormat == 0) // MembershipPasswordFormat.Clear
return pass;
byte[] bIn = Encoding.Unicode.GetBytes(pass);
byte[] bSalt = Convert.FromBase64String(salt);
byte[] bRet = null;
if (passwordFormat == 1)
{ // MembershipPasswordFormat.Hashed
HashAlgorithm hm = HashAlgorithm.Create("SHA1");
if (hm is KeyedHashAlgorithm)
{
KeyedHashAlgorithm kha = (KeyedHashAlgorithm)hm;
if (kha.Key.Length == bSalt.Length)
{
kha.Key = bSalt;
}
else if (kha.Key.Length < bSalt.Length)
{
byte[] bKey = new byte[kha.Key.Length];
Buffer.BlockCopy(bSalt, 0, bKey, 0, bKey.Length);
kha.Key = bKey;
}
else
{
byte[] bKey = new byte[kha.Key.Length];
for (int iter = 0; iter < bKey.Length; )
{
int len = Math.Min(bSalt.Length, bKey.Length - iter);
Buffer.BlockCopy(bSalt, 0, bKey, iter, len);
iter += len;
}
kha.Key = bKey;
}
bRet = kha.ComputeHash(bIn);
}
else
{
byte[] bAll = new byte[bSalt.Length + bIn.Length];
Buffer.BlockCopy(bSalt, 0, bAll, 0, bSalt.Length);
Buffer.BlockCopy(bIn, 0, bAll, bSalt.Length, bIn.Length);
bRet = hm.ComputeHash(bAll);
}
}
return Convert.ToBase64String(bRet);
}
然后在您的 Identity UserManager 类中声明一个构造器以使用此哈希器,例如:
public UserManager()
: base(new UserStore<User>(new ApplicationDbContext()))
{
this.PasswordHasher = new SQLPasswordHasher();
}
在以下链接中说明:http://kevin-junghans.blogspot.com/2014/02/migrating-existing-website-from.html
public class SimplePasswordHasher : IPasswordHasher
{
public string HashPassword(string password)
{
return Crypto.HashPassword(password);
}
public PasswordVerificationResult VerifyHashedPassword(string hashedPassword, string providedPassword)
{
if(Crypto.VerifyHashedPassword(hashedPassword, providedPassword))
return PasswordVerificationResult.Success;
else return PasswordVerificationResult.Failed;
}
}