Migrace stávajícího webu z členství SQL na ASP.NET Identity
Tento kurz ukazuje postup migrace existující webové aplikace s uživatelskými daty a daty rolí vytvořenými pomocí členství SQL do nového systému identit ASP.NET. Tento přístup zahrnuje změnu existujícího schématu databáze na schéma, které vyžaduje identita ASP.NET, a připojit k němu staré nebo nové třídy. Po přijetí tohoto přístupu se po migraci databáze budou budoucí aktualizace identity zpracovávat bez problémů.
V tomto kurzu použijeme šablonu webové aplikace (Web Forms) vytvořenou pomocí sady Visual Studio 2010 k vytvoření dat uživatelů a rolí. Pak použijeme skripty SQL k migraci stávající databáze do tabulek, které potřebuje systém identit. Dále nainstalujeme potřebné balíčky NuGet a přidáme nové stránky pro správu účtů, které pro správu členství používají systém identit. Jako test migrace by se uživatelé vytvořené pomocí členství SQL měli mít možnost přihlásit a noví uživatelé by se měli mít možnost zaregistrovat. Kompletní ukázku najdete tady. Viz také Migrace z členství ASP.NET na ASP.NET Identity.
Začínáme
Vytvoření aplikace s členstvím SQL
Musíme začít s existující aplikací, která používá členství SQL a má data o uživatelích a rolích. Pro účely tohoto článku vytvoříme webovou aplikaci v sadě Visual Studio 2010.
Pomocí nástroje ASP.NET Configuration vytvořte 2 uživatele: oldAdminUser a oldUser.
Vytvořte roli s názvem Správa a přidejte do této role uživatele oldAdminUser.
Vytvořte Správa oddíl webu pomocí souboru Default.aspx. Nastavte autorizační značku v souboru web.config tak, aby povolte přístup jenom uživatelům ve Správa rolích. Další informace najdete tady. https://www.asp.net/web-forms/tutorials/security/roles/role-based-authorization-cs
Zobrazte databázi v Průzkumníku serveru a seznamte se s tabulkami vytvořenými systémem členství SQL. Přihlašovací data uživatele jsou uložená v tabulkách aspnet_Users a aspnet_Membership, zatímco data rolí jsou uložená v tabulce aspnet_Roles. Informace o tom, kteří uživatelé jsou ve kterých rolích jsou uloženy v tabulce aspnet_UsersInRoles. Pro základní správu členství stačí přenést informace z výše uvedených tabulek do systému ASP.NET Identity.
Migrace na Visual Studio 2013
Nainstalujte Visual Studio Express 2013 pro web nebo Visual Studio 2013 spolu s nejnovějšími aktualizacemi.
Otevřete výše uvedený projekt v nainstalované verzi sady Visual Studio. Pokud SQL Server Express není na počítači nainstalovaný, zobrazí se při otevření projektu výzva, protože připojovací řetězec používá SQL Express. Můžete buď nainstalovat SQL Express, nebo při řešení změnit připojovací řetězec na LocalDb. V tomto článku ho změníme na LocalDb.
Otevřete web.config a změňte připojovací řetězec z . SQLExpress na (LocalDb)v11.0. Odeberte z připojovacího řetězce user instance=true.
Otevřete Průzkumníka serveru a ověřte, že je možné sledovat schéma a data tabulky.
Systém identit ASP.NET funguje s architekturou verze 4.5 nebo vyšší. Změna cílení aplikace na verzi 4.5 nebo vyšší
Sestavte projekt a ověřte, že nedošlo k žádným chybám.
Instalace balíčků NuGet
V Průzkumník řešení klikněte pravým tlačítkem na projekt >Spravovat balíčky NuGet. Do vyhledávacího pole zadejte "Asp.net Identita". V seznamu výsledků vyberte balíček a klikněte na nainstalovat. Přijměte licenční smlouvu kliknutím na tlačítko Přijmout. Všimněte si, že tento balíček nainstaluje balíčky závislostí: EntityFramework a Microsoft ASP.NET Identity Core. Podobně nainstalujte následující balíčky (pokud nechcete povolit přihlášení OAuth, přeskočte poslední 4 balíčky OWIN):
Microsoft.AspNet.Identity.Owin
Microsoft.Owin.Host.SystemWeb
Microsoft.Owin.Security.Facebook
Microsoft.Owin.Security.Google
Microsoft.Owin.Security.MicrosoftAccount
Microsoft.Owin.Security.Twitter
Migrace databáze do nového systému identit
Dalším krokem je migrace existující databáze do schématu požadovaného systémem ASP.NET Identity. Abychom toho dosáhli, spustíme skript SQL, který obsahuje sadu příkazů pro vytváření nových tabulek a migraci existujících uživatelských informací do nových tabulek. Soubor skriptu najdete tady.
Tento soubor skriptu je specifický pro tuto ukázku. Pokud je schéma pro tabulky vytvořené pomocí členství SQL přizpůsobeno nebo změněno, je potřeba odpovídajícím způsobem změnit skripty.
Jak vygenerovat skript SQL pro migraci schématu
Aby třídy identity ASP.NET fungovaly s daty stávajících uživatelů, musíme migrovat schéma databáze do schématu, které potřebuje ASP.NET Identity. Můžeme to udělat přidáním nových tabulek a zkopírováním existujících informací do těchto tabulek. Ve výchozím nastavení ASP.NET Identity používá EntityFramework k mapování tříd modelu identit zpět do databáze pro ukládání nebo načítání informací. Tyto třídy modelu implementují základní rozhraní identity definující objekty uživatelů a rolí. Tabulky a sloupce v databázi jsou založené na těchto třídách modelu. Třídy modelu EntityFramework ve službě Identity v2.1.0 a jejich vlastnosti jsou definované níže.
IdentityUser | Typ | Role identity | IdentitaUserRole | IdentityUserLogin | IdentityUserClaim |
---|---|---|---|---|---|
Id | řetězec | Id | Id role | ProviderKey | Id |
Uživatelské jméno | řetězec | Název | UserId | UserId | Typ deklarace identity |
PasswordHash (Hodnota hash hesla) | řetězec | LoginProvider | Deklarace identity | ||
SecurityStamp | řetězec | User_id | |||
řetězec | |||||
Potvrzení e-mailu | bool | ||||
PhoneNumber | řetězec | ||||
PhoneNumberConfirmed | bool | ||||
LockoutEnabled | bool | ||||
LockoutEndDate | DateTime | ||||
AccessFailedCount | int |
Pro každý z těchto modelů musíme mít tabulky se sloupci odpovídajícími vlastnostem. Mapování mezi třídami a tabulkami je definováno OnModelCreating
v metodě objektu IdentityDBContext
. To se označuje jako metoda konfigurace fluent API a další informace najdete tady. Konfigurace pro třídy je, jak je uvedeno níže.
Třída | Tabulka | Primární klíč | Cizí klíč |
---|---|---|---|
IdentityUser | AspnetUsers | Id | |
Role identity | Role aspnet | Id | |
IdentitaRole uživatele | Role uživatele aspnetu | UserId + RoleId | User_Id-AspnetUsers> RoleId-AspnetRoles> |
IdentityUserLogin | AspnetUserLogins | ProviderKey+UserId+ LoginProvider | UserId-AspnetUsers> |
IdentityUserClaim | AspnetUserClaims | Id | User_Id-AspnetUsers> |
Pomocí těchto informací můžeme vytvořit příkazy SQL pro vytvoření nových tabulek. Každý příkaz můžeme napsat zvlášť nebo vygenerovat celý skript pomocí příkazů PowerShellu EntityFramework, které pak můžeme podle potřeby upravit. Uděláte to tak, že v sadě Visual Studio otevřete konzolu Správce balíčků z nabídky Zobrazení nebo Nástroje .
- Spuštěním příkazu Enable-Migrations povolte migrace EntityFramework.
- Spusťte příkaz Add-migration initial, který vytvoří počáteční instalační kód pro vytvoření databáze v C#/VB.
- Posledním krokem je spuštění příkazu Update-Database –Script, který vygeneruje skript SQL na základě tříd modelu.
Některé příkazy nejsou podporované, pokud aplikace jako úložiště dat identity používá SQLite. Kvůli omezením databázového stroje
Alter
vyvolají příkazy následující výjimku:System.NotSupportedException: SQLite nepodporuje tuto operaci migrace.
Obejdete to tak, že v databázi spustíte migrace Code First a změníte tabulky.
Tento skript pro generování databáze je možné použít jako začátek, kdy provedeme další změny pro přidání nových sloupců a kopírování dat. Výhodou je, že vygenerujeme _MigrationHistory
tabulku, kterou EntityFramework používá k úpravě schématu databáze při změně tříd modelu pro budoucí verze verzí identity.
Informace o uživatelích členství SQL měly kromě vlastností ve třídě modelu uživatele Identity i další vlastnosti: e-mail, pokusy o heslo, datum posledního přihlášení, datum posledního uzamčení atd. Jedná se o užitečné informace a chtěli bychom, aby se přenášely do systému identit. Můžete to provést přidáním dalších vlastností do modelu uživatele a jejich namapováním zpět na sloupce tabulky v databázi. Můžeme to udělat přidáním třídy, která model podtřídy IdentityUser
. Do této vlastní třídy můžeme přidat vlastnosti a úpravou skriptu SQL přidat odpovídající sloupce při vytváření tabulky. Kód pro tuto třídu je popsán dále v článku. Skript SQL pro vytvoření AspnetUsers
tabulky po přidání nových vlastností by byl
CREATE TABLE [dbo].[AspNetUsers] (
[Id] NVARCHAR (128) NOT NULL,
[UserName] NVARCHAR (MAX) NULL,
[PasswordHash] NVARCHAR (MAX) NULL,
[SecurityStamp] NVARCHAR (MAX) NULL,
[EmailConfirmed] BIT NOT NULL,
[PhoneNumber] NVARCHAR (MAX) NULL,
[PhoneNumberConfirmed] BIT NOT NULL,
[TwoFactorEnabled] BIT NOT NULL,
[LockoutEndDateUtc] DATETIME NULL,
[LockoutEnabled] BIT NOT NULL,
[AccessFailedCount] INT NOT NULL,
[ApplicationId] UNIQUEIDENTIFIER NOT NULL,
[LegacyPasswordHash] NVARCHAR (MAX) NULL,
[LoweredUserName] NVARCHAR (256) NOT NULL,
[MobileAlias] NVARCHAR (16) DEFAULT (NULL) NULL,
[IsAnonymous] BIT DEFAULT ((0)) NOT NULL,
[LastActivityDate] DATETIME2 NOT NULL,
[MobilePIN] NVARCHAR (16) NULL,
[Email] NVARCHAR (256) NULL,
[LoweredEmail] NVARCHAR (256) NULL,
[PasswordQuestion] NVARCHAR (256) NULL,
[PasswordAnswer] NVARCHAR (128) NULL,
[IsApproved] BIT NOT NULL,
[IsLockedOut] BIT NOT NULL,
[CreateDate] DATETIME2 NOT NULL,
[LastLoginDate] DATETIME2 NOT NULL,
[LastPasswordChangedDate] DATETIME2 NOT NULL,
[LastLockoutDate] DATETIME2 NOT NULL,
[FailedPasswordAttemptCount] INT NOT NULL,
[FailedPasswordAttemptWindowStart] DATETIME2 NOT NULL,
[FailedPasswordAnswerAttemptCount] INT NOT NULL,
[FailedPasswordAnswerAttemptWindowStart] DATETIME2 NOT NULL,
[Comment] NTEXT NULL,
CONSTRAINT [PK_dbo.AspNetUsers] PRIMARY KEY CLUSTERED ([Id] ASC),
FOREIGN KEY ([ApplicationId]) REFERENCES [dbo].[aspnet_Applications] ([ApplicationId]),
);
Dále musíme zkopírovat existující informace z databáze členství SQL do nově přidaných tabulek identity. Můžete to provést prostřednictvím SQL zkopírováním dat přímo z jedné tabulky do druhé. K přidání dat do řádků tabulky použijeme INSERT INTO [Table]
konstruktor . Ke kopírování z jiné tabulky můžeme použít INSERT INTO
příkaz spolu s příkazem SELECT
. Abychom získali všechny informace o uživateli, musíme se dotazovat na aspnet_Users a aspnet_Membership tabulky a zkopírovat data do tabulky AspNetUsers . Používáme příkazy INSERT INTO
a SELECT
spolu s JOIN
a .LEFT OUTER JOIN
Další informace o dotazování a kopírování dat mezi tabulkami najdete na tomto odkazu. Tabulky AspnetUserLogins a AspnetUserClaims jsou pro začátek prázdné, protože v členství SQL nejsou žádné informace, které by se na tuto hodnotu ve výchozím nastavení mapují. Jediné zkopírované informace jsou pro uživatele a role. V případě projektu vytvořeného v předchozích krocích by byl dotaz SQL na zkopírování informací do tabulky users (Uživatelé).
INSERT INTO AspNetUsers(Id,UserName,PasswordHash,SecurityStamp,EmailConfirmed,
PhoneNumber,PhoneNumberConfirmed,TwoFactorEnabled,LockoutEndDateUtc,LockoutEnabled,AccessFailedCount,
ApplicationId,LoweredUserName,MobileAlias,IsAnonymous,LastActivityDate,LegacyPasswordHash,
MobilePIN,Email,LoweredEmail,PasswordQuestion,PasswordAnswer,IsApproved,IsLockedOut,CreateDate,
LastLoginDate,LastPasswordChangedDate,LastLockoutDate,FailedPasswordAttemptCount,
FailedPasswordAnswerAttemptWindowStart,FailedPasswordAnswerAttemptCount,FailedPasswordAttemptWindowStart,Comment)
SELECT aspnet_Users.UserId,aspnet_Users.UserName,(aspnet_Membership.Password+'|'+CAST(aspnet_Membership.PasswordFormat as varchar)+'|'+aspnet_Membership.PasswordSalt),NewID(),
'true',NULL,'false','true',aspnet_Membership.LastLockoutDate,'true','0',
aspnet_Users.ApplicationId,aspnet_Users.LoweredUserName,
aspnet_Users.MobileAlias,aspnet_Users.IsAnonymous,aspnet_Users.LastActivityDate,aspnet_Membership.Password,
aspnet_Membership.MobilePIN,aspnet_Membership.Email,aspnet_Membership.LoweredEmail,aspnet_Membership.PasswordQuestion,aspnet_Membership.PasswordAnswer,
aspnet_Membership.IsApproved,aspnet_Membership.IsLockedOut,aspnet_Membership.CreateDate,aspnet_Membership.LastLoginDate,aspnet_Membership.LastPasswordChangedDate,
aspnet_Membership.LastLockoutDate,aspnet_Membership.FailedPasswordAttemptCount, aspnet_Membership.FailedPasswordAnswerAttemptWindowStart,
aspnet_Membership.FailedPasswordAnswerAttemptCount,aspnet_Membership.FailedPasswordAttemptWindowStart,aspnet_Membership.Comment
FROM aspnet_Users
LEFT OUTER JOIN aspnet_Membership ON aspnet_Membership.ApplicationId = aspnet_Users.ApplicationId
AND aspnet_Users.UserId = aspnet_Membership.UserId;
Ve výše uvedeném příkazu SQL se informace o každém uživateli z aspnet_Users a aspnet_Membership tabulek zkopírují do sloupců tabulky AspnetUsers . Jediná změna, která se tady provede, je zkopírování hesla. Vzhledem k tomu, že šifrovací algoritmus pro hesla v rámci členství SQL používal PasswordSalt a PasswordFormat, zkopírujeme také tento algoritmus spolu s hashovaným heslem, aby se mohl použít k dešifrování hesla pomocí identity. To je vysvětleno dále v článku při připojení vlastního hesla hasher.
Tento soubor skriptu je specifický pro tuto ukázku. U aplikací, které mají další tabulky, mohou vývojáři použít podobný přístup k přidání dalších vlastností do třídy modelu uživatele a jejich mapování na sloupce v tabulce AspnetUsers. Skript spustíte tak, že
Otevřete Průzkumníka serveru. Rozbalte připojení ApplicationServices a zobrazte tabulky. Klikněte pravým tlačítkem na uzel Tabulky a vyberte možnost Nový dotaz.
V okně dotazu zkopírujte a vložte celý skript SQL ze souboru Migrations.sql. Spusťte soubor skriptu stisknutím tlačítka se šipkou Spustit.
Aktualizujte okno Průzkumník serveru. V databázi se vytvoří pět nových tabulek.
Níže je uvedeno, jak se informace v tabulkách členství SQL mapují na nový systém identit.
aspnet_Roles –> AspNetRoles
asp_netUsers a asp_netMembership –> AspNetUsers
aspnet_UserInRoles –> AspNetUserRoles
Jak je vysvětleno v předchozí části, tabulky AspNetUserClaims a AspNetUserLogins jsou prázdné. Pole "Discriminator" v tabulce AspNetUser by se mělo shodovat s názvem třídy modelu, který je definován jako další krok. Sloupec PasswordHash je také ve formátu "šifrované heslo |heslo salt|formát hesla". To vám umožní použít speciální kryptografickou logiku členství SQL, abyste mohli znovu použít stará hesla. To je vysvětleno v pozdější části článku.
Vytváření modelů a stránek členství
Jak už bylo zmíněno dříve, funkce Identita ve výchozím nastavení používá Entity Framework ke komunikaci s databází za účelem ukládání informací o účtu. Abychom mohli pracovat s existujícími daty v tabulce, potřebujeme vytvořit třídy modelu, které se mapují zpět na tabulky a připojují je do systému identit. Jako součást kontraktu Identity by třídy modelu měly buď implementovat rozhraní definovaná v knihovně DLL Identity.Core, nebo mohou rozšířit stávající implementaci těchto rozhraní dostupných v Microsoft.AspNet.Identity.EntityFramework.
Tabulky AspNetRoles, AspNetUserClaims, AspNetLogins a AspNetUserRole v naší ukázce obsahují sloupce, které se podobají stávající implementaci systému identit. Proto můžeme znovu použít existující třídy pro mapování na tyto tabulky. Tabulka AspNetUser obsahuje několik dalších sloupců, které slouží k ukládání dalších informací z tabulek členství SQL. To lze mapovat vytvořením třídy modelu, která rozšiřuje existující implementaci 'IdentityUser' a přidat další vlastnosti.
Vytvořte v projektu složku Models a přidejte třídu User. Název třídy by se měl shodovat s daty přidanou ve sloupci Diskriminátor v tabulce AspnetUsers.
Třída User by měla rozšířit třídu IdentityUser v knihovně DLL Microsoft.AspNet.Identity.EntityFramework . Deklarujte vlastnosti ve třídě, které mapují zpět na sloupce AspNetUser. Vlastnosti ID, Username, PasswordHash a SecurityStamp jsou definovány v objektu IdentityUser, a proto jsou vynechány. Níže je kód pro třídu User, která má všechny vlastnosti.
public class User : IdentityUser { public User() { CreateDate = DateTime.Now; IsApproved = false; LastLoginDate = DateTime.Now; LastActivityDate = DateTime.Now; LastPasswordChangedDate = DateTime.Now; LastLockoutDate = DateTime.Parse("1/1/1754"); FailedPasswordAnswerAttemptWindowStart = DateTime.Parse("1/1/1754"); FailedPasswordAttemptWindowStart = DateTime.Parse("1/1/1754"); } public System.Guid ApplicationId { get; set; } public string MobileAlias { get; set; } public bool IsAnonymous { get; set; } public System.DateTime LastActivityDate { get; set; } public string MobilePIN { get; set; } public string LoweredEmail { get; set; } public string LoweredUserName { get; set; } public string PasswordQuestion { get; set; } public string PasswordAnswer { get; set; } public bool IsApproved { get; set; } public bool IsLockedOut { get; set; } public System.DateTime CreateDate { get; set; } public System.DateTime LastLoginDate { get; set; } public System.DateTime LastPasswordChangedDate { get; set; } public System.DateTime LastLockoutDate { get; set; } public int FailedPasswordAttemptCount { get; set; } public System.DateTime FailedPasswordAttemptWindowStart { get; set; } public int FailedPasswordAnswerAttemptCount { get; set; } public System.DateTime FailedPasswordAnswerAttemptWindowStart { get; set; } public string Comment { get; set; } }
Třída DbContext pro Entity Framework se vyžaduje k uchování dat v modelech zpět do tabulek a načtení dat z tabulek za účelem naplnění modelů. Knihovna DLL Microsoft.AspNet.Identity.EntityFramework definuje třídu IdentityDbContext, která pracuje s tabulkami Identity za účelem načtení a ukládání informací. Tuser> IdentityDbContext<přebírá třídu TUser, která může být libovolnou třídou, která rozšiřuje třídu IdentityUser.
Vytvořte novou třídu ApplicationDBContext, která rozšiřuje IdentityDbContext ve složce Models a předá třídu User vytvořenou v kroku 1.
public class ApplicationDbContext : IdentityDbContext<User> { }
Správa uživatelů v novém systému identit se provádí pomocí třídy tuser> UserManager<definované v knihovně DLL Microsoft.AspNet.Identity.EntityFramework. Potřebujeme vytvořit vlastní třídu, která rozšíří userManager a předá třídu User vytvořenou v kroku 1.
Ve složce Modely vytvořte novou třídu UserManager, která rozšiřuje uživatele UserManager<.>
public class UserManager : UserManager<User> { }
Hesla uživatelů aplikace jsou zašifrovaná a uložená v databázi. Kryptografický algoritmus používaný při členství v SQL se liší od algoritmu v novém systému identit. Abychom mohli znovu použít stará hesla, musíme selektivně dešifrovat hesla, když se staří uživatelé přihlašují pomocí algoritmu členství SQL, zatímco pro nové uživatele použijeme kryptografický algoritmus v identitě.
Třída UserManager má vlastnost PasswordHasher, která ukládá instanci třídy, která implementuje rozhraní IPasswordHasher. Používá se k šifrování/dešifrování hesel během transakcí ověřování uživatelů. Ve třídě UserManager definované v kroku 3 vytvořte novou třídu SQLPasswordHasher a zkopírujte níže uvedený kód.
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); }
Chyby kompilace vyřešíte importem oborů názvů System.Text a System.Security.Cryptography.
EncodePassword Metoda šifruje heslo podle výchozího členství SQL kryptografické implementace. Tento soubor je převzat z knihovny DLL System.Web. Pokud stará aplikace používala vlastní implementaci, měla by se to tady projevit. Potřebujeme definovat dvě další metody HashPassword a VerifyHashedPassword , které používají Metodu EncodePassword k hashování daného hesla nebo ověření hesla ve formátu prostého textu s heslem existujícím v databázi.
Systém členství SQL použil PasswordHash, PasswordSalt a PasswordFormat k hashování hesla zadaného uživateli při registraci nebo změně hesla. Během migrace jsou všechna tři pole uložena ve sloupci PasswordHash v tabulce AspNetUser oddělená znakem |. Když se uživatel přihlásí a heslo obsahuje tato pole, použijeme ke kontrole hesla kryptografické členství SQL. v opačném případě použijeme k ověření hesla výchozí šifrování systému identit. Díky tomu by si staří uživatelé nemuseli po migraci aplikace měnit hesla.
Deklarujte konstruktor třídy UserManager a předejte ji jako SQLPasswordHasher do vlastnosti v konstruktoru.
public UserManager() : base(new UserStore<User>(new ApplicationDbContext())) { this.PasswordHasher = new SQLPasswordHasher(); }
Vytvořit nové stránky pro správu účtů
Dalším krokem při migraci je přidání stránek pro správu účtů, které umožní registraci a přihlášení uživatele. Staré stránky účtů z členství SQL používají ovládací prvky, které s novým systémem identit nefungují. Pokud chcete přidat nové stránky pro správu uživatelů, postupujte podle kurzu na tomto odkazu https://www.asp.net/identity/overview/getting-started/adding-aspnet-identity-to-an-empty-or-existing-web-forms-project počínaje krokem "Přidání Web Forms pro registraci uživatelů do vaší aplikace", protože jsme už vytvořili projekt a přidali balíčky NuGet.
Abychom mohli v ukázce pracovat s projektem, který tady máme, musíme udělat nějaké změny.
Kód Register.aspx.cs a Login.aspx.cs na pozadí třídy používá
UserManager
z balíčků identity k vytvoření uživatele. V tomto příkladu použijte UserManager přidaný do složky Modely podle výše uvedených kroků.Použijte třídu User vytvořenou místo IdentityUser v kódu Register.aspx.cs a Login.aspx.cs za třídami. Tím se naše vlastní třída uživatelů připojí k systému identit.
Část pro vytvoření databáze se dá přeskočit.
Vývojář musí nastavit ApplicationId pro nového uživatele tak, aby odpovídala aktuálnímu ID aplikace. To lze provést dotazováním ApplicationId pro tuto aplikaci před vytvořením objektu uživatele ve třídě Register.aspx.cs a jeho nastavením před vytvořením uživatele.
Příklad:
Na stránce Register.aspx.cs definujte metodu pro dotazování aspnet_Applications tabulky a získání ID aplikace podle názvu aplikace.
private Guid GetApplicationID() { using (SqlConnection connection = new SqlConnection(ConfigurationManager.ConnectionStrings["ApplicationServices"].ConnectionString)) { string queryString = "SELECT ApplicationId from aspnet_Applications WHERE ApplicationName = '/'"; //Set application name as in database SqlCommand command = new SqlCommand(queryString, connection); command.Connection.Open(); var reader = command.ExecuteReader(); while (reader.Read()) { return reader.GetGuid(0); } return Guid.NewGuid(); } }
Teď ho nastavte u objektu uživatele.
var currentApplicationId = GetApplicationID(); User user = new User() { UserName = Username.Text, ApplicationId=currentApplicationId, …};
K přihlášení existujícího uživatele použijte staré uživatelské jméno a heslo. Pomocí stránky Zaregistrovat vytvořte nového uživatele. Ověřte také, že jsou uživatelé v rolích podle očekávání.
Přenos do systému identit pomáhá uživateli přidat do aplikace otevřené ověřování (OAuth). Projděte si ukázku , která má povolený protokol OAuth.
Další kroky
V tomto kurzu jsme ukázali, jak přenést uživatele z členství SQL na ASP.NET Identity, ale nepřepojili jsme data profilu. V dalším kurzu se podíváme na přenos dat profilu z členství SQL do nového systému identit.
Svůj názor můžete zanechat na konci tohoto článku.
Díky Tom Dykstra a Rick Anderson za přezkoumání článku.