Migrace ověřování a Identity ASP.NET Core 2.0
ASP.NET Core 2.0 má nový model pro ověřování a Identity zjednodušuje konfiguraci pomocí služeb. ASP.NET aplikace Core 1.x, které používají ověřování, nebo Identity je možné je aktualizovat, aby používaly nový model, jak je uvedeno níže.
Aktualizace oborů názvů
V 1.x byly třídy jako a IdentityRole
IdentityUser
byly nalezeny v Microsoft.AspNetCore.Identity.EntityFrameworkCore
oboru názvů.
Ve verzi 2.0 Microsoft.AspNetCore.Identity se obor názvů stal novým home pro několik takových tříd. S výchozím Identity kódem zahrnují ApplicationUser
ovlivněné třídy a Startup
. Upravte příkazy a vyřešte using
ovlivněné odkazy.
Middleware a služby ověřování
V projektech 1.x se ověřování konfiguruje prostřednictvím middlewaru. Metoda middlewaru se vyvolá pro každé schéma ověřování, které chcete podporovat.
Následující příklad 1.x konfiguruje ověřování facebooku pomocí Identity Startup.cs
příkazu :
public void ConfigureServices(IServiceCollection services)
{
services.AddIdentity<ApplicationUser, IdentityRole>()
.AddEntityFrameworkStores<ApplicationDbContext>();
}
public void Configure(IApplicationBuilder app, ILoggerFactory loggerfactory)
{
app.UseIdentity();
app.UseFacebookAuthentication(new FacebookOptions {
AppId = Configuration["auth:facebook:appid"],
AppSecret = Configuration["auth:facebook:appsecret"]
});
}
Ve 2.0 projektech se ověřování konfiguruje prostřednictvím služeb. Každé schéma ověřování je registrováno ConfigureServices
v metodě Startup.cs
. Metoda UseIdentity
je nahrazena UseAuthentication
.
Následující příklad 2.0 konfiguruje ověřování facebooku pomocí Identity Startup.cs
příkazu :
public void ConfigureServices(IServiceCollection services)
{
services.AddIdentity<ApplicationUser, IdentityRole>()
.AddEntityFrameworkStores<ApplicationDbContext>();
// 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();
}
Metoda UseAuthentication
přidá jednu komponentu middlewaru ověřování, která zodpovídá za automatické ověřování a zpracování žádostí o vzdálené ověřování. Nahrazuje všechny jednotlivé komponenty middlewaru jednou, běžnou komponentou middlewaru.
Níže najdete pokyny pro migraci 2.0 pro každé hlavní schéma ověřování.
Cookieověřování na základě
Vyberte jednu ze dvou možností níže a proveďte potřebné změny v Startup.cs
:
Použití souborů cookie se soubory cookie Identity
UseAuthentication
NahraďteUseIdentity
metodouConfigure
:app.UseAuthentication();
Vyvolání
AddIdentity
metody vConfigureServices
metodě pro přidání cookie ověřovacích služeb.Volitelně můžete vyvolat metodu
ConfigureApplicationCookie
neboConfigureExternalCookie
metoduConfigureServices
v metodě a upravit Identitycookie nastavení.services.AddIdentity<ApplicationUser, IdentityRole>() .AddEntityFrameworkStores<ApplicationDbContext>() .AddDefaultTokenProviders(); services.ConfigureApplicationCookie(options => options.LoginPath = "/Account/LogIn");
Použití souborů cookie bez Identity
UseCookieAuthentication
Nahraďte volání metody vConfigure
metoděUseAuthentication
za :app.UseAuthentication();
Vyvolání
AddAuthentication
metod aAddCookie
metod vConfigureServices
metodě:// 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
Proveďte následující změny v Startup.cs
:
UseJwtBearerAuthentication
Nahraďte volání metody vConfigure
metoděUseAuthentication
za :app.UseAuthentication();
Vyvolání
AddJwtBearer
metody vConfigureServices
metodě:services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme) .AddJwtBearer(options => { options.Audience = "http://localhost:5001/"; options.Authority = "http://localhost:5000/"; });
Tento fragment kódu se nepoužívá Identity, takže výchozí schéma by mělo být nastaveno předáním
JwtBearerDefaults.AuthenticationScheme
metodyAddAuthentication
.
Ověřování OpenID Connect (OIDC)
Proveďte následující změny v Startup.cs
:
UseOpenIdConnectAuthentication
Nahraďte volání metody vConfigure
metoděUseAuthentication
za :app.UseAuthentication();
Vyvolání
AddOpenIdConnect
metody vConfigureServices
metodě: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"]; });
PostLogoutRedirectUri
Vlastnost vOpenIdConnectOptions
akci nahraďte :SignedOutRedirectUri
.AddOpenIdConnect(options => { options.SignedOutRedirectUri = "https://contoso.com"; });
Ověřování pomocí Facebooku
Proveďte následující změny v Startup.cs
:
UseFacebookAuthentication
Nahraďte volání metody vConfigure
metoděUseAuthentication
za :app.UseAuthentication();
Vyvolání
AddFacebook
metody vConfigureServices
metodě:services.AddAuthentication() .AddFacebook(options => { options.AppId = Configuration["auth:facebook:appid"]; options.AppSecret = Configuration["auth:facebook:appsecret"]; });
Ověřování pomocí Googlu
Proveďte následující změny v Startup.cs
:
UseGoogleAuthentication
Nahraďte volání metody vConfigure
metoděUseAuthentication
za :app.UseAuthentication();
Vyvolání
AddGoogle
metody vConfigureServices
metodě:services.AddAuthentication() .AddGoogle(options => { options.ClientId = Configuration["auth:google:clientid"]; options.ClientSecret = Configuration["auth:google:clientsecret"]; });
Ověřování pomocí účtu Microsoft
Další informace o ověřování účtu Microsoft najdete v tomto problému s GitHubem.
Proveďte následující změny v Startup.cs
:
UseMicrosoftAccountAuthentication
Nahraďte volání metody vConfigure
metoděUseAuthentication
za :app.UseAuthentication();
Vyvolání
AddMicrosoftAccount
metody vConfigureServices
metodě:services.AddAuthentication() .AddMicrosoftAccount(options => { options.ClientId = Configuration["auth:microsoft:clientid"]; options.ClientSecret = Configuration["auth:microsoft:clientsecret"]; });
Ověřování pomocí Twitteru
Proveďte následující změny v Startup.cs
:
UseTwitterAuthentication
Nahraďte volání metody vConfigure
metoděUseAuthentication
za :app.UseAuthentication();
Vyvolání
AddTwitter
metody vConfigureServices
metodě:services.AddAuthentication() .AddTwitter(options => { options.ConsumerKey = Configuration["auth:twitter:consumerkey"]; options.ConsumerSecret = Configuration["auth:twitter:consumersecret"]; });
Nastavení výchozích schémat ověřování
V 1.x AutomaticAuthenticate
byly a AutomaticChallenge
vlastnosti AuthenticationOptions základní třídy určeny k nastavení v jednom schématu ověřování. Nebyl žádný dobrý způsob, jak to vynutit.
Ve verzi 2.0 byly tyto dvě vlastnosti odebrány jako vlastnosti v jednotlivých AuthenticationOptions
instancích. Je možné je nakonfigurovat ve AddAuthentication
volání metody v rámci ConfigureServices
metody Startup.cs
:
services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme);
V předchozím fragmentu kódu je výchozí schéma nastaveno na CookieAuthenticationDefaults.AuthenticationScheme
("Cookies").
Alternativně použijte přetíženou verzi AddAuthentication
metody k nastavení více než jedné vlastnosti. V následujícím příkladu přetížené metody je výchozí schéma nastaveno na CookieAuthenticationDefaults.AuthenticationScheme
. Schéma ověřování může být případně zadáno v rámci jednotlivých [Authorize]
atributů nebo zásad autorizace.
services.AddAuthentication(options =>
{
options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
});
Definujte výchozí schéma ve verzi 2.0, pokud platí jedna z následujících podmínek:
- Chcete, aby se uživatel automaticky přihlásil.
- Použijete zásady atributu
[Authorize]
nebo autorizace bez určení schémat.
Výjimkou tohoto pravidla je AddIdentity
metoda. Tato metoda přidá soubory cookie pro vás a nastaví výchozí schémata ověřování a výzvy do aplikace cookieIdentityConstants.ApplicationScheme
. Kromě toho nastaví výchozí přihlašovací schéma na externí cookieIdentityConstants.ExternalScheme
.
Použití rozšíření ověřování HttpContext
Rozhraní IAuthenticationManager
je hlavním vstupním bodem do ověřovacího systému 1.x. V oboru názvů byla nahrazena novou sadou rozšiřujících HttpContext
metod Microsoft.AspNetCore.Authentication
.
Například projekty 1.x odkazují na Authentication
vlastnost:
// Clear the existing external cookie to ensure a clean login process
await HttpContext.Authentication.SignOutAsync(_externalCookieScheme);
Ve 2.0 projektech importujte Microsoft.AspNetCore.Authentication
obor názvů a odstraňte odkazy na Authentication
vlastnost:
// Clear the existing external cookie to ensure a clean login process
await HttpContext.SignOutAsync(IdentityConstants.ExternalScheme);
Ověřování systému Windows (HTTP.sys / IISIntegration)
Existují dvě varianty ověřování systému Windows:
Hostitel povoluje jenom ověřené uživatele. Tato varianta není ovlivněná změnami 2.0.
Hostitel umožňuje anonymním i ověřeným uživatelům. Tato varianta je ovlivněna změnami 2.0. Aplikace by například měla povolit anonymním uživatelům ve službě IIS nebo HTTP.sys vrstvě , ale autorizovat uživatele na úrovni kontroleru. V tomto scénáři nastavte výchozí schéma v
Startup.ConfigureServices
metodě.Pro Microsoft.AspNetCore.Server.IISIntegration nastavte výchozí schéma na
IISDefaults.AuthenticationScheme
:using Microsoft.AspNetCore.Server.IISIntegration; services.AddAuthentication(IISDefaults.AuthenticationScheme);
Pro Microsoft.AspNetCore.Server.HttpSys nastavte výchozí schéma na
HttpSysDefaults.AuthenticationScheme
:using Microsoft.AspNetCore.Server.HttpSys; services.AddAuthentication(HttpSysDefaults.AuthenticationScheme);
Nastavení výchozího schématu zabrání autorizaci (výzvě) v práci s následující výjimkou:
System.InvalidOperationException
: Nebylo zadáno žádné ověřováníScheme a nebyl nalezen žádný DefaultChallengeScheme.
Další informace najdete v tématu Konfigurace ověřování systému Windows v ASP.NET Core.
Instance IdentityCookieOptions
Vedlejším účinkem změn 2,0 je přepnutí na použití pojmenovaných možností místo cookie instancí možností. Možnost přizpůsobit Identitycookie názvy schématu je odebrána.
Například projekty 1.x používají injektáž konstruktoru k předání parametru IdentityCookieOptions
do AccountController.cs
a ManageController.cs
. K schématu externího cookie ověřování se přistupuje z poskytnuté instance:
public AccountController(
UserManager<ApplicationUser> userManager,
SignInManager<ApplicationUser> signInManager,
IOptions<IdentityCookieOptions> identityCookieOptions,
IEmailSender emailSender,
ISmsSender smsSender,
ILoggerFactory loggerFactory)
{
_userManager = userManager;
_signInManager = signInManager;
_externalCookieScheme = identityCookieOptions.Value.ExternalCookieAuthenticationScheme;
_emailSender = emailSender;
_smsSender = smsSender;
_logger = loggerFactory.CreateLogger<AccountController>();
}
Výše uvedená injektáž konstruktoru se stává nepotřebnou ve 2.0 projektech a _externalCookieScheme
pole lze odstranit:
public AccountController(
UserManager<ApplicationUser> userManager,
SignInManager<ApplicationUser> signInManager,
IEmailSender emailSender,
ISmsSender smsSender,
ILoggerFactory loggerFactory)
{
_userManager = userManager;
_signInManager = signInManager;
_emailSender = emailSender;
_smsSender = smsSender;
_logger = loggerFactory.CreateLogger<AccountController>();
}
Projekty 1.x používaly _externalCookieScheme
pole takto:
// Clear the existing external cookie to ensure a clean login process
await HttpContext.Authentication.SignOutAsync(_externalCookieScheme);
V projektech 2.0 nahraďte předchozí kód následujícím kódem. Konstantu IdentityConstants.ExternalScheme
lze použít přímo.
// Clear the existing external cookie to ensure a clean login process
await HttpContext.SignOutAsync(IdentityConstants.ExternalScheme);
Vyřešte nově přidané SignOutAsync
volání importem následujícího oboru názvů:
using Microsoft.AspNetCore.Authentication;
Přidání navigačních vlastností IdentityUser POCO
Byly odebrány vlastnosti navigace Entity Framework (EF) Core základního IdentityUser
OBJEKTu POCO (Plain Old CLR Object). Pokud váš projekt 1.x použil tyto vlastnosti, přidejte je ručně zpět do projektu 2.0:
/// <summary>
/// Navigation property for the roles this user belongs to.
/// </summary>
public virtual ICollection<IdentityUserRole<int>> Roles { get; } = new List<IdentityUserRole<int>>();
/// <summary>
/// Navigation property for the claims this user possesses.
/// </summary>
public virtual ICollection<IdentityUserClaim<int>> Claims { get; } = new List<IdentityUserClaim<int>>();
/// <summary>
/// Navigation property for this users login accounts.
/// </summary>
public virtual ICollection<IdentityUserLogin<int>> Logins { get; } = new List<IdentityUserLogin<int>>();
Pokud chcete zabránit duplicitním cizím klíčům při spuštění EF Core migrace, přidejte následující kód do metody třídy IdentityDbContext
OnModelCreating
(po base.OnModelCreating();
volání):
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);
builder.Entity<ApplicationUser>()
.HasMany(e => e.Claims)
.WithOne()
.HasForeignKey(e => e.UserId)
.IsRequired()
.OnDelete(DeleteBehavior.Cascade);
builder.Entity<ApplicationUser>()
.HasMany(e => e.Logins)
.WithOne()
.HasForeignKey(e => e.UserId)
.IsRequired()
.OnDelete(DeleteBehavior.Cascade);
builder.Entity<ApplicationUser>()
.HasMany(e => e.Roles)
.WithOne()
.HasForeignKey(e => e.UserId)
.IsRequired()
.OnDelete(DeleteBehavior.Cascade);
}
Nahradit GetExternalAuthenticationSchemes
Synchronní metoda GetExternalAuthenticationSchemes
byla odebrána ve prospěch asynchronní verze. Projekty 1.x mají následující kód:Controllers/ManageController.cs
var otherLogins = _signInManager.GetExternalAuthenticationSchemes().Where(auth => userLogins.All(ul => auth.AuthenticationScheme != ul.LoginProvider)).ToList();
Tato metoda se zobrazuje Views/Account/Login.cshtml
také:
@{
var loginProviders = SignInManager.GetExternalAuthenticationSchemes().ToList();
if (loginProviders.Count == 0)
{
<div>
<p>
There are no external authentication services configured. See <a href="https://go.microsoft.com/fwlink/?LinkID=532715">this article</a>
for details on setting up this ASP.NET application to support logging in via external services.
</p>
</div>
}
else
{
<form asp-controller="Account" asp-action="ExternalLogin" asp-route-returnurl="@ViewData["ReturnUrl"]" method="post" class="form-horizontal">
<div>
<p>
@foreach (var provider in loginProviders)
{
<button type="submit" class="btn btn-default" name="provider" value="@provider.AuthenticationScheme" title="Log in using your @provider.DisplayName account">@provider.AuthenticationScheme</button>
}
</p>
</div>
</form>
}
}
V projektech 2.0 použijte metodu GetExternalAuthenticationSchemesAsync . ManageController.cs
Změna se podobá následujícímu kódu:
var schemes = await _signInManager.GetExternalAuthenticationSchemesAsync();
var otherLogins = schemes.Where(auth => userLogins.All(ul => auth.Name != ul.LoginProvider)).ToList();
Vlastnost Login.cshtml
, ke které se AuthenticationScheme
přistupuje ve foreach
smyčce, se změní na Name
:
@{
var loginProviders = (await SignInManager.GetExternalAuthenticationSchemesAsync()).ToList();
if (loginProviders.Count == 0)
{
<div>
<p>
There are no external authentication services configured. See <a href="https://go.microsoft.com/fwlink/?LinkID=532715">this article</a>
for details on setting up this ASP.NET application to support logging in via external services.
</p>
</div>
}
else
{
<form asp-controller="Account" asp-action="ExternalLogin" asp-route-returnurl="@ViewData["ReturnUrl"]" method="post" class="form-horizontal">
<div>
<p>
@foreach (var provider in loginProviders)
{
<button type="submit" class="btn btn-default" name="provider" value="@provider.Name" title="Log in using your @provider.DisplayName account">@provider.DisplayName</button>
}
</p>
</div>
</form>
}
}
Změna vlastnosti ManageLoginsViewModel
Objekt ManageLoginsViewModel
se používá v ManageLogins
akci .ManageController.cs
V projektech 1.x je IList<AuthenticationDescription>
návratový OtherLogins
typ vlastnosti objektu . Tento návratový typ vyžaduje import:Microsoft.AspNetCore.Http.Authentication
using System.Collections.Generic;
using Microsoft.AspNetCore.Http.Authentication;
using Microsoft.AspNetCore.Identity;
namespace AspNetCoreDotNetCore1App.Models.ManageViewModels
{
public class ManageLoginsViewModel
{
public IList<UserLoginInfo> CurrentLogins { get; set; }
public IList<AuthenticationDescription> OtherLogins { get; set; }
}
}
Ve 2.0 projektech se návratový typ změní na IList<AuthenticationScheme>
. Tento nový návratový typ vyžaduje nahrazení Microsoft.AspNetCore.Http.Authentication
importu importem Microsoft.AspNetCore.Authentication
.
using System.Collections.Generic;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Identity;
namespace AspNetCoreDotNetCore2App.Models.ManageViewModels
{
public class ManageLoginsViewModel
{
public IList<UserLoginInfo> CurrentLogins { get; set; }
public IList<AuthenticationScheme> OtherLogins { get; set; }
}
}
Další materiály
Další informace najdete v diskuzi o problému s ověřováním 2.0 na GitHubu.