Mevcut Bir Web Sitesini SQL Üyeliğinden ASP.NET Identity’ye GeçirmeMigrating an Existing Website from SQL Membership to ASP.NET Identity

by Rick Anderson, Suwith Joshiby Rick Anderson, Suhas Joshi

Bu öğreticide, mevcut bir Web uygulamasını yeni ASP.NET Identity sistemine SQL üyeliği kullanılarak oluşturulan kullanıcı ve rol verileriyle geçirme adımları gösterilmektedir.This tutorial illustrates the steps to migrate an existing web application with user and role data created using SQL Membership to the new ASP.NET Identity system. Bu yaklaşım, var olan veritabanı şemasını ASP.NET Identity için gereken bir şekilde değiştirmeyi ve eski/yeni sınıflarda bu sınıfa kancalarını içerir.This approach involves changing the existing database schema to the one needed by the ASP.NET Identity and hook in the old/new classes to it. Bu yaklaşımı benimsediğinizde, veritabanınız geçirildikten sonra, sonraki kimlik güncelleştirmeleri daha kolay bir şekilde ele alınacaktır.After you adopt this approach, once your database is migrated, future updates to Identity will be handled effortlessly.

Bu öğreticide, Kullanıcı ve rol verileri oluşturmak için Visual Studio 2010 kullanılarak oluşturulan bir Web uygulaması şablonu (Web Forms) kullanacağız.For this tutorial, we will take a web application template (Web Forms) created using Visual Studio 2010 to create user and role data. Daha sonra, mevcut veritabanını kimlik sisteminin gerektirdiği tablolara geçirmek için SQL betikleri kullanacağız.We will then use SQL scripts to migrate the existing database to tables needed by the Identity system. Ardından, gerekli NuGet paketlerini yükleyeceğiz ve Üyelik yönetimi için kimlik sistemini kullanan yeni hesap yönetimi sayfaları ekleyeceğiz.Next we'll install the necessary NuGet packages and add new account management pages which use the Identity system for membership management. Geçişin bir testi olarak, SQL üyeliği kullanılarak oluşturulan kullanıcıların oturum açabiliyor ve yeni kullanıcıların kayıt yapabilmesi gerekir.As a test of migration, users created using SQL membership should be able to log in and new users should be able to register. Örneğin tamamını burada bulabilirsiniz.You can find the complete sample here. Ayrıca bkz. ASP.net üyeliğinden ASP.NET Identity geçirme.See also Migrating from ASP.NET Membership to ASP.NET Identity.

BaşlarkenGetting started

SQL üyeliğiyle uygulama oluşturmaCreating an application with SQL Membership

  1. SQL üyeliği kullanan ve Kullanıcı ve rol verilerine sahip olan mevcut bir uygulamayla başlamamız gerekir.We need to start with an existing application that uses SQL membership and has user and role data. Bu makalenin amacı doğrultusunda, Visual Studio 2010 'de bir Web uygulaması oluşturalım.For the purpose of this article, let's create a web application in Visual Studio 2010.

  2. ASP.NET yapılandırma aracını kullanarak 2 Kullanıcı oluşturun: Oldadminuser ve olduser.Using the ASP.NET Configuration tool, create 2 users: oldAdminUser and oldUser.

  3. Yönetici adlı bir rol oluşturun ve bu roldeki bir kullanıcı olarak ' oldAdminUser ' ekleyin.Create a role named Admin and add 'oldAdminUser' as a user in that role.

  4. Site için default. aspx olan bir yönetici bölümü oluşturun.Create an Admin section of the site with a Default.aspx. Yalnızca yönetici rollerindeki kullanıcılara erişimi etkinleştirmek için Web. config dosyasındaki yetkilendirme etiketini ayarlayın.Set the authorization tag in the web.config file to enable access only to users in Admin roles. Burada daha fazla bilgi bulabilirsiniz https://www.asp.net/web-forms/tutorials/security/roles/role-based-authorization-csMore information can be found here https://www.asp.net/web-forms/tutorials/security/roles/role-based-authorization-cs

  5. SQL üyelik sistemi tarafından oluşturulan tabloları anlamak için Sunucu Gezgini veritabanını görüntüleyin.View the database in Server Explorer to understand the tables created by the SQL membership system. Kullanıcı oturum açma verileri ASPNET_Users ve ASPNET_üyelik tablolarında depolanır, ancak rol verileri ASPNET_roller tablosunda depolanır.The user login data is stored in the aspnet_Users and aspnet_Membership tables, while role data is stored in the aspnet_Roles table. Hangi kullanıcıların, ASPNET_Usersınroles tablosunda hangi rollerin depolandığı hakkında bilgiler.Information about which users are in which roles is stored in the aspnet_UsersInRoles table. Temel üyelik yönetimi için yukarıdaki tablolardaki bilgilerin ASP.NET Identity sistemine bağlantı noktası almak yeterlidir.For basic membership management it is sufficient to port the information in the above tables to the ASP.NET Identity system.

Visual Studio 2013 geçiriliyorMigrating to Visual Studio 2013

  1. Web veya Visual Studio 2013 için Visual Studio Express 2013 ' i en son güncelleştirmelerlebirlikte yükler.Install Visual Studio Express 2013 for Web or Visual Studio 2013 along with the latest updates.

  2. Yukarıdaki projeyi Visual Studio 'nun yüklü sürümünde açın.Open the above project in your installed version of Visual Studio. Makinede SQL Server Express yüklü değilse, bağlantı dizesi SQL Express kullandığından projeyi açtığınızda bir istem görüntülenir.If SQL Server Express is not installed on the machine, a prompt is displayed when you open the project, since the connection string uses SQL Express. SQL Express 'i yüklemeyi veya geçici bir çözüm olarak, bağlantı dizesini LocalDb olarak değiştirmeyi seçebilirsiniz.You can either choose to install SQL Express or as work around change the connection string to LocalDb. Bu makalede, LocalDb olarak değiştirilecek.For this article we'll change it to LocalDb.

  3. Web. config dosyasını açın ve bağlantı dizesini ' den değiştirin. SQLExpress (LocalDb) v 11.0.Open web.config and change the connection string from .SQLExpress to (LocalDb)v11.0. Bağlantı dizesinden ' User Instance = true ' değerini kaldırın.Remove 'User Instance=true' from the connection string.

  4. Sunucu Gezgini açın ve tablo şemasının ve verilerin gözlemlenebilir olduğunu doğrulayın.Open Server Explorer and verify that the table schema and data can be observed.

  5. ASP.NET Identity sistem Framework sürüm 4,5 veya üzeri sürümlerle birlikte çalışmaktadır.The ASP.NET Identity system works with version 4.5 or higher of the framework. Uygulamayı 4,5 veya daha yüksek bir düzeye yeniden hedefleyin.Retarget the application to 4.5 or higher.

    Hata olmadığını doğrulamak için projeyi derleyin.Build the project to verify that there are no errors.

NuGet paketlerini yüklemeInstalling the Nuget packages

  1. Çözüm Gezgini, NuGet paketlerini yönetmek> projeye sağ tıklayın.In Solution Explorer, right-click the project > Manage NuGet Packages. Arama kutusuna "Asp.net Identity" yazın.In the search box, enter "Asp.net Identity". Sonuçlar listesinden paketi seçin ve ardından yükler ' e tıklayın.Select the package in the list of results and click install. "Kabul ediyorum" düğmesine tıklayarak lisans sözleşmesini kabul edin.Accept the license agreement by clicking on "I Accept" button. Bu paketin bağımlılık paketlerini yükleyeceğini unutmayın: EntityFramework ve Microsoft ASP.NET Identity Core.Note that this package will install the dependency packages: EntityFramework and Microsoft ASP.NET Identity Core. Benzer şekilde, aşağıdaki paketleri yüklemek (OAuth oturum açma işlemini etkinleştirmek istemiyorsanız son 4 OWIN paketlerini atlayın):Similarly install the following packages (skip the last 4 OWIN packages if you don't want to enable OAuth log-in):

    • Microsoft.AspNet.Identity.OwinMicrosoft.AspNet.Identity.Owin

    • Microsoft.Owin.Host.SystemWebMicrosoft.Owin.Host.SystemWeb

    • Microsoft. Owin. Security. FacebookMicrosoft.Owin.Security.Facebook

    • Microsoft. Owin. Security. GoogleMicrosoft.Owin.Security.Google

    • Microsoft.Owin.Security.MicrosoftAccountMicrosoft.Owin.Security.MicrosoftAccount

    • Microsoft.Owin.Security.TwitterMicrosoft.Owin.Security.Twitter

Veritabanını yeni kimlik sistemine geçirMigrate database to the new Identity system

Sonraki adım, mevcut veritabanını ASP.NET Identity sisteminin gerektirdiği bir şemaya geçirmadır.The next step is to migrate the existing database to a schema required by the ASP.NET Identity system. Bunu başarmak için yeni tablolar oluşturmaya ve mevcut kullanıcı bilgilerini yeni tablolara geçirmeye yönelik bir komut kümesine sahip bir SQL betiği çalıştırdık.To achieve this we run a SQL script which has a set of commands to create new tables and migrate existing user information to the new tables. Betik dosyası buradabulunabilir.The script file can be found here.

Bu betik dosyası bu örneğe özeldir.This script file is specific to this sample. SQL üyeliği kullanılarak oluşturulan tablolar için şema özelleştirildiyse veya değiştirilirse betiklerin uygun şekilde değiştirilmesi gerekir.If the schema for the tables created using SQL membership is customized or modified the scripts need to be changed accordingly.

Şema geçişi için SQL betiği oluşturmaHow to generate the SQL script for schema migration

ASP.NET Identity sınıflarının mevcut kullanıcıların verileriyle birlikte çalışması için, veritabanı şemasını ASP.NET Identity için gereken birine geçirmemiz gerekir.For ASP.NET Identity classes to work out of the box with the data of existing users, we need to migrate the database schema to the one needed by ASP.NET Identity. Bunu, yeni tablolar ekleyerek ve var olan bilgileri bu tablolara kopyalayarak yapabiliriz.We can do this by adding new tables and copying the existing information to those tables. Varsayılan olarak ASP.NET Identity EntityFramework kullanarak kimlik modeli sınıflarını, bilgileri depolamak/almak üzere veritabanına geri eşlemek için kullanır.By default ASP.NET Identity uses EntityFramework to map the Identity model classes back to the database to store/retrieve information. Bu model sınıfları, Kullanıcı ve rol nesnelerini tanımlayan temel kimlik arabirimlerini uygular.These model classes implement the core Identity interfaces defining user and role objects. Veritabanındaki tablolar ve sütunlar bu model sınıflarını temel alır.The tables and the columns in the database are based on these model classes. Identity v 2.1.0 ve özellikleri içindeki EntityFramework model sınıfları aşağıda tanımlanmıştırThe EntityFramework model classes in Identity v2.1.0 and their properties are as defined below

IdentityuserIdentityUser TürType IdentityroleIdentityRole IdentityuserroleIdentityUserRole IdentityuserloginIdentityUserLogin IdentityuserclaimIdentityUserClaim
KimlikId dizestring KimlikId RoleIDRoleId ProviderKeyProviderKey KimlikId
Kullanıcı adıUsername dizestring AdıName UserIDUserId UserIDUserId ClaimTypeClaimType
PasswordHashPasswordHash dizestring LoginProviderLoginProvider ClaimValueClaimValue
SecurityStampSecurityStamp dizestring Kullanıcı_kimliğiUser_Id
E-postaEmail dizestring
EmailonaylandıEmailConfirmed boolbool
PhoneNumberPhoneNumber dizestring
PhonenumberonaylandıPhoneNumberConfirmed boolbool
LockoutEnabledLockoutEnabled boolbool
LockoutEndDateLockoutEndDate DateTimeDateTime
AccessFailedCountAccessFailedCount intint

Özelliklere karşılık gelen sütunlarla bu modellerden her biri için tabloların olması gerekir.We need to have tables for each of these models with columns corresponding to the properties. Sınıflar ve tablolar arasındaki eşleme IdentityDBContext``OnModelCreating yönteminde tanımlanmıştır.The mapping between classes and tables is defined in the OnModelCreating method of the IdentityDBContext. Bu, Fluent API yapılandırma yöntemi olarak bilinir ve buradadaha fazla bilgi bulabilirsiniz.This is known as the fluent API method of configuration and more information can be found here. Sınıfların yapılandırması aşağıda belirtilmiştirThe configuration for the classes is as mentioned below

SınıfıClass TabloTable Birincil anahtarPrimary key Yabancı anahtarForeign key
IdentityuserIdentityUser AspnetUsersAspnetUsers KimlikId
IdentityroleIdentityRole AspnetRolesAspnetRoles KimlikId
IdentityuserroleIdentityUserRole AspnetUserRoleAspnetUserRole UserID + RoleIDUserId + RoleId Kullanıcı_kimliği->AspnetUsers RoleID->AspnetRolesUser_Id->AspnetUsers RoleId->AspnetRoles
IdentityuserloginIdentityUserLogin AspnetUserLoginsAspnetUserLogins ProviderKey + UserID + LoginProviderProviderKey+UserId + LoginProvider UserID->AspnetUsersUserId->AspnetUsers
IdentityUserClaimIdentityUserClaim AspnetUserClaimsAspnetUserClaims KimlikId Kullanıcı_kimliği->AspnetUsersUser_Id->AspnetUsers

Bu bilgilerle, yeni tablolar oluşturmak için SQL deyimleri oluşturuyoruz.With this information we can create SQL statements to create new tables. Her bir ifadeyi ayrı ayrı yazabilir veya daha sonra gerektiği şekilde düzenleyebilmemiz için EntityFramework PowerShell komutlarını kullanarak tüm betiği oluşturabilirsiniz.We can either write each statement individually or generate the entire script using EntityFramework PowerShell commands which we can then edit as required. Bunu yapmak için, VS 'de Görünüm veya Araçlar menüsünden Paket Yöneticisi konsolunu açınTo do this, in VS open the Package Manager Console from the View or Tools menu

  • EntityFramework geçişlerini etkinleştirmek için "Enable-geçişler" komutunu çalıştırın.Run command "Enable-Migrations" to enable EntityFramework migrations.
  • /Vbiçinde C#veritabanını oluşturmak için ilk kurulum kodunu oluşturan "Add-geçiş Initial" komutunu çalıştırın.Run command "Add-migration initial" which creates the initial setup code to create the database in C#/VB.
  • Son adım, model sınıflarına dayalı olarak SQL betiğini üreten "güncelleştirme-veritabanı – komut dosyası" komutunu çalıştırmlarıdır.The final step is to run "Update-Database –Script" command that generates the SQL script based on the model classes.

Uygulamanın kimlik veri deposu olarak SQLite kullanması durumunda bazı komutlar desteklenmez.Some commands aren't supported if the app uses SQLite as its Identity data store. Veritabanı altyapısından sınırlamalar nedeniyle Alter komutlar aşağıdaki özel durumu oluşturur:Due to limitations in the database engine, Alter commands throw the following exception:

"System. NotSupportedException: SQLite bu geçiş işlemini desteklemiyor.""System.NotSupportedException: SQLite does not support this migration operation."

Geçici bir çözüm olarak, tabloları değiştirmek için veritabanında Code First geçişleri çalıştırın.As a work around, run Code First migrations on the database to change the tables.

Bu veritabanı oluşturma betiği, yeni sütun eklemek ve veri kopyalamak için ek değişiklikler yapmakta olduğumuz bir başlangıç olarak kullanılabilir.This database generation script can be used as a start where we'll be making additional changes to add new columns and copy data. Bunun avantajı, model sınıfları kimlik sürümlerinin gelecek sürümleri için değişiklik yaparken, EntityFramework tarafından veritabanı şemasını değiştirmek için kullanılan _MigrationHistory tablosunu oluşturmamız.The advantage of this is that we generate the _MigrationHistory table which is used by EntityFramework to modify the database schema when the model classes change for future versions of Identity releases.

SQL üyeliği kullanıcı bilgilerinin, kimlik Kullanıcı modeli sınıfındaki e-posta, parola denemeleri, son oturum açma tarihi, son kilit kapatma tarihi vb. gibi diğer özellikleri de vardır. Bu, yararlı bilgiler ve kimlik sistemine taşınmasını istiyoruz.The SQL membership user information had other properties in addition to the ones in the Identity user model class namely email, password attempts, last login date, last lock-out date etc. This is useful information and we would like it to be carried over to the Identity system. Bu, Kullanıcı modeline ek özellikler eklenerek ve bunları veritabanındaki tablo sütunlarına geri eşleyerek yapılabilir.This can be done by adding additional properties to the user model and mapping them back to the table columns in the database. Bunu, IdentityUser modelini alt sınıflara uygulayan bir sınıf ekleyerek yapabiliriz.We can do this by adding a class that subclasses the IdentityUser model. Bu özel sınıfa özellikleri ekleyebiliyoruz ve tabloyu oluştururken karşılık gelen sütunları eklemek için SQL betiğini düzenleyebiliriz.We can add the properties to this custom class and edit the SQL script to add the corresponding columns when creating the table. Bu sınıfın kodu, makalesinde daha ayrıntılı olarak açıklanmıştır.The code for this class is described further in the article. Yeni özellikler eklendikten sonra AspnetUsers tablosu oluşturmaya yönelik SQL betiğiThe SQL script for creating the AspnetUsers table after adding the new properties would be

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]),
);

Daha sonra, mevcut bilgileri SQL üyelik veritabanından kimlik için yeni eklenen tablolara kopyalamanız gerekir.Next we need to copy the existing information from the SQL membership database to the newly added tables for Identity. Bu, verileri doğrudan bir tablodan diğerine kopyalayarak SQL üzerinden yapılabilir.This can be done through SQL by copying data directly from one table to another. Tablo satırlarına veri eklemek için INSERT INTO [Table] yapısını kullanırız.To add data into the rows of table, we use the INSERT INTO [Table] construct. Başka bir tablodan kopyalamak için SELECT ifadesiyle birlikte INSERT INTO ifadesini kullanabiliriz.To copy from another table we can use the INSERT INTO statement along with the SELECT statement. Aspnet_kullanıcıları ve ASPNET_üyelik tablolarını sorgulamak ve verileri aspnetusers tablosuna kopyalamak için gereken tüm Kullanıcı bilgilerini almak için.To get all the user information we need to query the aspnet_Users and aspnet_Membership tables and copy the data to the AspNetUsers table. JOIN ve LEFT OUTER JOIN deyimleriyle birlikte INSERT INTO ve SELECT kullanırız.We use the INSERT INTO and SELECT along with JOIN and LEFT OUTER JOIN statements. Tablolar arasında veri sorgulama ve kopyalama hakkında daha fazla bilgi için Bu bağlantıya başvurun.For more information about querying and copying data between tables, refer to this link. Ayrıca, SQL üyeliğinde varsayılan olarak buna eşlenen hiçbir bilgi olmadığından, AspnetUserLogins ve Aspnetuserclaim tabloları ile başlamak için boştur.Additionally the AspnetUserLogins and AspnetUserClaims tables are empty to begin with since there is no information in SQL membership that maps to this by default. Yalnızca kullanıcılar ve roller için kopyalanmış bilgiler kullanılır.The only information copied is for users and roles. Önceki adımlarda oluşturulan proje için, bilgileri kullanıcılar tablosuna kopyalamak üzere SQL sorgusu şöyle olacaktırFor the project created in the previous steps, the SQL query to copy information to the users table would be

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;

Yukarıdaki SQL ifadesinde, aspnet_Users ve ASPNET_Membership tablolarından her bir kullanıcı hakkında bilgi, aspnetusers tablosunun sütunlarına kopyalanır.In the above SQL statement, information about each user from the aspnet_Users and aspnet_Membership tables is copied into the columns of the AspnetUsers table. Burada yapılan tek değişiklik, parolayı kopyalayacağız.The only modification done here is when we copy the password. SQL üyeliğindeki parolalara yönelik şifreleme algoritması ' password, ' ve ' PasswordFormat ' kullandı, bu sayede parolanın kimliğe göre şifresini çözmek için kullanılabilmesi için onu karma parola ile birlikte kopyalayacağız.Since the encryption algorithm for passwords in SQL membership used 'PasswordSalt' and 'PasswordFormat', we copy that too along with the hashed password so that it can be used to decrypt the password by Identity. Bu, özel bir parola karmacısı oluştururken makalede daha ayrıntılı olarak açıklanmaktadır.This is explained further in the article when hooking up a custom password hasher.

Bu betik dosyası bu örneğe özeldir.This script file is specific to this sample. Geliştiriciler, ek tablolar içeren uygulamalar için, Kullanıcı modeli sınıfına ek özellikler eklemek ve bunları AspnetUsers tablosundaki sütunlarla eşlemek için benzer bir yaklaşımı izleyebilir.For applications which have additional tables, developers can follow a similar approach to add additional properties on the user model class and map them to columns in the AspnetUsers table. Betiği çalıştırmak içinTo run the script,

  1. Sunucu Gezgini açın.Open Server Explorer. Tabloları göstermek için ' ApplicationServices ' bağlantısını genişletin.Expand the 'ApplicationServices' connection to display the tables. Tablolar düğümüne sağ tıklayın ve ' yeni sorgu ' seçeneğini belirleyinRight click on the Tables node and select the 'New Query' option

  2. Sorgu penceresinde, tüm SQL betiğini kopyalayıp geçişler. SQL dosyasından yapıştırın.In the query window, copy and paste the entire SQL script from the Migrations.sql file. Komut dosyasını ' Yürüt ' ok düğmesine vurarak çalıştırın.Run the script file by hitting the 'Execute' arrow button.

    Sunucu Gezgini penceresini yenileyin.Refresh the Server Explorer window. Veritabanında beş yeni tablo oluşturulur.Five new tables are created in the database.

    SQL üyelik tablolarındaki bilgilerin yeni kimlik sistemine nasıl eşlendiğine aşağıda verilmiştir.Below is how the information in the SQL membership tables are mapped to the new Identity system.

    ASPNET_rolleri--> AspNetRolesaspnet_Roles --> AspNetRoles

    netUsers ve ASP_netMembership ile ASP_--> AspNetUsersasp_netUsers and asp_netMembership --> AspNetUsers

    ASPNET_Userınroles--> AspNetUserRolesaspnet_UserInRoles --> AspNetUserRoles

    Yukarıdaki bölümde açıklandığı gibi, Aspnetuserclaim ve AspNetUserLogins tabloları boştur.As explained in the above section, the AspNetUserClaims and AspNetUserLogins tables are empty. AspNetUser tablosundaki ' ayrıştırıcı ' alanı, bir sonraki adım olarak tanımlanan model sınıfı adıyla eşleşmelidir.The 'Discriminator' field in the AspNetUser table should match the model class name which is defined as a next step. Ayrıca, PasswordHash sütunu ' şifreli parola | parola anahtar | parola biçimi ' biçiminde olur.Also the PasswordHash column is in the form 'encrypted password |password salt|password format'. Bu, eski parolaları yeniden kullanabilmeniz için özel SQL üyelik şifreleme mantığını kullanmanıza olanak sağlar.This enables you to use special SQL membership crypto logic so that you can reuse old passwords. Bu makalede daha sonra makalesinde açıklanmaktadır.That is explained in later in the article.

Modeller ve üyelik sayfaları oluşturmaCreating models and membership pages

Daha önce belirtildiği gibi, kimlik özelliği, varsayılan olarak hesap bilgilerini depolamak için veritabanı ile konuşmak üzere Entity Framework kullanır.As mentioned earlier, the Identity feature uses Entity Framework to talk to the database for storing account information by default. Tablodaki mevcut verilerle çalışmak için, tablolara geri eşlenen ve bunları kimlik sisteminde bağlayan model sınıfları oluşturmanız gerekir.To work with existing data in the table, we need to create model classes which map back to the tables and hook them up in the Identity system. Kimlik sözleşmesinin bir parçası olarak model sınıfları, Identity. Core dll dosyasında tanımlanan arabirimleri uygulamalıdır ya da Microsoft. AspNet. Identity. EntityFramework içinde bulunan bu arabirimlerin mevcut uygulamasını genişletebilir.As part of the Identity contract, the model classes should either implement the interfaces defined in the Identity.Core dll or can extend the existing implementation of these interfaces available in Microsoft.AspNet.Identity.EntityFramework.

Örneğimizde, AspNetRoles, Aspnetuserclaim, AspNetLogins ve AspNetUserRole tablolarında, kimlik sisteminin mevcut uygulamasına benzer sütunlar bulunur.In our sample, the AspNetRoles, AspNetUserClaims, AspNetLogins and AspNetUserRole tables have columns that are similar to the existing implementation of the Identity system. Bu nedenle, bu tablolarla eşlemek için mevcut sınıfları yeniden kullanabiliriz.Hence we can reuse the existing classes to map to these tables. AspNetUser tablosunda, SQL üyelik tablolarından ek bilgileri depolamak için kullanılan bazı ek sütunlar bulunur.The AspNetUser table has some additional columns which are used to store additional information from the SQL membership tables. Bu, mevcut ' ıdentityuser ' uygulamasını genişleten ve ek özellikleri ekleyen bir model sınıfı oluşturularak eşleştirilebilir.This can be mapped by creating a model class that extend the existing implementation of 'IdentityUser' and add the additional properties.

  1. Projede modeller klasörü oluşturun ve bir sınıf kullanıcısı ekleyin.Create a Models folder in the project and add a class User. Sınıfın adı ' AspnetUsers ' tablosunun ' ayrıştırıcı ' sütununda eklenen verilerle eşleşmelidir.The name of the class should match the data added in the 'Discriminator' column of 'AspnetUsers' table.

    Kullanıcı sınıfı, Microsoft. Aspnet. Identity. EntityFramework dll dosyasında bulunan ıdentityuser sınıfını genişletmelidir.The User class should extend the IdentityUser class found in the Microsoft.AspNet.Identity.EntityFramework dll. Bir sınıf içinde AspNetUser sütunlarına geri eşlenen özellikler bildirin.Declare the properties in class that map back to the AspNetUser columns. Özellik KIMLIĞI, Kullanıcı adı, PasswordHash ve SecurityStamp, ıdentityuser içinde tanımlanmıştır ve bu nedenle atlanır.The properties ID, Username, PasswordHash and SecurityStamp are defined in the IdentityUser and so are omitted. Aşağıda, tüm özelliklerine sahip olan Kullanıcı sınıfının kodu verilmiştirBelow is the code for the User class that has all the properties

    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; }
    }
    
  2. Modellerdeki verileri tablolara geri kalıcı hale getirmek ve modelleri doldurmak üzere tablolardan veri almak için Entity Framework DbContext sınıfı gerekir.An Entity Framework DbContext class is required in order to persist data in models back to tables and retrieve data from tables to populate the models. Microsoft. Aspnet. Identity. EntityFramework dll, bilgileri almak ve depolamak için kimlik tablolarıyla etkileşim kuran ıdentitydbcontext sınıfını tanımlar.Microsoft.AspNet.Identity.EntityFramework dll defines the IdentityDbContext class which interacts with the Identity tables to retrieve and store information. Identitydbcontext<Tuser>, ıdentityuser sınıfını genişleten herhangi bir sınıf olabilen bir ' TUser ' sınıfı alır.The IdentityDbContext<tuser> takes a 'TUser' class which can be any class that extends the IdentityUser class.

    1. adımda oluşturulan ' user ' sınıfını geçirerek ' modeller ' klasörü altında ıdentitydbcontext ' i genişleten yeni bir ApplicationDBContext sınıfı oluşturunCreate a new class ApplicationDBContext that extends IdentityDbContext under the 'Models' folder, passing in the 'User' class created in step 1

    public class ApplicationDbContext : IdentityDbContext<User>
    {
            
    }
    
  3. Yeni kimlik sistemindeki kullanıcı yönetimi, Microsoft. Aspnet. Identity. EntityFramework dll 'de tanımlanan usermanager<tuser> sınıfı kullanılarak yapılır.User management in the new Identity system is done using the UserManager<tuser> class defined in the Microsoft.AspNet.Identity.EntityFramework dll. UserManager 'ı genişleten, 1. adımda oluşturulan ' user ' sınıfını geçirerek, özel bir sınıf oluşturuyoruz.We need to create a custom class that extends UserManager, passing in the 'User' class created in step 1.

    Modeller klasöründe, UserManager<kullanıcıyı genişleten yeni bir UserManager sınıfı oluşturun>In the Models folder create a new class UserManager that extends UserManager<user>

    public class UserManager : UserManager<User>
    {
            
    }
    
  4. Uygulama kullanıcılarının parolaları şifrelenir ve veritabanında depolanır.The passwords of the users of the application are encrypted and stored in the database. SQL üyeliğinde kullanılan şifre algoritması, yeni kimlik sisteminden farklı.The crypto algorithm used in SQL membership is different from the one in the new Identity system. Eski parolaları yeniden kullanmak için, yeni kullanıcılar için kimlik ' de şifre algoritmasını kullanırken eski kullanıcılar SQL üyelik algoritmasını kullanarak oturum açarken parolaların şifresini seçmeli olarak çözmemiz gerekir.To reuse old passwords we need to selectively decrypt passwords when old users log in using the SQL memberships algorithm while using the crypto algorithm in Identity for the new users.

    UserManager sınıfı ' ıpasswordhasher ' arabirimini uygulayan bir sınıfın örneğini depolayan ' PasswordHasher ' özelliğine sahiptir.The UserManager class has a property 'PasswordHasher' which stores an instance of a class that implements the 'IPasswordHasher' interface. Bu, Kullanıcı kimlik doğrulama işlemleri sırasında parolaları şifrelemek/şifrelerini çözmek için kullanılır.This is used to encrypt/decrypt passwords during user authentication transactions. Adım 3 ' te tanımlanan UserManager sınıfında, SQLPasswordHasher adlı yeni bir sınıf oluşturun ve aşağıdaki kodu kopyalayın.In the UserManager class defined in step 3, create a new class SQLPasswordHasher and copy the below code.

    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);
        }
    

    System. Text ve System. Security. Cryptography ad alanlarını içeri aktararak derleme hatalarını çözün.Resolve the compilation errors by importing the System.Text and System.Security.Cryptography namespaces.

    EncodePassword yöntemi, parolayı varsayılan SQL üyelik şifre uygulamasına göre şifreler.The EncodePassword method encrypts the password according to the default SQL membership crypto implementation. Bu, System. Web dll 'den alınmıştır.This is taken from the System.Web dll. Eski uygulama özel bir uygulama kullanıyorsa buraya yansıtılmalıdır.If the old app used a custom implementation then it should be reflected here. Belirli bir parolayı karma hale getirmek için Encodepassword metodunu kullanan iki diğer yöntem Hashpassword ve verifyhashedpassword tanımladık veya veritabanında mevcut olan bir düz metin parolasının doğrulanması gerekir.We need to define two other methods HashPassword and VerifyHashedPassword that use the EncodePassword method to hash a given password or verify a plain text password with the one existing in the database.

    SQL üyelik sistemi, parolalarını kaydederken veya değiştirdiklerinde kullanıcılar tarafından girilen parolayı karma hale almak için PasswordHash, Passwordanahtar ve PasswordFormat kullandı.The SQL membership system used PasswordHash, PasswordSalt and PasswordFormat to hash the password entered by users when they register or change their password. Geçiş sırasında, tüm üç alan, ' | ' karakteriyle ayrılmış olan AspNetUser tablosundaki PasswordHash sütununda depolanır.During the migration all the three fields are stored in the PasswordHash column in the AspNetUser table separated by the '|' character. Bir Kullanıcı oturum açtığında ve parolada bu alanlar varsa, parolayı denetlemek için SQL üyelik şifre ' nu kullanırız; Aksi takdirde, parolayı doğrulamak için kimlik sisteminin varsayılan şifresini kullanırız.When a user logs in and the password has these fields, we use the SQL membership crypto to check the password; otherwise we use the Identity system's default crypto to verify the password. Bu sayede, uygulama geçirildikten sonra eski kullanıcıların parolalarını değiştirmesi gerekmez.This way old users would not have to change their passwords once the app is migrated.

  5. UserManager sınıfı için oluşturucuyu bildirin ve bunu oluşturucudaki özelliğe SQLPasswordHasher olarak geçirin.Declare the constructor for the UserManager class and pass this as the SQLPasswordHasher to the property in the constructor.

    public UserManager()
                : base(new UserStore<User>(new ApplicationDbContext()))
    {
                this.PasswordHasher = new SQLPasswordHasher();
    }
    

Yeni hesap yönetimi sayfaları oluşturCreate new account management pages

Geçiş içindeki bir sonraki adım, bir kullanıcının kaydolmasına ve oturum açmasına izin verecek hesap yönetimi sayfaları eklemektir.The next step in the migration is to add account management pages that will let a user register and log in. SQL üyeliğinden eski hesap sayfaları, yeni kimlik sistemiyle çalışmayan denetimleri kullanır.The old account pages from SQL membership use controls that don't work with the new Identity system. Yeni Kullanıcı Yönetimi sayfalarını eklemek için, projeyi zaten oluşturduğumuz ve NuGet paketlerini eklediğimiz için, bu bağlantıdaki öğreticiyi https://www.asp.net/identity/overview/getting-started/adding-aspnet-identity-to-an-empty-or-existing-web-forms-project ' Web Forms uygulamanıza Kullanıcı ekleme ' adımından başlayarakTo add the new user management pages follow the tutorial at this link https://www.asp.net/identity/overview/getting-started/adding-aspnet-identity-to-an-empty-or-existing-web-forms-project starting from the step 'Adding Web Forms for registering users to your application' since we have already created the project and added the NuGet packages.

Burada, örnek için, burada yaptığımız projeyle birlikte çalışmak üzere bazı değişiklikler yapmanız gerekiyor.We need to make some changes for the sample to work with the project we have here.

  • Register.aspx.cs ve Login.aspx.cs kodu sınıflarının arkasında bir kullanıcı oluşturmak için kimlik paketlerindeki UserManager kullanır.The Register.aspx.cs and Login.aspx.cs code behind classes use the UserManager from the Identity packages to create a User. Bu örnekte, daha önce bahsedilen adımları izleyerek modeller klasörüne eklenen UserManager 'ı kullanın.For this example use the UserManager added in the Models folder by following the steps mentioned earlier.

  • Register.aspx.cs içinde ıdentityuser yerine oluşturulan kullanıcı sınıfını ve Login.aspx.cs arka plan kodu sınıflarını kullanın.Use the User class created instead of the IdentityUser in Register.aspx.cs and Login.aspx.cs code behind classes. Bu, Özel Kullanıcı sınıfımızda kimlik sistemine kanca oluşturur.This hooks in our custom user class into the Identity system.

  • Veritabanının oluşturulacağı bölüm atlanabilir.The part to create the database can be skipped.

  • Geliştiricinin Yeni Kullanıcı için ApplicationId 'yi geçerli uygulama KIMLIĞIYLE eşleşecek şekilde ayarlaması gerekir.The developer needs to set the ApplicationId for the new user to match the current application ID. Bu, Register.aspx.cs sınıfında bir kullanıcı nesnesi oluşturulmadan ve Kullanıcı oluşturmadan önce ayarlanarak önce bu uygulama için ApplicationId sorgulanarak yapılabilir.This can be done by querying the ApplicationId for this application before a user object is created in the Register.aspx.cs class and setting it before creating user.

    Örnek:Example:

    Register.aspx.cs sayfasında, ASPNET_uygulamalar tablosunu sorgulamak ve uygulama adına göre uygulama kimliğini almak için bir yöntem tanımlayınDefine a method in Register.aspx.cs page to query the aspnet_Applications table and get the application Id according to application name

    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();
        }
    }
    

    Şimdi bunu Kullanıcı nesnesinde ayarla ' yı alNow get set this on the user object

    var currentApplicationId = GetApplicationID();
    
    User user = new User() { UserName = Username.Text,
    ApplicationId=currentApplicationId, …};
    

Mevcut bir kullanıcının oturumu açmak için eski Kullanıcı adı ve parolayı kullanın.Use the old username and password to login an existing user. Yeni bir kullanıcı oluşturmak için kayıt sayfasını kullanın.Use the Register page to create a new user. Ayrıca, kullanıcıların rollerde beklendiği gibi olduğunu doğrulayın.Also verify that the users are in roles as expected.

Kimlik sistemine taşıma, kullanıcının uygulamaya açık kimlik doğrulaması (OAuth) eklemesini sağlar.Porting to the Identity system helps the user add Open Authentication (OAuth) to the application. Lütfen bu örneğe OAuth etkin olan örneği inceleyin.Please refer to the sample here which has OAuth enabled.

Sonraki AdımlarNext Steps

Bu öğreticide, kullanıcıların SQL üyeliğinden ASP.NET Identity için bağlantı noktası alma, ancak profil verileri için bağlantı noktası yoktu.In this tutorial we showed how to port users from SQL membership to ASP.NET Identity, but we didn't port Profile data. Sonraki öğreticide, SQL üyeliğinden yeni kimlik sistemine profil verilerini taşıma sayfasına bakacağız.In the next tutorial we'll look into porting Profile data from SQL membership to the new Identity system.

Bu makalenin en altında geri bildirim alabilirsiniz.You can leave feedback at the bottom of this article.

Makaleyi gözden geçirmek için Tom Dykstra ve Rick Anderson için teşekkürler.Thanks to Tom Dykstra and Rick Anderson for reviewing the article.