Migrate Authentication and Identity to ASP.NET Core
By Steve Smith
In the previous article, we migrated configuration from an ASP.NET MVC project to ASP.NET Core MVC. In this article, we migrate the registration, login, and user management features.
Configure Identity and Membership
In ASP.NET MVC, authentication and identity features are configured using ASP.NET Identity in Startup.Auth.cs
and IdentityConfig.cs
, located in the App_Start folder. In ASP.NET Core MVC, these features are configured in Startup.cs
.
Install the following NuGet packages:
Microsoft.AspNetCore.Identity.EntityFrameworkCore
Microsoft.AspNetCore.Authentication.Cookies
Microsoft.EntityFrameworkCore.SqlServer
Warning
This article shows the use of connection strings. With a local database the user doesn't have to be authenticated, but in production, connection strings sometimes include a password to authenticate. A resource owner password credential (ROPC) is a security risk that should be avoided in production databases. Production apps should use the most secure authentication flow available. For more information on authentication for apps deployed to test or production environments, see Secure authentication flows.
In Startup.cs
, update the Startup.ConfigureServices
method to use Entity Framework and Identity services:
public void ConfigureServices(IServiceCollection services)
{
// Add EF services to the services container.
services.AddDbContext<ApplicationDbContext>(options =>
options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
services.AddIdentity<ApplicationUser, IdentityRole>()
.AddEntityFrameworkStores<ApplicationDbContext>()
.AddDefaultTokenProviders();
services.AddMvc();
}
At this point, there are two types referenced in the above code that we haven't yet migrated from the ASP.NET MVC project: ApplicationDbContext
and ApplicationUser
. Create a new Models folder in the ASP.NET Core project, and add two classes to it corresponding to these types. You will find the ASP.NET MVC versions of these classes in /Models/IdentityModels.cs
, but we will use one file per class in the migrated project since that's more clear.
ApplicationUser.cs
:
using Microsoft.AspNetCore.Identity.EntityFrameworkCore;
namespace NewMvcProject.Models
{
public class ApplicationUser : IdentityUser
{
}
}
ApplicationDbContext.cs
:
using Microsoft.AspNetCore.Identity.EntityFrameworkCore;
using Microsoft.Data.Entity;
namespace NewMvcProject.Models
{
public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
{
public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)
: base(options)
{
}
protected override void OnModelCreating(ModelBuilder builder)
{
base.OnModelCreating(builder);
// Customize the ASP.NET Core Identity model and override the defaults if needed.
// For example, you can rename the ASP.NET Core Identity table names and more.
// Add your customizations after calling base.OnModelCreating(builder);
}
}
}
The ASP.NET Core MVC Starter Web project doesn't include much customization of users, or the ApplicationDbContext
. When migrating a real app, you also need to migrate all of the custom properties and methods of your app's user and DbContext
classes, as well as any other Model classes your app utilizes. For example, if your DbContext
has a DbSet<Album>
, you need to migrate the Album
class.
With these files in place, the Startup.cs
file can be made to compile by updating its using
statements:
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Hosting;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
Our app is now ready to support authentication and Identity services. It just needs to have these features exposed to users.
Migrate registration and login logic
With Identity services configured for the app and data access configured using Entity Framework and SQL Server, we're ready to add support for registration and login to the app. Recall that earlier in the migration process we commented out a reference to _LoginPartial in _Layout.cshtml
. Now it's time to return to that code, uncomment it, and add in the necessary controllers and views to support login functionality.
Uncomment the @Html.Partial
line in _Layout.cshtml
:
<li>@Html.ActionLink("Contact", "Contact", "Home")</li>
</ul>
@*@Html.Partial("_LoginPartial")*@
</div>
</div>
Now, add a new Razor view called _LoginPartial to the Views/Shared folder:
Update _LoginPartial.cshtml
with the following code (replace all of its contents):
@inject SignInManager<ApplicationUser> SignInManager
@inject UserManager<ApplicationUser> UserManager
@if (SignInManager.IsSignedIn(User))
{
<form asp-area="" asp-controller="Account" asp-action="Logout" method="post" id="logoutForm" class="navbar-right">
<ul class="nav navbar-nav navbar-right">
<li>
<a asp-area="" asp-controller="Manage" asp-action="Index" title="Manage">Hello @UserManager.GetUserName(User)!</a>
</li>
<li>
<button type="submit" class="btn btn-link navbar-btn navbar-link">Log out</button>
</li>
</ul>
</form>
}
else
{
<ul class="nav navbar-nav navbar-right">
<li><a asp-area="" asp-controller="Account" asp-action="Register">Register</a></li>
<li><a asp-area="" asp-controller="Account" asp-action="Login">Log in</a></li>
</ul>
}
At this point, you should be able to refresh the site in your browser.
Summary
ASP.NET Core introduces changes to the ASP.NET Identity features. In this article, you have seen how to migrate the authentication and user management features of ASP.NET Identity to ASP.NET Core.