将身份用户从 .NET 4.5 MVC 项目迁移到 .NET 6 MVC 项目

Migrating identity users from .NET 4.5 MVC to .NET 6 MVC project

由于身份用户密码存在哈希差异,我们需要保留老用户而不强迫他们更新密码。所以我必须将散列更改为旧样式。我正在关注这个答案,但尽管 PasswordHasher 在服务容器中被替换,但新的哈希器并未被使用。

重现问题的步骤:

.NET 6 创建 ASP Core MVC 项目并选择 Individual Accounts 进行身份验证。更改 Program.cs 文件:

using Microsoft.AspNetCore.Identity;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection.Extensions;
using Proofs.Data;

var builder = WebApplication.CreateBuilder(args);

// Add services to the container.
var connectionString = builder.Configuration.GetConnectionString("DefaultConnection");
builder.Services.AddDbContext<ApplicationDbContext>(options =>
    options.UseSqlServer(connectionString));
builder.Services.AddDatabaseDeveloperPageExceptionFilter();

builder.Services.AddDefaultIdentity<IdentityUser>(options => options.SignIn.RequireConfirmedAccount = true)
    .AddEntityFrameworkStores<ApplicationDbContext>();
builder.Services.AddControllersWithViews();

var serviceDescriptor = builder.Services.FirstOrDefault(descriptor => descriptor.ServiceType == typeof(IPasswordHasher<IdentityUser>));
builder.Services.Remove(serviceDescriptor);
builder.Services.AddScoped<IPasswordHasher<IdentityUser>, OldMvcPasswordHasher>();

//builder.Services.Replace(new ServiceDescriptor(
//    serviceType: typeof(IPasswordHasher<IdentityUser>),
//    implementationType: typeof(OldMvcPasswordHasher),
//    ServiceLifetime.Scoped));

var app = builder.Build();

// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
    app.UseMigrationsEndPoint();
}
else
{
    app.UseExceptionHandler("/Home/Error");
    // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
    app.UseHsts();
}

app.UseHttpsRedirection();
app.UseStaticFiles();

app.UseRouting();

app.UseAuthentication();
app.UseAuthorization();

app.MapControllerRoute(
    name: "default",
    pattern: "{controller=Home}/{action=Index}/{id?}");
app.MapRazorPages();

app.Run();


public class OldMvcPasswordHasher : PasswordHasher<IdentityUser>
{
    public override PasswordVerificationResult VerifyHashedPassword(IdentityUser user, string hashedPassword, string providedPassword)
    {
        return PasswordVerificationResult.SuccessRehashNeeded;
    }
}

我尝试删除和添加新服务,也尝试替换服务,但是当我尝试登录时新的 VerifyHashedPassword 方法没有被调用。

在我的一个项目中,我将现有用户(使用我自己的自定义 tables)迁移到具有 .NET Core Identity 的 .NET 6 项目中。在 DataContext 中,我通过旧应用程序中的遗留哈希列扩展了我的用户 table。

每当用户尝试登录(使用电子邮件 + 密码)时,我都会检查遗留哈希列中是否仍有值。如果是这样的话,

  • 我根据旧的机制计算旧的哈希值,看看它们是否匹配
  • 如果它们匹配,我使用 .NET Core Identity 设置新密码(基于用户输入的内容。用户不知道我更改了底层哈希算法)。为此,我创建了一个 PasswordResetToken,然后使用 ResetPassword 功能。
  • 之后,我从用户行中删除旧哈希。

在您的情况下,只需按照适用于新用户的方式设置 .NET Core 身份。在登录方法期间注意迁移现有密码。