Catatan
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba masuk atau mengubah direktori.
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba mengubah direktori.
oleh Rick Anderson, Suhas Joshi
Tutorial ini menggambarkan langkah-langkah untuk memigrasikan aplikasi web yang ada dengan data pengguna dan peran yang dibuat menggunakan Keanggotaan SQL ke sistem Identitas ASP.NET baru. Pendekatan ini melibatkan perubahan skema database yang ada ke yang diperlukan oleh identitas ASP.NET dan kaitkan di kelas lama/baru ke dalamnya. Setelah Anda mengadopsi pendekatan ini, setelah database Anda dimigrasikan, pembaruan identitas di masa mendatang akan ditangani dengan mudah.
Untuk tutorial ini, kami akan mengambil templat aplikasi web (Formulir Web) yang dibuat menggunakan Visual Studio 2010 untuk membuat data pengguna dan peran. Kami kemudian akan menggunakan skrip SQL untuk memigrasikan database yang ada ke tabel yang diperlukan oleh sistem Identitas. Selanjutnya kita akan menginstal paket NuGet yang diperlukan dan menambahkan halaman manajemen akun baru yang menggunakan sistem Identitas untuk manajemen keanggotaan. Sebagai pengujian migrasi, pengguna yang dibuat menggunakan keanggotaan SQL harus dapat masuk dan pengguna baru harus dapat mendaftar. Anda dapat menemukan sampel lengkap di sini. Lihat juga Migrasi dari Keanggotaan ASP.NET ke Identitas ASP.NET.
Memulai
Membuat aplikasi dengan Keanggotaan SQL
Kita perlu memulai dengan aplikasi yang ada yang menggunakan keanggotaan SQL dan memiliki data pengguna dan peran. Untuk tujuan artikel ini, mari kita buat aplikasi web di Visual Studio 2010.
Menggunakan alat konfigurasi ASP.NET, buat 2 pengguna: oldAdminUser dan oldUser.
Buat peran bernama Admin dan tambahkan 'oldAdminUser' sebagai pengguna dalam peran tersebut.
Buat bagian Admin situs dengan Default.aspx. Atur tag otorisasi dalam file web.config untuk mengaktifkan akses hanya ke pengguna dalam peran Admin. Informasi lebih lanjut dapat ditemukan di sini https://www.asp.net/web-forms/tutorials/security/roles/role-based-authorization-cs
Tampilkan database di Server Explorer untuk memahami tabel yang dibuat oleh sistem keanggotaan SQL. Data masuk pengguna disimpan dalam tabel aspnet_Users dan aspnet_Membership, sementara data peran disimpan dalam tabel aspnet_Roles. Informasi tentang pengguna mana yang menyimpan peran dalam tabel aspnet_UsersInRoles. Untuk manajemen keanggotaan dasar, cukup untuk memindahkan informasi dalam tabel di atas ke sistem identitas ASP.NET.
Migrasi ke Visual Studio 2013
Instal Visual Studio Express 2013 untuk Web atau Visual Studio 2013 bersama dengan pembaruan terbaru.
Buka proyek di atas di versi Visual Studio yang terinstal. Jika SQL Server Express tidak diinstal pada komputer, perintah ditampilkan saat Anda membuka proyek, karena string koneksi menggunakan SQL Express. Anda dapat memilih untuk menginstal SQL Express atau sebagai solusi untuk mengubah string koneksi ke LocalDb. Untuk artikel ini, kami akan mengubahnya menjadi LocalDb.
Buka web.config dan ubah string koneksi dari . SQLExpress ke (LocalDb)v11.0. Hapus 'User Instance=true' dari string koneksi.
Buka Server Explorer dan verifikasi bahwa skema tabel dan data dapat diamati.
Sistem identitas ASP.NET berfungsi dengan versi 4.5 atau yang lebih tinggi dari kerangka kerja. Targetkan ulang aplikasi ke 4,5 atau lebih tinggi.
Bangun proyek untuk memverifikasi bahwa tidak ada kesalahan.
Menginstal paket Nuget
Di Penjelajah Solusi, klik kanan proyek >Kelola Paket NuGet. Di kotak pencarian, masukkan "Asp.net Identity". Pilih paket dalam daftar hasil dan klik instal. Terima perjanjian lisensi dengan mengklik tombol "Saya Terima". Perhatikan bahwa paket ini akan menginstal paket dependensi: EntityFramework dan Microsoft ASP.NET Identity Core. Demikian pula instal paket berikut (lewati 4 paket OWIN terakhir jika Anda tidak ingin mengaktifkan masuk OAuth):
Microsoft.AspNet.Identity.Owin
Microsoft.Owin.Host.SystemWeb
Microsoft.Owin.Security.Facebook
Microsoft.Owin.Security.Google
Microsoft.Owin.Security.MicrosoftAccount
Microsoft.Owin.Security.Twitter
Memigrasikan database ke sistem Identitas baru
Langkah selanjutnya adalah memigrasikan database yang ada ke skema yang diperlukan oleh sistem identitas ASP.NET. Untuk mencapai hal ini, kami menjalankan skrip SQL yang memiliki sekumpulan perintah untuk membuat tabel baru dan memigrasikan informasi pengguna yang ada ke tabel baru. File skrip dapat ditemukan di sini.
File skrip ini khusus untuk sampel ini. Jika skema untuk tabel yang dibuat menggunakan keanggotaan SQL dikustomisasi atau dimodifikasi, skrip perlu diubah.
Cara menghasilkan skrip SQL untuk migrasi skema
Agar kelas ASP.NET Identity berfungsi di luar kotak dengan data pengguna yang ada, kita perlu memigrasikan skema database ke yang diperlukan oleh ASP.NET Identity. Kita dapat melakukan ini dengan menambahkan tabel baru dan menyalin informasi yang ada ke tabel tersebut. Secara default ASP.NET Identity menggunakan EntityFramework untuk memetakan kelas model Identitas kembali ke database untuk menyimpan/mengambil informasi. Kelas model ini mengimplementasikan antarmuka Identitas inti yang menentukan objek pengguna dan peran. Tabel dan kolom dalam database didasarkan pada kelas model ini. Kelas model EntityFramework di Identity v2.1.0 dan propertinya seperti yang didefinisikan di bawah ini
| IdentityUser | Jenis | IdentityRole | IdentityUserRole | IdentityUserLogin | IdentityUserClaim |
|---|---|---|---|---|---|
| Id | string | Id | RoleId | ProviderKey | Id |
| Nama pengguna | string | Nama | UserId | UserId | ClaimType |
| PasswordHash | string | LoginProvider | ClaimValue | ||
| Tanda Keamanan | string | User_Id | |||
| string | |||||
| EmailKonfirmasi | bool | ||||
| NomorTelepon | string | ||||
| PhoneNumberConfirmed | bool | ||||
| LockoutEnabled | bool | ||||
| LockoutEndDate | DateTime | ||||
| AccessFailedCount | int |
Kita harus memiliki tabel untuk masing-masing model ini dengan kolom yang sesuai dengan properti. Pemetaan antara kelas dan tabel didefinisikan dalam OnModelCreating metode IdentityDBContext. Ini dikenal sebagai metode konfigurasi API yang fasih dan informasi lebih lanjut dapat ditemukan di sini. Konfigurasi untuk kelas adalah seperti yang disebutkan di bawah ini
| Kelas | Meja | Kunci utama | Kunci asing |
|---|---|---|---|
| IdentityUser | AspnetUsers | Id | |
| IdentityRole | AspnetRoles | Id | |
| IdentityUserRole | AspnetUserRole | UserId + RoleId | User_Id-AspnetUsers> RoleId-AspnetRoles> |
| IdentityUserLogin | AspnetUserLogins | ProviderKey+UserId + LoginProvider | UserId-AspnetUsers> |
| IdentityUserClaim | AspnetUserClaims | Id | User_Id-AspnetUsers> |
Dengan informasi ini kita dapat membuat pernyataan SQL untuk membuat tabel baru. Kita dapat menulis setiap pernyataan satu per satu atau menghasilkan seluruh skrip menggunakan perintah EntityFramework PowerShell yang kemudian dapat kita edit sesuai kebutuhan. Untuk melakukan ini, di VS buka Konsol Manajer Paket dari menu Tampilan atau Alat
- Jalankan perintah "Enable-Migrations" untuk mengaktifkan migrasi EntityFramework.
- Jalankan perintah "Add-migration initial" yang membuat kode penyiapan awal untuk membuat database di C#/VB.
- Langkah terakhir adalah menjalankan perintah "Update-Database –Script" yang menghasilkan skrip SQL berdasarkan kelas model.
Beberapa perintah tidak didukung jika aplikasi menggunakan SQLite sebagai penyimpanan data Identitasnya. Karena keterbatasan dalam mesin database,
Alterperintah melemparkan pengecualian berikut:"System.NotSupportedException: SQLite tidak mendukung operasi migrasi ini."
Sebagai pekerjaan, jalankan migrasi Kode Pertama pada database untuk mengubah tabel.
Skrip pembuatan database ini dapat digunakan sebagai awal di mana kita akan membuat perubahan tambahan untuk menambahkan kolom baru dan menyalin data. Keuntungan dari ini adalah bahwa kita menghasilkan _MigrationHistory tabel yang digunakan oleh EntityFramework untuk memodifikasi skema database ketika kelas model berubah untuk versi rilis Identitas di masa mendatang.
Informasi pengguna keanggotaan SQL memiliki properti lain selain yang ada di kelas model pengguna Identitas yaitu email, upaya kata sandi, tanggal masuk terakhir, tanggal penguncian terakhir, dll. Ini adalah informasi yang berguna dan kami ingin dibawa ke sistem Identitas. Ini dapat dilakukan dengan menambahkan properti tambahan ke model pengguna dan memetakannya kembali ke kolom tabel dalam database. Kita dapat melakukan ini dengan menambahkan kelas yang mensubkelas IdentityUser model. Kita dapat menambahkan properti ke kelas kustom ini dan mengedit skrip SQL untuk menambahkan kolom yang sesuai saat membuat tabel. Kode untuk kelas ini dijelaskan lebih lanjut dalam artikel. Skrip SQL untuk membuat AspnetUsers tabel setelah menambahkan properti baru adalah
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]),
);
Selanjutnya kita perlu menyalin informasi yang ada dari database keanggotaan SQL ke tabel yang baru ditambahkan untuk Identitas. Ini dapat dilakukan melalui SQL dengan menyalin data langsung dari satu tabel ke tabel lainnya. Untuk menambahkan data ke dalam baris tabel, kami menggunakan INSERT INTO [Table] konstruksi . Untuk menyalin dari tabel lain, kita dapat menggunakan INSERT INTO pernyataan bersama dengan SELECT pernyataan . Untuk mendapatkan semua informasi pengguna, kita perlu mengkueri tabel aspnet_Users dan aspnet_Membership dan menyalin data ke tabel AspNetUsers . Kami menggunakan INSERT INTO dan bersama dengan JOIN pernyataan dan LEFT OUTER JOINSELECT . Untuk informasi selengkapnya tentang mengkueri dan menyalin data antar tabel, lihat tautan ini . Selain itu tabel AspnetUserLogins dan AspnetUserClaims kosong untuk memulai karena tidak ada informasi dalam keanggotaan SQL yang memetakan ini secara default. Satu-satunya informasi yang disalin adalah untuk pengguna dan peran. Untuk proyek yang dibuat di langkah-langkah sebelumnya, kueri SQL untuk menyalin informasi ke tabel pengguna adalah
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;
Dalam pernyataan SQL di atas, informasi tentang setiap pengguna dari tabel aspnet_Users dan aspnet_Membership disalin ke dalam kolom tabel AspnetUsers . Satu-satunya modifikasi yang dilakukan di sini adalah ketika kami menyalin kata sandi. Karena algoritma enkripsi untuk kata sandi dalam keanggotaan SQL menggunakan 'PasswordSalt' dan 'PasswordFormat', kami menyalinnya juga bersama dengan kata sandi yang di-hash sehingga dapat digunakan untuk mendekripsi kata sandi oleh Identitas. Ini dijelaskan lebih lanjut dalam artikel saat menghubungkan hasher kata sandi kustom.
File skrip ini khusus untuk sampel ini. Untuk aplikasi yang memiliki tabel tambahan, pengembang dapat mengikuti pendekatan serupa untuk menambahkan properti tambahan pada kelas model pengguna dan memetakannya ke kolom dalam tabel AspnetUsers. Untuk menjalankan skrip,
Buka Penjelajah Server. Perluas koneksi 'ApplicationServices' untuk menampilkan tabel. Klik kanan pada simpul Tabel dan pilih opsi 'Kueri Baru'
Di jendela kueri, salin dan tempel seluruh skrip SQL dari file Migrations.sql. Jalankan file skrip dengan menekan tombol panah 'Jalankan'.
Refresh jendela Penjelajah Server. Lima tabel baru dibuat dalam database.
Di bawah ini adalah bagaimana informasi dalam tabel keanggotaan SQL dipetakan ke sistem Identitas baru.
aspnet_Roles --> AspNetRoles
asp_netUsers dan asp_netMembership --> AspNetUsers
aspnet_UserInRoles --> AspNetUserRoles
Seperti yang dijelaskan di bagian di atas, tabel AspNetUserClaims dan AspNetUserLogins kosong. Bidang 'Diskriminator' dalam tabel AspNetUser harus cocok dengan nama kelas model yang didefinisikan sebagai langkah berikutnya. Kolom PasswordHash juga dalam bentuk 'kata sandi terenkripsi |salt kata sandi|format kata sandi'. Ini memungkinkan Anda untuk menggunakan logika kripto keanggotaan SQL khusus sehingga Anda dapat menggunakan kembali kata sandi lama. Itu dijelaskan di kemudian hari dalam artikel.
Membuat model dan halaman keanggotaan
Seperti disebutkan sebelumnya, fitur Identitas menggunakan Kerangka Kerja Entitas untuk berbicara dengan database untuk menyimpan informasi akun secara default. Untuk bekerja dengan data yang ada dalam tabel, kita perlu membuat kelas model yang memetakan kembali ke tabel dan menghubungkannya di sistem Identitas. Sebagai bagian dari kontrak Identitas, kelas model harus mengimplementasikan antarmuka yang ditentukan dalam dll Identity.Core atau dapat memperluas implementasi antarmuka yang ada yang tersedia di Microsoft.AspNet.Identity.EntityFramework.
Dalam sampel kami, tabel AspNetRoles, AspNetUserClaims, AspNetLogins, dan AspNetUserRole memiliki kolom yang mirip dengan implementasi sistem Identitas yang ada. Oleh karena itu, kita dapat menggunakan kembali kelas yang ada untuk memetakan ke tabel ini. Tabel AspNetUser memiliki beberapa kolom tambahan yang digunakan untuk menyimpan informasi tambahan dari tabel keanggotaan SQL. Ini dapat dipetakan dengan membuat kelas model yang memperluas implementasi 'IdentityUser' yang ada dan menambahkan properti tambahan.
Buat folder Model di proyek dan tambahkan Pengguna kelas. Nama kelas harus cocok dengan data yang ditambahkan di kolom 'Diskriminator' tabel 'AspnetUsers'.
Kelas Pengguna harus memperluas kelas IdentityUser yang ditemukan di dll Microsoft.AspNet.Identity.EntityFramework . Nyatakan properti di kelas yang memetakan kembali ke kolom AspNetUser. ID properti, Nama Pengguna, PasswordHash, dan SecurityStamp ditentukan dalam IdentityUser sehingga dihilangkan. Di bawah ini adalah kode untuk kelas Pengguna yang memiliki semua properti
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; } }Kelas Entity Framework DbContext diperlukan untuk mempertahankan data dalam model kembali ke tabel dan mengambil data dari tabel untuk mengisi model. Dll Microsoft.AspNet.Identity.EntityFramework menentukan kelas IdentityDbContext yang berinteraksi dengan tabel Identitas untuk mengambil dan menyimpan informasi. Tuser> IdentityDbContext<mengambil kelas 'TUser' yang dapat menjadi kelas apa pun yang memperluas kelas IdentityUser.
Buat kelas baru ApplicationDBContext yang memperluas IdentityDbContext di bawah folder 'Model', meneruskan kelas 'Pengguna' yang dibuat di langkah 1
public class ApplicationDbContext : IdentityDbContext<User> { }Manajemen pengguna dalam sistem Identitas baru dilakukan menggunakan kelas tuser UserManager<yang ditentukan dalam dll Microsoft.AspNet.Identity.EntityFramework.> Kita perlu membuat kelas kustom yang memperluas UserManager, melewati kelas 'Pengguna' yang dibuat di langkah 1.
Di folder Model, buat kelas baru UserManager yang memperluas pengguna UserManager<>
public class UserManager : UserManager<User> { }Kata sandi pengguna aplikasi dienkripsi dan disimpan dalam database. Algoritma kripto yang digunakan dalam keanggotaan SQL berbeda dari yang ada di sistem Identitas baru. Untuk menggunakan kembali kata sandi lama, kita perlu mendekripsi kata sandi secara selektif saat pengguna lama masuk menggunakan algoritma keanggotaan SQL saat menggunakan algoritma kripto di Identitas untuk pengguna baru.
Kelas UserManager memiliki properti 'PasswordHasher' yang menyimpan instans kelas yang mengimplementasikan antarmuka 'IPasswordHasher'. Ini digunakan untuk mengenkripsi/mendekripsi kata sandi selama transaksi autentikasi pengguna. Di kelas UserManager yang ditentukan di langkah 3, buat kelas baru SQLPasswordHasher dan salin kode di bawah ini.
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); }Atasi kesalahan kompilasi dengan mengimpor namespace System.Text dan System.Security.Cryptography.
Metode EncodePassword mengenkripsi kata sandi sesuai dengan implementasi kripto keanggotaan SQL default. Ini diambil dari dll System.Web. Jika aplikasi lama menggunakan implementasi kustom, maka aplikasi tersebut harus tercermin di sini. Kita perlu menentukan dua metode lain HashPassword dan VerifyHashedPassword yang menggunakan metode EncodePassword untuk hash kata sandi yang diberikan atau memverifikasi kata sandi teks biasa dengan yang ada dalam database.
Sistem keanggotaan SQL menggunakan PasswordHash, PasswordSalt, dan PasswordFormat untuk hash kata sandi yang dimasukkan oleh pengguna saat mereka mendaftar atau mengubah kata sandi mereka. Selama migrasi ketiga bidang disimpan di kolom PasswordHash dalam tabel AspNetUser yang dipisahkan oleh karakter '|'. Ketika pengguna masuk dan kata sandi memiliki bidang ini, kami menggunakan kripto keanggotaan SQL untuk memeriksa kata sandi; jika tidak, kami menggunakan kripto default sistem Identitas untuk memverifikasi kata sandi. Dengan cara ini pengguna lama tidak perlu mengubah kata sandi mereka setelah aplikasi dimigrasikan.
Deklarasikan konstruktor untuk kelas UserManager dan teruskan ini sebagai SQLPasswordHasher ke properti di konstruktor.
public UserManager() : base(new UserStore<User>(new ApplicationDbContext())) { this.PasswordHasher = new SQLPasswordHasher(); }
Membuat halaman manajemen akun baru
Langkah selanjutnya dalam migrasi adalah menambahkan halaman manajemen akun yang akan memungkinkan pengguna mendaftar dan masuk. Halaman akun lama dari keanggotaan SQL menggunakan kontrol yang tidak berfungsi dengan sistem Identitas baru. Untuk menambahkan halaman manajemen pengguna baru, ikuti tutorial di tautan https://www.asp.net/identity/overview/getting-started/adding-aspnet-identity-to-an-empty-or-existing-web-forms-project ini mulai dari langkah 'Menambahkan Formulir Web untuk mendaftarkan pengguna ke aplikasi Anda' karena kami telah membuat proyek dan menambahkan paket NuGet.
Kita perlu membuat beberapa perubahan agar sampel berfungsi dengan proyek yang kita miliki di sini.
Kode Register.aspx.cs dan Login.aspx.cs di belakang kelas menggunakan
UserManagerdari paket Identitas untuk membuat Pengguna. Untuk contoh ini, gunakan UserManager yang ditambahkan di folder Model dengan mengikuti langkah-langkah yang disebutkan sebelumnya.Gunakan kelas Pengguna yang dibuat alih-alih IdentityUser di Register.aspx.cs dan kode Login.aspx.cs di belakang kelas. Ini mengaitkan di kelas pengguna kustom kami ke dalam sistem Identitas.
Bagian untuk membuat database dapat dilewati.
Pengembang perlu mengatur ApplicationId agar pengguna baru sesuai dengan ID aplikasi saat ini. Ini dapat dilakukan dengan mengkueri ApplicationId untuk aplikasi ini sebelum objek pengguna dibuat di kelas Register.aspx.cs dan mengaturnya sebelum membuat pengguna.
Contoh:
Tentukan metode di halaman Register.aspx.cs untuk mengkueri tabel aspnet_Applications dan mendapatkan Id aplikasi sesuai dengan nama aplikasi
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(); } }Sekarang atur ini pada objek pengguna
var currentApplicationId = GetApplicationID(); User user = new User() { UserName = Username.Text, ApplicationId=currentApplicationId, …};
Gunakan nama pengguna dan kata sandi lama untuk masuk ke pengguna yang sudah ada. Gunakan halaman Daftar untuk membuat pengguna baru. Verifikasi juga bahwa pengguna berada dalam peran seperti yang diharapkan.
Porting ke sistem Identitas membantu pengguna menambahkan Open Authentication (OAuth) ke aplikasi. Silakan lihat sampel di sini yang mengaktifkan OAuth.
Langkah berikutnya
Dalam tutorial ini kami menunjukkan cara memindahkan pengguna dari keanggotaan SQL ke identitas ASP.NET, tetapi kami tidak memindahkan data Profil. Dalam tutorial berikutnya kita akan melihat porting data Profil dari keanggotaan SQL ke sistem Identitas baru.
Anda dapat meninggalkan umpan balik di bagian bawah artikel ini.
Terima kasih kepada Tom Dykstra dan Rick Anderson untuk meninjau artikel ini.