ASP.NET 成员资格身份验证从迁移到 ASP.NET Core 2.0 标识Migrate from ASP.NET Membership authentication to ASP.NET Core 2.0 Identity

本文内容

作者:Isaac Levin

本文演示如何迁移使用成员资格到 ASP.NET Core 2.0 标识的身份验证的 ASP.NET 应用程序的数据库架构。

备注

本文档提供将基于 ASP.NET 成员资格的应用程序的数据库架构迁移到用于 ASP.NET Core 标识的数据库架构所需的步骤。有关从基于 ASP.NET 成员身份的身份验证迁移到 ASP.NET Identity 的详细信息,请参阅将现有应用从 SQL 成员身份迁移到 ASP.NET Identity有关 ASP.NET Core 标识的详细信息,请参阅ASP.NET Core 上的标识简介

成员资格架构评审Review of Membership schema

在 ASP.NET 2.0 之前,开发人员负责为其应用创建整个身份验证和授权过程。使用 ASP.NET 2.0,引入了成员身份,提供了一个样本解决方案来处理 ASP.NET 应用中的安全性。开发人员现在可以使用aspnet_regsql的命令将架构启动到 SQL Server 数据库中。运行此命令后,将在数据库中创建以下表。

成员资格表

若要将现有应用迁移到 ASP.NET Core 2.0 标识,这些表中的数据需要迁移到使用新的标识架构的表。

ASP.NET Core 标识 2.0 架构ASP.NET Core Identity 2.0 schema

ASP.NET Core 2.0 遵循 ASP.NET 4.5 中引入的标识原则。尽管此原则是共享的,但在不同版本的 ASP.NET Core (请参阅将身份验证和标识迁移到 ASP.NET Core 2.0)之间的实现不同。

ASP.NET Core 2.0 标识查看架构的最快方法是创建新的 ASP.NET Core 2.0 应用程序。在 Visual Studio 2017 中执行以下步骤:

  • 选择“文件” “新建” “项目” > > 。

  • 创建一个名为CoreIdentitySample的新ASP.NET Core Web 应用程序项目。

  • 在下拉列表中选择ASP.NET Core 2.0 ,然后选择 " Web 应用程序"。此模板生成Razor Pages应用。单击 "确定" 之前,请单击 "更改身份验证"。

  • 为标识模板选择单个用户帐户。最后,单击 "确定",然后单击 "确定" 。Visual Studio 创建项目时使用 ASP.NET Core 标识模板。

  • 选择 "工具" > NuGet 包管理器" > 程序包管理器控制台" 打开 "包管理器控制台" (PMC)窗口。

  • 导航到 PMC 中的项目根,并运行实体框架(EF) Core Update-Database 命令。

ASP.NET Core 2.0 标识使用 EF Core 与存储身份验证数据的数据库进行交互。为了使新创建的应用程序正常工作,需要有数据库来存储此数据。创建新应用后,在数据库环境中检查架构的最快方法是使用EF Core 迁移来创建数据库。此过程将创建一个在本地或其他位置模拟该架构的数据库。有关详细信息,请查看前面的文档。

EF Core 命令使用appsettings中指定的数据库的连接字符串。以下连接字符串针对名为 .asp 的__localhost上的数据库。在此设置中,EF Core 配置为使用 DefaultConnection 连接字符串。

  1. {
  2. "ConnectionStrings": {
  3. "DefaultConnection": "Server=localhost;Database=aspnet-core-identity;Trusted_Connection=True;MultipleActiveResultSets=true"
  4. }
  5. }
  • 选择 "查看 > SQL Server 对象资源管理器。展开对应于appsettingsConnectionStrings:DefaultConnection 属性中指定的数据库名称的节点。

Update-Database 命令创建了用架构指定的数据库以及应用初始化所需的任何数据。下图描绘了在前面的步骤中创建的表结构。

标识表

迁移架构Migrate the schema

有细微的差别的表结构和成员身份和 ASP.NET Core 标识字段。模式已显著更改身份验证/授权与 ASP.NET 和 ASP.NET Core 应用程序。仍用于标识的关键对象是用户角色下面是用户角色UserRoles的映射表。

用户Users

标识(dbo)。AspNetUsers成员身份(dbo. aspnet_Users/dbo. aspnet_Membership)
字段名称类型字段名称类型
Id字符串aspnet_Users.UserId字符串
UserName字符串aspnet_Users.UserName字符串
Email字符串aspnet_Membership.Email字符串
NormalizedUserName字符串aspnet_Users.LoweredUserName字符串
NormalizedEmail字符串aspnet_Membership.LoweredEmail字符串
PhoneNumber字符串aspnet_Users.MobileAlias字符串
LockoutEnabledbitaspnet_Membership.IsLockedOutbit

备注

并非所有字段映射类似都于从成员资格到 ASP.NET Core 标识的一对一关系。前面的表使用默认成员资格用户架构,并将其映射到 ASP.NET Core 标识架构。需要手动映射用于成员身份的任何其他自定义字段。在此映射中,无密码映射,因为密码条件和密码 salts 不会在两者之间迁移。建议将密码保留为 null 并要求用户重置其密码。在 ASP.NET Core 标识中,如果用户被锁定,应将 LockoutEnd 设置为将来的某个日期。这会显示在迁移脚本中。

角色Roles

标识(dbo)。AspNetRoles)成员身份(dbo. aspnet_Roles)
字段名称类型字段名称类型
Id字符串RoleId字符串
Name字符串RoleName字符串
NormalizedName字符串LoweredRoleName字符串

用户角色User Roles

标识(dbo)。AspNetUserRoles成员身份(dbo. aspnet_UsersInRoles)
字段名称类型字段名称类型
RoleId字符串RoleId字符串
UserId字符串UserId字符串

创建用户角色的迁移脚本时引用前面的映射表。下面的示例假定数据库服务器上有两个数据库。一个数据库包含现有的 ASP.NET 成员身份架构和数据。使用前面所述的步骤创建了另一个CoreIdentitySample数据库。有关详细信息,请以内联方式包含注释。

  1. -- THIS SCRIPT NEEDS TO RUN FROM THE CONTEXT OF THE MEMBERSHIP DB
  2. BEGIN TRANSACTION MigrateUsersAndRoles
  3. USE aspnetdb
  4. -- INSERT USERS
  5. INSERT INTO CoreIdentitySample.dbo.AspNetUsers
  6. (Id,
  7. UserName,
  8. NormalizedUserName,
  9. PasswordHash,
  10. SecurityStamp,
  11. EmailConfirmed,
  12. PhoneNumber,
  13. PhoneNumberConfirmed,
  14. TwoFactorEnabled,
  15. LockoutEnd,
  16. LockoutEnabled,
  17. AccessFailedCount,
  18. Email,
  19. NormalizedEmail)
  20. SELECT aspnet_Users.UserId,
  21. aspnet_Users.UserName,
  22. -- The NormalizedUserName value is upper case in ASP.NET Core Identity
  23. UPPER(aspnet_Users.UserName),
  24. -- Creates an empty password since passwords don't map between the 2 schemas
  25. '',
  26. /*
  27. The SecurityStamp token is used to verify the state of an account and
  28. is subject to change at any time. It should be initialized as a new ID.
  29. */
  30. NewID(),
  31. /*
  32. EmailConfirmed is set when a new user is created and confirmed via email.
  33. Users must have this set during migration to reset passwords.
  34. */
  35. 1,
  36. aspnet_Users.MobileAlias,
  37. CASE
  38. WHEN aspnet_Users.MobileAlias IS NULL THEN 0
  39. ELSE 1
  40. END,
  41. -- 2FA likely wasn't setup in Membership for users, so setting as false.
  42. 0,
  43. CASE
  44. -- Setting lockout date to time in the future (1,000 years)
  45. WHEN aspnet_Membership.IsLockedOut = 1 THEN Dateadd(year, 1000,
  46. Sysutcdatetime())
  47. ELSE NULL
  48. END,
  49. aspnet_Membership.IsLockedOut,
  50. /*
  51. AccessFailedAccount is used to track failed logins. This is stored in
  52. Membership in multiple columns. Setting to 0 arbitrarily.
  53. */
  54. 0,
  55. aspnet_Membership.Email,
  56. -- The NormalizedEmail value is upper case in ASP.NET Core Identity
  57. UPPER(aspnet_Membership.Email)
  58. FROM aspnet_Users
  59. LEFT OUTER JOIN aspnet_Membership
  60. ON aspnet_Membership.ApplicationId =
  61. aspnet_Users.ApplicationId
  62. AND aspnet_Users.UserId = aspnet_Membership.UserId
  63. LEFT OUTER JOIN CoreIdentitySample.dbo.AspNetUsers
  64. ON aspnet_Membership.UserId = AspNetUsers.Id
  65. WHERE AspNetUsers.Id IS NULL
  66. -- INSERT ROLES
  67. INSERT INTO CoreIdentitySample.dbo.AspNetRoles(Id, Name)
  68. SELECT RoleId, RoleName
  69. FROM aspnet_Roles;
  70. -- INSERT USER ROLES
  71. INSERT INTO CoreIdentitySample.dbo.AspNetUserRoles(UserId, RoleId)
  72. SELECT UserId, RoleId
  73. FROM aspnet_UsersInRoles;
  74. IF @@ERROR <> 0
  75. BEGIN
  76. ROLLBACK TRANSACTION MigrateUsersAndRoles
  77. RETURN
  78. END
  79. COMMIT TRANSACTION MigrateUsersAndRoles

完成上述脚本后,将向成员资格用户填充先前创建的 ASP.NET Core 标识应用。用户需要在登录之前更改密码。

备注

如果成员资格系统中的用户的用户名与其电子邮件地址不匹配,则需要对之前创建的应用进行更改,以满足此要求。默认模板要求 UserNameEmail 相同。对于它们不同的情况,需要将登录过程修改为使用 UserName 而不是 Email

在登录页的 PageModel,位于Pages\Account\Login.cshtml.cs,从Email属性中删除 [EmailAddress] 属性。将其重命名为UserName这需要在视图PageModelEmailAddress 提到的任何位置进行更改。结果应类似如下所示:

固定登录

后续步骤Next steps

在本教程中,您学习了如何移植到 ASP.NET Core 2.0 标识从 SQL 成员资格用户。有关 ASP.NET Core 标识的详细信息,请参阅标识简介