---
title: Migrating Auth and Identity to ASP.NET Core 2.0
author: scottaddie
description: This article outlines the most common steps for migrating ASP.NET Core 1.x authentication and Identity to ASP.NET Core 2.0.
keywords: ASP.NET Core,Identity,authentication
ms.author: scaddie
manager: wpickett
ms.date: 08/02/2017
ms.topic: article
ms.technology: aspnet
ms.prod: asp.net-core
uid: migration/1x-to-2x/identity-2x
---
# Migrating Authentication and Identity to ASP.NET Core 2.0
By [Scott Addie](https://github.com/scottaddie) and [Hao Kung](https://github.com/HaoK)
ASP.NET Core 2.0 has a new model for authentication and [Identity](xref:security/authentication/identity) which simplifies configuration by using services. ASP.NET Core 1.x applications that use authentication or Identity can be updated to use the new model as outlined below.
## Authentication Middleware and Services
In 1.x projects, authentication is configured via middleware. A middleware method is invoked for each authentication scheme you want to support.
The following 1.x example configures Facebook authentication with Identity in *Startup.cs*:
```csharp
public void ConfigureServices(IServiceCollection services)
{
services.AddIdentity()
.AddEntityFrameworkStores();
}
public void Configure(IApplicationBuilder app, ILoggerFactory loggerfactory)
{
app.UseIdentity();
app.UseFacebookAuthentication(new FacebookOptions {
AppId = Configuration["auth:facebook:appid"],
AppSecret = Configuration["auth:facebook:appsecret"]
});
}
```
In 2.0 projects, authentication is configured via services. Each authentication scheme is registered in the `ConfigureServices` method of *Startup.cs*. The `UseIdentity` method is replaced with `UseAuthentication`.
The following 2.0 example configures Facebook authentication with Identity in *Startup.cs*:
```csharp
public void ConfigureServices(IServiceCollection services)
{
services.AddIdentity()
.AddEntityFrameworkStores();
// If you want to tweak Identity cookies, they're no longer part of IdentityOptions.
services.ConfigureApplicationCookie(options => options.LoginPath = "/Account/LogIn");
services.AddAuthentication()
.AddFacebook(options => {
options.AppId = Configuration["auth:facebook:appid"];
options.AppSecret = Configuration["auth:facebook:appsecret"];
});
}
public void Configure(IApplicationBuilder app, ILoggerFactory loggerfactory) {
app.UseAuthentication();
}
```
The `UseAuthentication` method adds a single authentication middleware component which is responsible for automatic authentication and the handling of remote authentication requests. It replaces all of the individual middleware components with a single, common middleware component.
Below are 2.0 migration instructions for each major authentication scheme.
### Cookie-based Authentication
Select one of the two options below, and make the necessary changes in *Startup.cs*:
1. Use cookies with Identity
- Replace `UseIdentity` with `UseAuthentication` in the `Configure` method:
```csharp
app.UseAuthentication();
```
- Invoke the `AddIdentity` method in the `ConfigureServices` method to add the cookie authentication services.
- Optionally, invoke the `ConfigureApplicationCookie` or `ConfigureExternalCookie` method in the `ConfigureServices` method to tweak the Identity cookie settings.
```csharp
services.AddIdentity()
.AddEntityFrameworkStores()
.AddDefaultTokenProviders();
services.ConfigureApplicationCookie(options => options.LoginPath = "/Account/LogIn");
```
2. Use cookies without Identity
- Replace the `UseCookieAuthentication` method call in the `Configure` method with `UseAuthentication`:
```csharp
app.UseAuthentication();
```
- Invoke the `AddAuthentication` and `AddCookie` methods in the `ConfigureServices` method:
```csharp
// If you don't want the cookie to be automatically authenticated and assigned to HttpContext.User,
// remove the CookieAuthenticationDefaults.AuthenticationScheme parameter passed to AddAuthentication.
services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
.AddCookie(options => {
options.LoginPath = "/Account/LogIn";
options.LogoutPath = "/Account/LogOff";
});
```
### JWT Bearer Authentication
Make the following changes in *Startup.cs*:
- Replace the `UseJwtBearerAuthentication` method call in the `Configure` method with `UseAuthentication`:
```csharp
app.UseAuthentication();
```
- Invoke the `AddJwtBearer` method in the `ConfigureServices` method:
```csharp
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(options => {
options.Audience = "http://localhost:5001/";
options.Authority = "http://localhost:5000/";
});
```
This code snippet doesn't use Identity, so the default scheme should be set by passing `JwtBearerDefaults.AuthenticationScheme` to the `AddAuthentication` method.
### OpenID Connect (OIDC) Authentication
Make the following changes in *Startup.cs*:
- Replace the `UseOpenIdConnectAuthentication` method call in the `Configure` method with `UseAuthentication`:
```csharp
app.UseAuthentication();
```
- Invoke the `AddOpenIdConnect` method in the `ConfigureServices` method:
```csharp
services.AddAuthentication(options => {
options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
})
.AddCookie()
.AddOpenIdConnect(options => {
options.Authority = Configuration["auth:oidc:authority"];
options.ClientId = Configuration["auth:oidc:clientid"];
});
```
### Facebook Authentication
Make the following changes in *Startup.cs*:
- Replace the `UseFacebookAuthentication` method call in the `Configure` method with `UseAuthentication`:
```csharp
app.UseAuthentication();
```
- Invoke the `AddFacebook` method in the `ConfigureServices` method:
```csharp
services.AddAuthentication()
.AddFacebook(options => {
options.AppId = Configuration["auth:facebook:appid"];
options.AppSecret = Configuration["auth:facebook:appsecret"];
});
```
### Google Authentication
Make the following changes in *Startup.cs*:
- Replace the `UseGoogleAuthentication` method call in the `Configure` method with `UseAuthentication`:
```csharp
app.UseAuthentication();
```
- Invoke the `AddGoogle` method in the `ConfigureServices` method:
```csharp
services.AddAuthentication()
.AddGoogle(options => {
options.ClientId = Configuration["auth:google:clientid"];
options.ClientSecret = Configuration["auth:google:clientsecret"];
});
```
### Microsoft Account Authentication
Make the following changes in *Startup.cs*:
- Replace the `UseMicrosoftAccountAuthentication` method call in the `Configure` method with `UseAuthentication`:
```csharp
app.UseAuthentication();
```
- Invoke the `AddMicrosoftAccount` method in the `ConfigureServices` method:
```csharp
services.AddAuthentication()
.AddMicrosoftAccount(options => {
options.ClientId = Configuration["auth:microsoft:clientid"];
options.ClientSecret = Configuration["auth:microsoft:clientsecret"];
});
```
### Twitter Authentication
Make the following changes in *Startup.cs*:
- Replace the `UseTwitterAuthentication` method call in the `Configure` method with `UseAuthentication`:
```csharp
app.UseAuthentication();
```
- Invoke the `AddTwitter` method in the `ConfigureServices` method:
```csharp
services.AddAuthentication()
.AddTwitter(options => {
options.ConsumerKey = Configuration["auth:twitter:consumerkey"];
options.ConsumerSecret = Configuration["auth:twitter:consumersecret"];
});
```
### Setting Default Authentication Schemes
In 1.x, the `AutomaticAuthenticate` and `AutomaticChallenge` properties were intended to be set on a single authentication scheme. There was no good way to enforce this.
In 2.0, these two properties have been removed as flags on the individual `AuthenticationOptions` instance and have moved into the base [AuthenticationOptions](/aspnet/core/api/microsoft.aspnetcore.builder.authenticationoptions) class. The properties can be configured in the `AddAuthentication` method call within the `ConfigureServices` method of *Startup.cs*:
```csharp
services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme);
```
Alternatively, use an overloaded version of the `AddAuthentication` method to set more than one property. In the following overloaded method example, the default scheme is set to `CookieAuthenticationDefaults.AuthenticationScheme`. The authentication scheme may alternatively be specified within your individual `[Authorize]` attributes or authorization policies.
```csharp
services.AddAuthentication(options => {
options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
});
```
Define a default scheme in 2.0 if one of the following conditions is true:
- You want the user to be automatically signed in
- You use the `[Authorize]` attribute or authorization policies without specifying schemes
An exception to this rule is the `AddIdentity` method. This method adds cookies for you and sets the default authenticate and challenge schemes to the application cookie `IdentityConstants.ApplicationScheme`. Additionally, it sets the default sign-in scheme to the external cookie `IdentityConstants.ExternalScheme`.
## Use HttpContext Authentication Extensions
The `IAuthenticationManager` interface is the main entry point into the 1.x authentication system. It has been replaced with a new set of `HttpContext` extension methods in the `Microsoft.AspNetCore.Authentication` namespace.
For example, 1.x projects reference an `Authentication` property:
[!code-csharp[Main](../1x-to-2x/samples/AspNetCoreDotNetCore1App/AspNetCoreDotNetCore1App/Controllers/AccountController.cs?name=snippet_AuthenticationProperty)]
In 2.0 projects, import the `Microsoft.AspNetCore.Authentication` namespace, and delete the `Authentication` property references:
[!code-csharp[Main](../1x-to-2x/samples/AspNetCoreDotNetCore2App/AspNetCoreDotNetCore2App/Controllers/AccountController.cs?name=snippet_AuthenticationProperty)]
## Windows Authentication (HTTP.sys / IISIntegration)
There are two variations of Windows authentication:
1. The host only allows authenticated users
2. The host allows both anonymous and authenticated users
The first variation described above is unaffected by the 2.0 changes.
The second variation described above is affected by the 2.0 changes. As an example, you may be allowing anonymous users into your application at the IIS or [HTTP.sys](xref:fundamentals/servers/weblistener) layer but authorizing users at the Controller level. In this scenario, set the default scheme to `IISDefaults.AuthenticationScheme` in the `ConfigureServices` method of *Startup.cs*:
```csharp
services.AddAuthentication(IISDefaults.AuthenticationScheme);
```
Failure to set the default scheme accordingly prevents the authorize request to challenge from working.
## IdentityCookieOptions Instances
A side effect of the 2.0 changes is the switch to using named options instead of cookie options instances. The ability to customize the Identity cookie scheme names is removed.
For example, 1.x projects use [constructor injection](xref:mvc/controllers/dependency-injection#constructor-injection) to pass an `IdentityCookieOptions` parameter into *AccountController.cs*. The external cookie authentication scheme is accessed from the provided instance:
[!code-csharp[Main](../1x-to-2x/samples/AspNetCoreDotNetCore1App/AspNetCoreDotNetCore1App/Controllers/AccountController.cs?name=snippet_AccountControllerConstructor&highlight=4,11)]
The aforementioned constructor injection becomes unnecessary in 2.0 projects, and the `_externalCookieScheme` field can be deleted:
[!code-csharp[Main](../1x-to-2x/samples/AspNetCoreDotNetCore2App/AspNetCoreDotNetCore2App/Controllers/AccountController.cs?name=snippet_AccountControllerConstructor)]
The `IdentityConstants.ExternalScheme` constant can be used directly:
[!code-csharp[Main](../1x-to-2x/samples/AspNetCoreDotNetCore2App/AspNetCoreDotNetCore2App/Controllers/AccountController.cs?name=snippet_AuthenticationProperty)]
## Add IdentityUser POCO Navigation Properties
The Entity Framework (EF) Core navigation properties of the base `IdentityUser` POCO (Plain Old CLR Object) have been removed. If your 1.x project used these properties, manually add them back to the 2.0 project:
```csharp
///
/// Navigation property for the roles this user belongs to.
///
public virtual ICollection> Roles { get; } = new List>();
///
/// Navigation property for the claims this user possesses.
///
public virtual ICollection> Claims { get; } = new List>();
///
/// Navigation property for this users login accounts.
///
public virtual ICollection> Logins { get; } = new List>();
```
To prevent duplicate foreign keys when running EF Core Migrations, add the following to your `IdentityDbContext` class' `OnModelCreating` method (after the `base.OnModelCreating();` call):
```csharp
protected override void OnModelCreating(ModelBuilder builder)
{
base.OnModelCreating(builder);
// Customize the ASP.NET Identity model and override the defaults if needed.
// For example, you can rename the ASP.NET Identity table names and more.
// Add your customizations after calling base.OnModelCreating(builder);
builder.Entity()
.HasMany(e => e.Claims)
.WithOne()
.HasForeignKey(e => e.UserId)
.IsRequired()
.OnDelete(DeleteBehavior.Cascade);
builder.Entity()
.HasMany(e => e.Logins)
.WithOne()
.HasForeignKey(e => e.UserId)
.IsRequired()
.OnDelete(DeleteBehavior.Cascade);
builder.Entity()
.HasMany(e => e.Roles)
.WithOne()
.HasForeignKey(e => e.UserId)
.IsRequired()
.OnDelete(DeleteBehavior.Cascade);
}
```
## Replace GetExternalAuthenticationSchemes
The synchronous method `GetExternalAuthenticationSchemes` was removed in favor of an asynchronous version. 1.x projects have the following code in *ManageController.cs*:
[!code-csharp[Main](../1x-to-2x/samples/AspNetCoreDotNetCore1App/AspNetCoreDotNetCore1App/Controllers/ManageController.cs?name=snippet_GetExternalAuthenticationSchemes)]
This method appears in *Login.cshtml* too:
[!code-cshtml[Main](../1x-to-2x/samples/AspNetCoreDotNetCore1App/AspNetCoreDotNetCore1App/Views/Account/Login.cshtml?range=62,75-84)]
In 2.0 projects, use the `GetExternalAuthenticationSchemesAsync` method:
[!code-csharp[Main](../1x-to-2x/samples/AspNetCoreDotNetCore2App/AspNetCoreDotNetCore2App/Controllers/ManageController.cs?name=snippet_GetExternalAuthenticationSchemesAsync)]
In *Login.cshtml*, the `AuthenticationScheme` property accessed in the `foreach` loop changes to `Name`:
[!code-cshtml[Main](../1x-to-2x/samples/AspNetCoreDotNetCore2App/AspNetCoreDotNetCore2App/Views/Account/Login.cshtml?range=62,75-84)]
## ManageLoginsViewModel Property Change
A `ManageLoginsViewModel` object is used in the `ManageLogins` action of *ManageController.cs*. In 1.x projects, the object's `OtherLogins` property return type is `IList`. This return type requires an import of `Microsoft.AspNetCore.Http.Authentication`:
[!code-csharp[Main](../1x-to-2x/samples/AspNetCoreDotNetCore1App/AspNetCoreDotNetCore1App/Models/ManageViewModels/ManageLoginsViewModel.cs?name=snippet_ManageLoginsViewModel&highlight=2,11)]
In 2.0 projects, the return type changes to `IList`. This new return type requires replacing the `Microsoft.AspNetCore.Http.Authentication` import with a `Microsoft.AspNetCore.Authentication` import.
[!code-csharp[Main](../1x-to-2x/samples/AspNetCoreDotNetCore2App/AspNetCoreDotNetCore2App/Models/ManageViewModels/ManageLoginsViewModel.cs?name=snippet_ManageLoginsViewModel&highlight=2,11)]
## Additional Resources
For additional details and discussion, see the [Discussion for Auth 2.0](https://github.com/aspnet/Security/issues/1338) issue on GitHub.