Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Core Identity Documentation Updates #5889

Merged
merged 50 commits into from
May 4, 2018
Merged
Show file tree
Hide file tree
Changes from 10 commits
Commits
Show all changes
50 commits
Select commit Hold shift + click to select a range
86ecc0f
Merge pull request #1 from aspnet/master
isaac2004 Oct 27, 2017
3e02c76
Merge pull request #2 from aspnet/master
isaac2004 Nov 1, 2017
08fbd77
Merge pull request #3 from aspnet/master
isaac2004 Nov 11, 2017
3ea3551
Merge pull request #4 from aspnet/master
isaac2004 Jan 16, 2018
9fec852
Merge pull request #5 from aspnet/master
isaac2004 Jan 17, 2018
3f95071
Merge pull request #6 from aspnet/master
isaac2004 Mar 16, 2018
cfc76bb
Merge pull request #8 from aspnet/master
isaac2004 Apr 4, 2018
546ed1e
intiial commit for membership to Core Identity
isaacrlevin Apr 5, 2018
5363917
Update membership-to-core-identity.md
isaac2004 Apr 5, 2018
1df5d8e
fix sql script
isaac2004 Apr 5, 2018
07960fa
updates for Barry
isaacrlevin Apr 24, 2018
e33d5c9
Style guide changes
scottaddie Apr 24, 2018
f969e56
udpates to Migration Index Node and MVC Walkthrough
isaacrlevin Apr 26, 2018
6965f50
Merge branch '974-work' of https://github.com/isaac2004/Docs into 974…
isaacrlevin Apr 26, 2018
5acdc99
updates to configuration and sample
isaacrlevin Apr 26, 2018
1be925b
fixes to MVC steps
isaacrlevin Apr 26, 2018
54a8aa6
udpates to proper to core identity doc and sample
isaacrlevin Apr 26, 2018
29a4a5f
image resizing
isaacrlevin Apr 26, 2018
723ae5d
updates to webapi
isaacrlevin Apr 30, 2018
b15e35e
Merge branch 'master' into 974-work
isaac2004 Apr 30, 2018
e7c86bf
update to error section
isaacrlevin Apr 30, 2018
61beeca
Minor tweaks to mvc.md
scottaddie May 2, 2018
808a14b
Change snippet type
scottaddie May 2, 2018
eb8c178
Merge branch '974-work' of https://github.com/isaac2004/Docs into 974…
isaacrlevin May 3, 2018
d76c464
remove references to bower in samples/readmes
isaacrlevin May 3, 2018
bfdfc8e
udpates for Scott
isaacrlevin May 3, 2018
e328438
updates to TOC
isaacrlevin May 3, 2018
173b353
updates
isaacrlevin May 3, 2018
908239c
Minor tweaks to membership-to-core-identity.md
scottaddie May 3, 2018
8a7f405
updates
isaacrlevin May 3, 2018
afb8d77
Merge branch '974-work' of https://github.com/isaac2004/Docs into 974…
isaacrlevin May 3, 2018
f749204
fix namespace
isaacrlevin May 3, 2018
2b3f72c
Minor verbiage tweaks
scottaddie May 3, 2018
f1153d2
Simplify link title in TOC
scottaddie May 3, 2018
d68623e
Shorten link title again
scottaddie May 3, 2018
28a2155
Fix indentation of PackageReference node
scottaddie May 3, 2018
a93ba8f
Quick UE edit
scottaddie May 3, 2018
70fc1ec
Minor tweaks to configuration.md
scottaddie May 3, 2018
878f61f
Remove unnecessary screenshots
scottaddie May 3, 2018
c6bee79
remove files
isaacrlevin May 3, 2018
c105903
Merge branch '974-work' of https://github.com/isaac2004/Docs into 974…
isaacrlevin May 3, 2018
9f56a01
Remove extra word
scottaddie May 3, 2018
6b00da0
Verbiage tweak
scottaddie May 3, 2018
bc47be9
Fix broken link
scottaddie May 3, 2018
44de751
Minor tweaks to mvc.md
scottaddie May 3, 2018
2489d7b
Merge branch 'master' into 974-work
scottaddie May 3, 2018
63c84a1
Improve readability of _Layout.cshtml
scottaddie May 4, 2018
46f11ba
Minor tweaks to mvc.md
scottaddie May 4, 2018
efa9288
remove extra space
isaacrlevin May 4, 2018
f29c0d0
Fix indentation issues
scottaddie May 4, 2018
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Empty file.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
190 changes: 190 additions & 0 deletions aspnetcore/migration/proper-to-2x/membership-to-core-identity.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,190 @@
---
title: Migrate from ASP.NET Membership to ASP.NET Core 2.0 Identity
author: isaac2004
description: Migrate existing ASP.NET Framework Applications using Membership Authentication to ASP.NET Core 2.0 Identity
ms.date: 04/04/2018
ms.prod: asp.net-core
ms.technology: aspnet
ms.topic: article
uid: migration/proper-to-2x/membership-to-core-identity
---
# Migrate from ASP.NET Membership Authentication to ASP.NET Core 2.0 Identity

By [Isaac Levin](https://isaaclevin.com)

This article serves as a reference guide for migrating the database schema for ASP.NET applications using Membership Authentication to ASP.NET Core 2 Identity.

## Prerequisites

**Note:** This document provides the steps needed to migrate the database schema for ASP.NET Membership-based Applications to the database schema used for ASP.NET Core Identity. For more information about migrating from ASP.NET Membership-based Authentication to ASP.NET Identity, see [Migrating an Existing Website from SQL Membership to ASP.NET Identity](../../../aspnet/identity/overview/migrations/migrating-an-existing-website-from-sql-membership-to-aspnet-identity.md). For more information about ASP.NET Core 2 Identity, see [Introduction to Identity on ASP.NET Core](xref:security/authentication/identity)

## Review of Membership Schema

Prior to ASP.NET 2.0, developers were tasked with creating the entire Authentication and Authorization process for thier applications. With ASP.NET 2.0, Membership was introduced, providing a boilerplate solution to handling Security within ASP.NET Applicaitons. Developers were now able to bootstrap a schema into a SQL Server database with the [aspnet_regsql.exe](https://msdn.microsoft.com/library/ms229862.aspx) command. After running this command, the following tables were created in the database.

![Membership Tables](identity/_static/membership-tables.png)

For existing applications to be migrated to ASP.NET Core 2 Identity, the data in these tables will need to be migrated to the tables used by the new Identity schema.

## ASP.NET Core Identity 2 Schema

For developers new to ASP.NET Core 2, it is highly reccommended to review the documentation starting at [Introduction to ASP.NET Core](xref:index). ASP.NET Core 2 follows the [Identity](../../../aspnet/identity/index) principle introduced in ASP.NET 4.5. Though the princible is shared, the implementation between the frameworks is different, even between versions of ASP.NET Core (see [Migrate authentication and Identity to ASP.NET Core 2.0](xref:migration/1x-to-2x/index)).

The fastest way to view the schema for ASP.NET Core 2 Identity is to create a new ASP.NET Core 2 Application using Visual Studio 2017.

* From Visual Studio **File** menu, select **New** > **Project**
* Create a new ASP.NET Core Web Application. Name the project **CoreIdentitySample**.

![File New Project](identity/_static/filenew.png)

* Select **ASP.NET Core 2.0** in the dropdown, and then select **Web Application** (this will create a [Razor Pages Application](xref:mvc/razor-pages/index)). Before clicking **OK**, click **Change Authentication**

![New Web Core Project](identity/_static/new-web-core.png)

* Choose **Individual User Accounts** for the Identity templates. Finally, click **OK**, than **OK**. Visual Studio will create a project using the Core Identity template.

![Change Auth](identity/_static/change-auth.png)

ASP.NET Core 2 Identity uses [Entity Framework Core](https://docs.microsoft.com/ef/core) to interact with the database that holds the Authentication data. In order for the newly created application to work, there needs to be a database to store this data. After creating a new application, the fastest way to inspect the schema in a database environment is to Migrate the Entity Framework Code First Schema to a database hosted either locally or elsewhere. Please review the documentation specified above for more information if interested. To create a database with the Identity Core Schema, run the following command `Package Manager Console`, which is located in **Tools** > **Nuget Package Manager** > **Package Manager Console**

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will people who have never used EF understand "Migrate the Entity Framework Code First Schema"? Should this be "create the database using Entity Framework migrations"?

![Package Manager Console](identity/_static/package-manage-console.png)

Package Manager Console allows us to run Entity Framework commands inside of Visual Studio. The command to create a database in this context is `Update-Database`.

**Note**: Entity Framework commands use the connection string for the database specified in **appsettings.json**. The below connection string targets a database in *localhost* called *asp-net-core-identity*. In this setting, Entity Framework is configured to use the **DefaultConnection** connection string.

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

This command will "Seed" the database specified with the schema and any data needed for intialization of the application. The following image is the table structure that is created with the above steps.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

seed, to me, means insertion of data, not the creation of the schema. The internet agrees. https://en.wikipedia.org/wiki/Database_seeding. So, not seeding. I don't think any actual data is created by default here.


![Identity Tables](identity/_static/identity-tables.png)

## Migrating the Schema

Observing the table structure for both Membership and Core Identity shows there are subtle differences in the table names, and upon further investigation, the fields on said tables is different as well. The pattern has changed substantially for Authentication/Authorization with ASP.NET and ASP.NET Core applications. The key objects that are still used with Identity are **Users** and **Roles**. Here are mapping table for **Users**, **Roles** and **UserRoles**.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"said tables" -> "the tables", easier to understand.


### Users

| **Identity(AspNetUsers)** | | **Membership(aspnet_Users/aspnet_Membership)** ||
| --- | --- | --- | --- | --- | --- |
| **Field Name** | **Type** | **Field Name** | **Type** |
|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

**Note**: Not all the fields are one-to-one relationships from Membership to Identity Core. The above table takes the default Membership User Schema and maps it to Identity Core Schema. If there are other custom fields that were used for Membership, those will need to be mapped manually. In this mapping, there is no map for Passwords, as both password criteria and Password Salts will not migrate between the two. **It is reccommended to leave the password blank and notify the user they will need to reset thier password.** LockoutEnd in Core Identity should be set to some date in the future if the user is locked out(this will be shown in the migration script).

## Roles

| **Identity(AspNetRoles)** | | **Membership(aspnet_Roles)** ||
| --- | --- | --- | --- | --- | --- |
| **Field Name** | **Type** | **Field Name** | **Type** |
|Id | string | RoleId | string
|Name | string | RoleName | string
|NormalizedName | string | LoweredRoleName | string

## User Roles

| **Identity(AspNetUserRoles)** | | **Membership(aspnet_UsersInRoles)** ||
| --- | --- | --- | --- | --- | --- |
| **Field Name** | **Type** | **Field Name** | **Type** |
|RoleId | string | RoleId | string
|UserId | string | UserId | string

Using the above mapping, putting together a migration script for Users and Roles is much easier. The below example assumes you have two databases on a database server; one that contains the existing ASP.NET Membership schema and data, and the other that was created using steps described earlier. Comments are included inline for more details

````sql
-- THIS SCRIPT WILL NEED TO BE RUN FROM THE CONTEXT OF THE MEMBERSHIP DB
BEGIN TRANSACTION MigrateUsersAndRoles
use aspnetdb

-- INSERT USERS
INSERT INTO coreidentity.dbo.aspnetusers
(id,
username,
normalizedusername,
passwordhash,
securitystamp,
emailconfirmed,
phonenumber,
phonenumberconfirmed,
twofactorenabled,
lockoutend,
lockoutenabled,
accessfailedcount,
email,
normalizedemail)
SELECT aspnet_users.userid,
aspnet_users.username,
aspnet_users.loweredusername,
'', --Creates an empty password since passwords do not map between the two schemas
NewID(), -- Security Stamp is a token used to verify the state of an account and is subject to change at any time. Due to this it should be intialized as a new ID
1, --EmailConfirmed is set when a new user is created and confirmed via email. Users must have this set during migration to ensure they are able to reset passwords.
aspnet_users.mobilealias,
CASE
WHEN aspnet_Users.MobileAlias is null THEN 0
ELSE 1
END, --
0, --More than likely Two Factor Authentication was not setup in Membership for users so setting as false
CASE
WHEN aspnet_membership.islockedout = 1 THEN Dateadd(year, 1000,
Sysutcdatetime())
ELSE NULL
END, -- setting lockout date to time in the future (1000 years)
aspnet_membership.islockedout,
0, --AccessFailedAccount is used to track failed logins. This is stored in membership in multiple columns. Setting to 0 arbitrarily.
aspnet_membership.email,
aspnet_membership.loweredemail
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 coreidentity.dbo.aspnetusers
ON aspnet_membership.userid = aspnetusers.id
WHERE aspnetusers.id IS NULL

-- INSERT ROLES

INSERT INTO coreIdentity.dbo.aspnetroles(id,name)
SELECT roleId,rolename
FROM aspnet_roles;

-- INSERT USER ROLES

INSERT INTO coreidentity.dbo.aspnetuserroles(userid,roleid)
SELECT userid,roleid
FROM aspnet_usersinroles;

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

COMMIT TRANSACTION MigrateUsersAndRoles
`````

After completion of this script, the Identity Core Application created earlier will be populated with Membership users. Users will need to change thier password in order to login as mentioned above.

**Note**: If the Membership system had users with usernames that did not match thier email address, there will need to be changes made to the Application created earlier to accommodate this. The default template expects UserName and Email to be the same, so in situations where they are different, the login process will be need to be modified to use UserName instead of Email.

* In the `PageModel` of the Login Page, located **Pages** > **Account** > **Login.cshtml.cs**
* Remove the `[EmailAddress]` Attribute from *Email*, and rename it *UserName*(this will require a change wherever EmailAddress is mentioned, in the *View* and *PageModel*)
* The result should look like the following

![Fixed Login](identity/_static/fixed-login.png)

## Next Steps

In this tutorial we showed how to port users from SQL membership to ASP.NET Core 2 Identity. For more information regarding Core 2 Identity, please refer to [Introduction to Identity](xref:security/authentication/identity)