Migrowanie z uwierzytelniania członkostwa ASP.NET do ASP.NET Core 2.0 Identity
Autor: Isaac Levin
W tym artykule przedstawiono migrowanie schematu bazy danych dla aplikacji ASP.NET przy użyciu uwierzytelniania członkostwa do ASP.NET Core 2.0 Identity.
Uwaga
Ten dokument zawiera kroki niezbędne do przeprowadzenia migracji schematu bazy danych dla aplikacji opartych na członkostwie ASP.NET do schematu bazy danych używanego dla platformy ASP.NET Core Identity. Aby uzyskać więcej informacji na temat migracji z uwierzytelniania opartego na członkostwie ASP.NET do ASP.NET Identity, zobacz Migrowanie istniejącej aplikacji z członkostwa SQL do ASP.NET Identity. Aby uzyskać więcej informacji na temat ASP.NET Core Identity, zobacz Wprowadzenie do Identity ASP.NET Core.
Przegląd schematu członkostwa
Przed ASP.NET 2.0 deweloperzy mieli za zadanie utworzenie całego procesu uwierzytelniania i autoryzacji dla swoich aplikacji. Wraz z ASP.NET 2.0 wprowadzono członkostwo, zapewniając kociołowe rozwiązanie do obsługi zabezpieczeń w aplikacjach ASP.NET. Deweloperzy mogli teraz uruchomić schemat w bazie danych programu SQL Server przy użyciu narzędzia ASP.NET rejestracji programu SQL Server () (Aspnet_regsql.exe
nie jest już obsługiwane). Po uruchomieniu tego polecenia w bazie danych zostały utworzone następujące tabele.
Aby przeprowadzić migrację istniejących aplikacji do ASP.NET Core 2.0 Identity, dane w tych tabelach muszą zostać zmigrowane do tabel używanych przez nowy Identity schemat.
schemat ASP.NET Core Identity 2.0
ASP.NET Core 2.0 jest zgodna z zasadą wprowadzoną Identity w ASP.NET 4.5. Chociaż zasada jest współdzielona, implementacja między strukturami jest inna, nawet między wersjami ASP.NET Core (zobacz Migrowanie uwierzytelniania i Identity do ASP.NET Core 2.0).
Najszybszym sposobem wyświetlenia schematu dla platformy ASP.NET Core 2.0 Identity jest utworzenie nowej aplikacji ASP.NET Core 2.0. Wykonaj następujące kroki w programie Visual Studio 2017:
Wybierz kolejno pozycje Plik>Nowy>Projekt.
Utwórz nowy projekt aplikacji internetowej ASP.NET Core o nazwie CoreIdentitySample.
Wybierz ASP.NET Core 2.0 na liście rozwijanej, a następnie wybierz pozycję Aplikacja internetowa. Ten szablon tworzy aplikację Razor Pages . Przed kliknięciem przycisku OK kliknij pozycję Zmień uwierzytelnianie.
Wybierz pozycję Indywidualne konta użytkowników dla Identity szablonów. Na koniec kliknij przycisk OK, a następnie przycisk OK. Program Visual Studio tworzy projekt przy użyciu szablonu ASP.NET Core Identity .
Wybierz pozycję Narzędzia Menedżer pakietów>NuGet> Menedżer pakietów Konsola, aby otworzyć okno konsoli Menedżer pakietów (PMC).
Przejdź do katalogu głównego projektu w usłudze PMC i uruchom polecenie Entity Framework (EF) Core
Update-Database
.ASP.NET Core 2.0 Identity używa EF Core do interakcji z bazą danych przechowującą dane uwierzytelniania. Aby nowo utworzona aplikacja działała, musi istnieć baza danych do przechowywania tych danych. Po utworzeniu nowej aplikacji najszybszym sposobem sprawdzenia schematu w środowisku bazy danych jest utworzenie bazy danych przy użyciu migracjiEF Core. Ten proces tworzy bazę danych lokalnie lub gdzie indziej, która naśladuje ten schemat. Aby uzyskać więcej informacji, zapoznaj się z poprzednią dokumentacją.
EF CorePolecenia używają parametry połączenia dla bazy danych określonej w pliku
appsettings.json
. Następujące parametry połączenia dotyczą bazy danych na localhost o nazwie asp-net-core-identity. W tym ustawieniu EF Core skonfigurowano używanieDefaultConnection
parametry połączenia.{ "ConnectionStrings": { "DefaultConnection": "Server=localhost;Database=aspnet-core-identity;Trusted_Connection=True;MultipleActiveResultSets=true" } }
Ostrzeżenie
W tym artykule przedstawiono użycie parametry połączenia. W przypadku lokalnej bazy danych użytkownik nie musi być uwierzytelniany, ale w środowisku produkcyjnym parametry połączenia czasami zawiera hasło do uwierzytelniania. Poświadczenie hasła właściciela zasobu (ROPC) jest zagrożeniem bezpieczeństwa, którego należy unikać w produkcyjnych bazach danych. Aplikacje produkcyjne powinny korzystać z najbezpieczniejszego dostępnego przepływu uwierzytelniania. Aby uzyskać więcej informacji na temat uwierzytelniania aplikacji wdrożonych w środowiskach testowych lub produkcyjnych, zobacz Bezpieczne przepływy uwierzytelniania.
Wybierz pozycję Wyświetl>Eksplorator obiektów programu SQL Server. Rozwiń węzeł odpowiadający nazwie bazy danych określonej we
ConnectionStrings:DefaultConnection
właściwościappsettings.json
.Polecenie
Update-Database
utworzyło bazę danych określoną przy użyciu schematu i wszelkie dane potrzebne do inicjowania aplikacji. Na poniższej ilustracji przedstawiono strukturę tabeli utworzoną przy użyciu poprzednich kroków.
Migrowanie schematu
Istnieją subtelne różnice w strukturach tabel i polach zarówno dla członkostwa, jak i ASP.NET Core Identity. Wzorzec zmienił się znacząco na potrzeby uwierzytelniania/autoryzacji przy użyciu aplikacji ASP.NET i ASP.NET Core. Kluczowe obiekty, które są nadal używane z usługą Identity , to Użytkownicy i role. Poniżej przedstawiono tabele mapowania użytkowników, ról i ról.
Użytkownicy
Identity ( dbo.AspNetUsers ) kolumna |
Typ | Członkostwo ( dbo.aspnet_Users / dbo.aspnet_Membership ) kolumna |
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
nie mapuje na LockoutEnabled
.
IsLockedOut
jest ustawiona, jeśli użytkownik miał zbyt wiele nieudanych logowań i jest zablokowany przez ustawiony czas.
LockoutEnabled
Umożliwia zablokowanie użytkownika z zbyt wieloma nieudanymi próbami logowania. Gdy użytkownik ma zbyt wiele nieudanych prób logowania, LockoutEnd
jest ustawiony na datę w przyszłości, a użytkownik nie może się zalogować do tej daty. Jeśli LockoutEnabled
jest to fałsz, użytkownik nigdy nie jest zablokowany dla zbyt wielu nieudanych prób logowania. Na OWASP, tymczasowe blokowanie konta po kilku nieudanych próbach jest zbyt proste w przypadku ataków DoS na uzasadnionych użytkowników.
Aby uzyskać więcej informacji na temat blokowania, zobacz Testowanie OWASP dla mechanizmu słabej blokady.
Aplikacje migrujące do Identity tej opcji, które chcą włączyć blokadę logowania, której nie można uruchomić, powinny mieć wartość LockoutEnabled
true w ramach migracji.
Uwaga
Nie wszystkie mapowania pól przypominają relacje jeden do jednego z członkostwa do ASP.NET Core Identity. Poprzednia tabela przyjmuje domyślny schemat Użytkownika członkostwa i mapuje go na schemat ASP.NET Core Identity . Wszystkie inne pola niestandardowe, które były używane do członkostwa, muszą być mapowane ręcznie. W tym mapowaniu nie ma mapy haseł, ponieważ zarówno kryteria hasła, jak i sole haseł nie są migrowane między nimi. Zaleca się pozostawienie hasła jako wartości null i monitowanie użytkowników o zresetowanie swoich haseł. W ASP.NET Core IdentityLockoutEnd
należy ustawić datę w przyszłości, jeśli użytkownik jest zablokowany. Jest to wyświetlane w skrygcie migracji.
Role
Identity ( dbo.AspNetRoles ) kolumna |
Typ | Członkostwo ( dbo.aspnet_Roles ) kolumna |
Typ |
---|---|---|---|
Id |
string |
RoleId |
string |
Name |
string |
RoleName |
string |
NormalizedName |
string |
LoweredRoleName |
string |
Role użytkowników
Identity ( dbo.AspNetUserRoles ) kolumna |
Typ | Członkostwo ( dbo.aspnet_UsersInRoles ) kolumna |
Typ |
---|---|---|---|
RoleId |
string |
RoleId |
string |
UserId |
string |
UserId |
string |
Odwołaj się do powyższych tabel mapowania podczas tworzenia skryptu migracji dla użytkowników i ról. W poniższym przykładzie założono, że masz dwie bazy danych na serwerze bazy danych. Jedna baza danych zawiera istniejący schemat członkostwa i dane ASP.NET. Druga baza danych CoreIdentitySample została utworzona przy użyciu opisanych wcześniej kroków. Komentarze są dołączane w tekście, aby uzyskać więcej szczegółów.
-- 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
Po zakończeniu poprzedniego skryptu utworzona wcześniej aplikacja ASP.NET Core Identity zostanie wypełniona użytkownikami członkostwa. Użytkownicy muszą zmienić swoje hasła przed zalogowaniem się.
Uwaga
Jeśli system członkostwa miał użytkowników z nazwami użytkowników, którzy nie są zgodni z ich adresem e-mail, zmiany są wymagane do aplikacji utworzonej wcześniej, aby ją uwzględnić. Domyślny szablon oczekuje UserName
i Email
będzie taki sam. W sytuacjach, w których są różne, proces logowania należy zmodyfikować, aby zamiast UserName
Email
.
PageModel
Na stronie logowania znajdującej się w lokalizacji usuń [EmailAddress]
atrybut z właściwości Email. Zmień jego nazwę na UserName. Wymaga to zmiany wszędzie tam, gdzie EmailAddress
jest wymieniona, w widoku i modelu PageModel. Wynik wygląda następująco:
Następne kroki
W tym samouczku przedstawiono sposób przenoszenia użytkowników z członkostwa SQL do ASP.NET Core 2.0 Identity. Aby uzyskać więcej informacji na temat ASP.NET Core Identity, zobacz Wprowadzenie do Identityprogramu .