Dela via


Migrera från ASP.NET-medlemskapsautentisering till ASP.NET Core 2.0 Identity

Av Isaac Levin

Den här artikeln visar hur du migrerar databasschemat för ASP.NET-appar som använder medlemskapsautentisering till ASP.NET Core 2.0 Identity.

Anmärkning

Det här dokumentet innehåller de steg som krävs för att migrera databasschemat för ASP.NET medlemskapsbaserade appar till databasschemat som används för ASP.NET Core Identity. Mer information om hur du migrerar från ASP.NET medlemskapsbaserad autentisering till ASP.NET Identityfinns i Migrera en befintlig app från SQL-medlemskap till ASP.NET Identity. Mer information om ASP.NET Core Identityfinns i Introduktion till Identity på ASP.NET Core.

Granskning av medlemskapsschema

Innan ASP.NET 2.0 fick utvecklarna i uppgift att skapa hela autentiserings- och auktoriseringsprocessen för sina appar. Med ASP.NET 2.0 introducerades Medlemskap, vilket ger en lösning för hantering av säkerhet i ASP.NET appar. Utvecklare kunde nu starta ett schema i en SQL Server-databas med ASP.NET SQL Server Registration Tool () (Aspnet_regsql.exestöds inte längre). När du har kört det här kommandot skapades följande tabeller i databasen.

Medlemskapstabeller

Om du vill migrera befintliga appar till ASP.NET Core 2.0 Identitymåste data i dessa tabeller migreras till de tabeller som används av det nya Identity schemat.

ASP.NET Core Identity 2.0-schema

ASP.NET Core 2.0 följer principen Identity som infördes i ASP.NET 4.5. Även om principen delas skiljer sig implementeringen mellan ramverken, även mellan versioner av ASP.NET Core (se Migrera autentisering och Identity till ASP.NET Core 2.0).

Det snabbaste sättet att visa schemat för ASP.NET Core 2.0 Identity är att skapa en ny ASP.NET Core 2.0-app. Följ dessa steg i Visual Studio 2017:

  1. Välj Arkiv>Nytt>Projekt.

  2. Skapa ett nytt ASP.NET Core Web Application-projekt med namnet CoreIdentitySample.

  3. Välj ASP.NET Core 2.0 i listrutan och välj sedan Webbprogram. Den här mallen skapar en Razor Pages-app . Innan du klickar på OK klickar du på Ändra autentisering.

  4. Välj Enskilda användarkonton för mallarna Identity . Klicka slutligen på OK och sedan på OK. Visual Studio skapar ett projekt med hjälp av mallen ASP.NET Core Identity .

  5. Välj Verktyg>NuGet-pakethanterare>Pakethanterare-konsol för att öppna fönstret Package Manager Console (PMC).

  6. Navigera till projektroten i PMC och kör kommandot Entity Framework (EF) CoreUpdate-Database .

    ASP.NET Core 2.0 Identity används EF Core för att interagera med databasen som lagrar autentiseringsdata. För att den nyligen skapade appen ska fungera måste det finnas en databas för att lagra dessa data. När du har skapat en ny app är det snabbaste sättet att inspektera schemat i en databasmiljö att skapa databasen med hjälp av EF Core migreringar. Den här processen skapar en databas, antingen lokalt eller någon annanstans, som efterliknar schemat. Mer information finns i föregående dokumentation.

    EF Core kommandon använder anslutningssträngen för databasen som anges i appsettings.json. Följande anslutningssträng riktar sig mot en databas på localhost med namnet asp-net-core-identity. I den här inställningen EF Core är konfigurerad att använda anslutningssträngen DefaultConnection .

    {
      "ConnectionStrings": {
        "DefaultConnection": "Server=localhost;Database=aspnet-core-identity;Trusted_Connection=True;MultipleActiveResultSets=true"
      }
    }
    

Varning

Den här artikeln visar användningen av anslutningssträngar. Med en lokal databas behöver användaren inte autentiseras, men i produktion innehåller anslutningssträngar ibland ett lösenord för att autentisera. En resursägares lösenordsautentiseringsuppgifter (ROPC) är en säkerhetsrisk som bör undvikas i produktionsdatabaser. Produktionsappar bör använda det säkraste tillgängliga autentiseringsflödet. Mer information om autentisering för appar som distribueras till test- eller produktionsmiljöer finns i Säkra autentiseringsflöden.

  1. Välj Visa>SQL Server Object Explorer. Expandera noden som motsvarar databasnamnet som anges i ConnectionStrings:DefaultConnection egenskapen appsettings.json.

    Kommandot Update-Database skapade databasen som angetts med schemat och alla data som behövs för appinitiering. Följande bild visar tabellstrukturen som skapas med föregående steg.

    Identity Tabeller

Migrera schemat

Det finns subtila skillnader i tabellstrukturer och fält för både Medlemskap och ASP.NET Core Identity. Mönstret har ändrats avsevärt för autentisering/auktorisering med ASP.NET och ASP.NET Core-appar. De viktigaste objekten som fortfarande används med Identity är Användare och roller. Här är mappningstabeller för Användare, Roller och UserRoles.

Användare

Identity
(dbo.AspNetUsers) kolumn
Typ Medlemskap
(dbo.aspnet_Users / dbo.aspnet_Membership) kolumn
Typ
Id string aspnet_Users.UserId string
UserName string aspnet_Users.UserName string
Email string aspnet_Membership.Email string
NormalizedUserName string aspnet_Users.LoweredUserName string
NormalizedEmail string aspnet_Membership.LoweredEmail string
PhoneNumber string aspnet_Users.MobileAlias string
LockoutEnabled bit aspnet_Membership.IsLockedOut bit

IsLockedOut mappas inte till LockoutEnabled. IsLockedOut anges om en användare hade för många misslyckade inloggningar och är utelåst under en viss tid. LockoutEnabled aktiverar låsning av en användare med för många misslyckade inloggningsförsök. När användaren har för många misslyckade inloggningsförsök LockoutEnd anges det till ett datum i framtiden och användaren kan inte logga in förrän det datumet. Om LockoutEnabled är falskt blir en användare aldrig utelåst för för många misslyckade inloggningsförsök. Per OWASPär tillfällig kontoutelåsning efter flera misslyckade försök för enkelt mål för DoS-attacker mot legitima användare.

Mer information om utelåsning finns i OWASP-testning för mekanismen för svag utelåsning.

Appar som migrerar till Identity och som vill aktivera uteslutning vid misslyckat inloggningsförsök bör sätta LockoutEnabled till true som en del av migreringen.

Anmärkning

Alla fältmappningar liknar inte en-till-en-relationer från Medlemskap till ASP.NET Core Identity. Tabellen ovan tar standardschemat för medlemskapsanvändare och mappar det till ASP.NET Core-schemat Identity . Alla andra anpassade fält som användes för Medlemskap måste mappas manuellt. I den här mappningen finns det ingen karta för lösenord eftersom både lösenordskriterier och lösenordssalter inte migreras mellan de två. Vi rekommenderar att du lämnar lösenordet som null och ber användarna att återställa sina lösenord. I ASP.NET Core IdentityLockoutEnd ska anges till något datum i framtiden om användaren är utelåst. Detta visas i migreringsskriptet.

Roller

Identity
(dbo.AspNetRoles) kolumn
Typ Medlemskap
(dbo.aspnet_Roles) kolumn
Typ
Id string RoleId string
Name string RoleName string
NormalizedName string LoweredRoleName string

Användarroller

Identity
(dbo.AspNetUserRoles) kolumn
Typ Medlemskap
(dbo.aspnet_UsersInRoles) kolumn
Typ
RoleId string RoleId string
UserId string UserId string

Referera till föregående mappningstabeller när du skapar ett migreringsskript för användare och roller. I följande exempel förutsätts att du har två databaser på en databasserver. En databas innehåller det befintliga ASP.NET Medlemskapsschema och data. Den andra CoreIdentitySample-databasen skapades med hjälp av stegen som beskrevs tidigare. Kommentarer är inkluderade inline för mer detaljer.

-- THIS SCRIPT NEEDS TO RUN FROM THE CONTEXT OF THE MEMBERSHIP DB
BEGIN TRANSACTION MigrateUsersAndRoles
USE aspnetdb

-- INSERT USERS
INSERT INTO CoreIdentitySample.dbo.AspNetUsers
            (Id,
             UserName,
             NormalizedUserName,
             PasswordHash,
             SecurityStamp,
             EmailConfirmed,
             PhoneNumber,
             PhoneNumberConfirmed,
             TwoFactorEnabled,
             LockoutEnd,
             LockoutEnabled,
             AccessFailedCount,
             Email,
             NormalizedEmail)
SELECT aspnet_Users.UserId,
       aspnet_Users.UserName,
       -- The NormalizedUserName value is upper case in ASP.NET Core Identity
       UPPER(aspnet_Users.UserName),
       -- Creates an empty password since passwords don't map between the 2 schemas
       '',
       /*
        The SecurityStamp token is used to verify the state of an account and
        is subject to change at any time. It should be initialized as a new ID.
       */
       NewID(),
       /*
        EmailConfirmed is set when a new user is created and confirmed via email.
        Users must have this set during migration to reset passwords.
       */
       1,
       aspnet_Users.MobileAlias,
       CASE
         WHEN aspnet_Users.MobileAlias IS NULL THEN 0
         ELSE 1
       END,
       -- 2FA likely wasn't setup in Membership for users, so setting as false.
       0,
       CASE
         -- Setting lockout date to time in the future (1,000 years)
         WHEN aspnet_Membership.IsLockedOut = 1 THEN Dateadd(year, 1000,
                                                     Sysutcdatetime())
         ELSE NULL
       END,
       aspnet_Membership.IsLockedOut,
       /*
        AccessFailedAccount is used to track failed logins. This is stored in
        Membership in multiple columns. Setting to 0 arbitrarily.
       */
       0,
       aspnet_Membership.Email,
       -- The NormalizedEmail value is upper case in ASP.NET Core Identity
       UPPER(aspnet_Membership.Email)
FROM   aspnet_Users
       LEFT OUTER JOIN aspnet_Membership
                    ON aspnet_Membership.ApplicationId =
                       aspnet_Users.ApplicationId
                       AND aspnet_Users.UserId = aspnet_Membership.UserId
       LEFT OUTER JOIN CoreIdentitySample.dbo.AspNetUsers
                    ON aspnet_Membership.UserId = AspNetUsers.Id
WHERE  AspNetUsers.Id IS NULL

-- INSERT ROLES
INSERT INTO CoreIdentitySample.dbo.AspNetRoles(Id, Name)
SELECT RoleId, RoleName
FROM aspnet_Roles;

-- INSERT USER ROLES
INSERT INTO CoreIdentitySample.dbo.AspNetUserRoles(UserId, RoleId)
SELECT UserId, RoleId
FROM aspnet_UsersInRoles;

IF @@ERROR <> 0
  BEGIN
    ROLLBACK TRANSACTION MigrateUsersAndRoles
    RETURN
  END

COMMIT TRANSACTION MigrateUsersAndRoles

När det föregående skriptet har slutförts fylls ASP.NET Core-appen Identity som skapades tidigare med medlemskapsanvändare. Användarna måste ändra sina lösenord innan de loggar in.

Anmärkning

Om medlemskapssystemet hade användare med användarnamn som inte matchade deras e-postadress, krävs ändringar i appen som skapades tidigare för att hantera detta. Standardmallen förväntar sig UserName och Email kommer att vara densamma. För situationer där de skiljer sig måste inloggningsprocessen ändras så att den används UserName i stället för Email.

På inloggningssidan PageModel , som finns på , tar du bort [EmailAddress] attributet från egenskapen E-post . Byt namn på den till UserName. Detta kräver en ändring oavsett var EmailAddress som anges, i Visa och PageModel. Resultatet ser ut så här:

Åtgärdad inloggning

Nästa steg

I den här självstudien har du lärt dig hur du porterar användare från SQL-medlemskap till ASP.NET Core 2.0 Identity. Mer information om ASP.NET Core Identityfinns i Introduktion till Identity.