使用Identity 2.0数据库来验证ASP.NET Core 1.0应用程序

use*_*717 11 c# asp.net asp.net-identity asp.net-core-1.0

我正在尝试创建一个新的ASP.NET Core 1.0 Web应用程序,我希望它使用我已经设置的身份验证表.这些表最初是由使用Microsoft.ASPNet.Identity.EntityFramework 2.2.0的ASP.NET 4.6 Web应用程序创建的.

看起来Microsoft.AspNetCore.Identity.EntityFrameworkCore中的内容发生了变化,因为新的Core 1.0应用程序在尝试登录时抛出此错误:

处理请求时数据库操作失败.

SqlException:无效的列名称'NormalizedUserName'.列名称'ConcurrencyStamp'无效.列名称"LockoutEnd"无效.列名称"NormalizedEmail"无效.列名称"NormalizedUserName"无效.

project.json是开箱即用的,看起来像这样:

"dependencies": {
"Microsoft.NETCore.App": {
  "version": "1.0.0",
  "type": "platform"
},
"Microsoft.AspNetCore.Authentication.Cookies": "1.0.0",
"Microsoft.AspNetCore.Diagnostics": "1.0.0",
"Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore": "1.0.0",
"Microsoft.AspNetCore.Identity.EntityFrameworkCore": "1.0.0",
"Microsoft.AspNetCore.Mvc": "1.0.0",
"Microsoft.AspNetCore.Razor.Tools": {
  "version": "1.0.0-preview2-final",
  "type": "build"
},
"Microsoft.AspNetCore.Server.IISIntegration": "1.0.0",
"Microsoft.AspNetCore.Server.Kestrel": "1.0.0",
"Microsoft.AspNetCore.StaticFiles": "1.0.0",
"Microsoft.EntityFrameworkCore.SqlServer": "1.0.0",
"Microsoft.EntityFrameworkCore.SqlServer.Design": {
  "version": "1.0.0",
  "type": "build"
},
"Microsoft.EntityFrameworkCore.Tools": {
  "version": "1.0.0-preview2-final",
  "type": "build"
},
"Microsoft.Extensions.Configuration.EnvironmentVariables": "1.0.0",
"Microsoft.Extensions.Configuration.Json": "1.0.0",
"Microsoft.Extensions.Configuration.UserSecrets": "1.0.0",
"Microsoft.Extensions.Logging": "1.0.0",
"Microsoft.Extensions.Logging.Console": "1.0.0",
"Microsoft.Extensions.Logging.Debug": "1.0.0",
"Microsoft.Extensions.Options.ConfigurationExtensions": "1.0.0",
"Microsoft.VisualStudio.Web.BrowserLink.Loader": "14.0.0",
"Microsoft.VisualStudio.Web.CodeGeneration.Tools": {
  "version": "1.0.0-preview2-final",
  "type": "build"
},
"Microsoft.VisualStudio.Web.CodeGenerators.Mvc": {
  "version": "1.0.0-preview2-final",
  "type": "build"
}
Run Code Online (Sandbox Code Playgroud)

},

另外,我没有更改我的ApplicationDbContext,但是我看到一些关于在该类中进行更改以解决此问题的帖子

War*_*son 14

这个SQL迁移脚本让我克服了上述障碍:

Alter Table ASPNETROLES
ADD
 ConcurrencyStamp varchar(255) null,               
 NormalizedName varchar(255) null

 Drop Table AspNetUserTokens

 CREATE TABLE [AspNetUserTokens] (
    [UserId]        NVARCHAR (450) NOT NULL,
    [LoginProvider] NVARCHAR (450) NOT NULL,
    [Name]          NVARCHAR (450) NOT NULL,
    [Value]         NVARCHAR (MAX) NULL,
    CONSTRAINT [PK_AspNetUserTokens]
 PRIMARY KEY CLUSTERED ([UserId] ASC, [LoginProvider] ASC, [Name] ASC)
)

Alter Table AspNetUsers
 Add
 ConcurrencyStamp varchar(255) null,
 LockoutEnd DateTime null,
 NormalizedEmail varchar(255) null,
 NormalizedUserName varchar(255) null

Drop Table [AspNetRoleClaims]

CREATE TABLE [AspNetRoleClaims] (
    [Id]         INT            IDENTITY (1, 1) NOT NULL,
    [ClaimType]  NVARCHAR (MAX) NULL,
    [ClaimValue] NVARCHAR (MAX) NULL,
    [RoleId]     NVARCHAR (128) NOT NULL,
    CONSTRAINT [PK_AspNetRoleClaims]
 PRIMARY KEY CLUSTERED ([Id] ASC),
    CONSTRAINT [FK_AspNetRoleClaims_AspNetRoles_RoleId]
 FOREIGN KEY ([RoleId])
  REFERENCES [dbo].[AspNetRoles] ([Id]) ON DELETE CASCADE
)


GO
CREATE NONCLUSTERED INDEX [IX_AspNetRoleClaims_RoleId]
    ON [AspNetRoleClaims]([RoleId] ASC)

Alter Table AspNetUserLogins
   Add  ProviderDisplayName varchar(255) null
Run Code Online (Sandbox Code Playgroud)

微软没有就如何迁移数据库提供大量指导,但这为我解决了上述问题.

  • 您是否继续在“旧”应用程序中使用此数据库?这就是我需要能够做到的。我看到您的脚本也没有更新规范化值。你不需要这样做吗,或者 Core 足够聪明来更新它们 (2认同)

Sim*_*ver 6

有一个包可以做到这一点。从字面上看,它就是为了这个目的。它是 Microsoft 代码库的一部分,最近似乎已针对 Core 2.1 进行了更新。

用于在 Microsoft.AspNet.Identity.EntityFramework 和 Microsoft.AspNetCore.Identity.EntityFrameworkCore 之间共享身份数据库的兼容层。

https://www.nuget.org/packages/Microsoft.AspNet.Identity.AspNetCoreCompat/

https://github.com/aspnet/Identity/tree/master/src/AspNetCoreCompat

它使用如下方法处理两个模式之间的“差异”:

    /// <summary>
    ///     Normalized email
    /// </summary>
    public string NormalizedEmail {
        get
        {
            return Email.ToUpperInvariant();
        }
        set { }
    }

    /// <summary>
    ///     Concurrency stamp
    /// </summary>
    public virtual string ConcurrencyStamp { get; set; } = Guid.NewGuid().ToString();
Run Code Online (Sandbox Code Playgroud)

我找不到任何真正的文档,但我已经完成了以下操作,并且似乎工作正常:

  • 您在旧网站(.NET 4.6)中安装兼容性包
  • 您必须将所有对IdentityRoleIdentityUser等的引用更改IdentityDbContext为兼容性包中的类。

    using Compat = Microsoft.AspNet.Identity.CoreCompat;
    
    // update to use the compatibility class
    public class ApplicationDbContext : Compat.IdentityDbContext<ApplicationUser>
    
    // change all instances, such as this
    Compat.IdentityUser user = await _repo.FindUser(context.UserName, context.Password);  
    
    Run Code Online (Sandbox Code Playgroud)
  • 您必须将数据库升级到新格式(基本上是添加一些列并更改一些数据类型)。这是最棘手的阶段!您肯定希望在临时环境中执行此操作。我使用的是 Azure,所以我只是克隆了数据库。

  • 在 GitHub 上,我发现了一些由@samnpathdr 编写的名为 的Migration.zip迁移脚本。有几个脚本需要一一运行。我建议一次运行每个命令,以确保它全部运行。
  • 目前,他的脚本中有一个表是对其实现自定义的 (AspNetUserRolePermissions),因此请删除对该表的引用。
  • 如果有任何其他表引用该AspNetUsers表,则必须删除约束、更新数据类型并重新添加约束。例如,我有一个Notes链接到 a 的表AspNetUser,因此我需要运行ALTER TABLE UserProfileNote ALTER COLUMN AspNetUsersId nvarchar(450) NOT NULL;(删除约束后)。首先编写约束脚本!
  • 如果您为核心启用了任何“自动迁移”,请小心,因为我个人在这种更改后不会信任它们。您应该重置到基线,或者根本不进行 EF 迁移。

https://github.com/aspnet/Docs/issues/6425