Migrace ověřování Identity a na ASP.NET Core 2.0
Scott Addie a Hao Jejich
ASP.NET Core 2.0 má nový model ověřování, který zjednodušuje Identity konfiguraci pomocí služeb. ASP.NET Core Aplikace 1.x, které používají ověřování nebo je možné je aktualizovat tak, aby se mohl používat nový model, jak Identity je uvedeno níže.
Aktualizace oborů názvů
Ve 1.x byly v oboru názvů nalezeny třídy jako IdentityRole IdentityUser a Microsoft.AspNetCore.Identity.EntityFrameworkCore .
Ve 2.0 se obor Microsoft.AspNetCore.Identity názvů stal novým domovem pro několik takových tříd. Ve výchozím kódu Identity zahrnují ovlivněné třídy ApplicationUser a Startup . Upravte příkazy using tak, aby vyřešily ovlivněné odkazy.
Ověřovací middleware a služby
V projektech 1.x se ověřování konfiguruje prostřednictvím middlewaru. Pro každé schéma ověřování, které chcete podporovat, se vyvolá metoda middlewaru.
Následující příklad 1.x konfiguruje ověřování přes Facebook v Identity souboru Startup.cs:
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"]
});
}
V projektech 2.0 se ověřování konfiguruje prostřednictvím služeb. Každé schéma ověřování je registrováno ConfigureServices v metodě souboru Startup.cs. Metoda UseIdentity se nahradí za UseAuthentication .
Následující příklad 2.0 konfiguruje ověřování přes Facebook v Identity souboru Startup.cs:
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 přidá jednu ověřovací middlewarovou komponentu, která je zodpovědná za automatické ověřování a zpracování UseAuthentication žádostí o vzdálené ověření. Nahrazuje všechny jednotlivé komponenty middlewaru jednou běžnou komponentou middlewaru.
Níže jsou uvedené pokyny k migraci 2.0 pro každé hlavní schéma ověřování.
CookieOvěřování na základě
Vyberte jednu z následujících dvou možností a v souboru Startup.cs proveďte potřebné změny:
Použití cookie s s Identity
Nahraďte
UseIdentityUseAuthenticationvConfiguremetodě za :app.UseAuthentication();Vyvoláním
AddIdentitymetody vConfigureServicesmetodě přidejte cookie ověřovací služby.Volitelně můžete v metodě vyvolat metodu
ConfigureApplicationCookieneboConfigureExternalCookie, abysteConfigureServicesupravili Identity cookie nastavení.services.AddIdentity<ApplicationUser, IdentityRole>() .AddEntityFrameworkStores<ApplicationDbContext>() .AddDefaultTokenProviders(); services.ConfigureApplicationCookie(options => options.LoginPath = "/Account/LogIn");
Použití cookie bez Identity
Nahraďte
UseCookieAuthenticationvolání metody vConfiguremetodě zaUseAuthentication:app.UseAuthentication();Vyvolání
AddAuthenticationmetodAddCookiea vConfigureServicesmetodě :// 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"; });
Ověřování pomocí beareru JWT
V souboru Startup.cs proveďte následující změny:
Nahraďte
UseJwtBearerAuthenticationvolání metody vConfiguremetodě zaUseAuthentication:app.UseAuthentication();AddJwtBearerVyvolat metodu vConfigureServicesmetodě :services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme) .AddJwtBearer(options => { options.Audience = "http://localhost:5001/"; options.Authority = "http://localhost:5000/"; });Tento fragment kódu nepoužívejte , takže výchozí schéma by mělo být Identity nastaveno předáním
JwtBearerDefaults.AuthenticationSchemeAddAuthenticationmetodě .
Ověřování openID Připojení (OIDC)
V souboru Startup.cs proveďte následující změny:
Nahraďte
UseOpenIdConnectAuthenticationvolání metody vConfiguremetodě zaUseAuthentication:app.UseAuthentication();AddOpenIdConnectVyvolat metodu vConfigureServicesmetodě :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"]; });Nahraďte
PostLogoutRedirectUrivlastnost v akciOpenIdConnectOptions:SignedOutRedirectUri.AddOpenIdConnect(options => { options.SignedOutRedirectUri = "https://contoso.com"; });
Ověřování Facebooku
V souboru Startup.cs proveďte následující změny:
Nahraďte
UseFacebookAuthenticationvolání metody vConfiguremetodě zaUseAuthentication:app.UseAuthentication();AddFacebookVyvolat metodu vConfigureServicesmetodě :services.AddAuthentication() .AddFacebook(options => { options.AppId = Configuration["auth:facebook:appid"]; options.AppSecret = Configuration["auth:facebook:appsecret"]; });
Ověřování Googlu
V souboru Startup.cs proveďte následující změny:
Nahraďte
UseGoogleAuthenticationvolání metody vConfiguremetodě zaUseAuthentication:app.UseAuthentication();AddGoogleVyvolat metodu vConfigureServicesmetodě :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í účet Microsoft najdete v tomto GitHub problému.
V souboru Startup.cs proveďte následující změny:
Nahraďte
UseMicrosoftAccountAuthenticationvolání metody vConfiguremetodě zaUseAuthentication:app.UseAuthentication();AddMicrosoftAccountVyvolat metodu vConfigureServicesmetodě :services.AddAuthentication() .AddMicrosoftAccount(options => { options.ClientId = Configuration["auth:microsoft:clientid"]; options.ClientSecret = Configuration["auth:microsoft:clientsecret"]; });
Ověřování Twitteru
V souboru Startup.cs proveďte následující změny:
Nahraďte
UseTwitterAuthenticationvolání metody vConfiguremetodě zaUseAuthentication:app.UseAuthentication();AddTwitterVyvolat metodu vConfigureServicesmetodě :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í
Ve 1.x byly vlastnosti a základní třídy AuthenticationOptions nastaveny na AutomaticAuthenticate AutomaticChallenge jedno schéma ověřování. Nebyl žádný dobrý způsob, jak to vynutit.
Ve windows 2.0 byly tyto dvě vlastnosti odebrány jako vlastnosti jednotlivé AuthenticationOptions instance. Je možné je nakonfigurovat ve AddAuthentication volání metody v rámci metody souboru ConfigureServices Startup.cs:
services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme);
V předchozím fragmentu kódu je výchozí schéma nastavené CookieAuthenticationDefaults.AuthenticationScheme na Cookie ("s").
Alternativně můžete použít přetíženou verzi metody k AddAuthentication 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í je možné zadat také v rámci jednotlivých atributů [Authorize] nebo zásad autorizace.
services.AddAuthentication(options =>
{
options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
});
Definujte výchozí schéma ve 2.0, pokud platí jedna z následujících podmínek:
- Chcete, aby byl uživatel automaticky přihlášen.
- Použijete atribut
[Authorize]nebo zásady autorizace bez zadávání schémat.
Výjimkou z tohoto pravidla je AddIdentity metoda . Tato metoda pro cookie vás přidá y a nastaví výchozí schémata ověřování a výzvy pro aplikaci cookie IdentityConstants.ApplicationScheme . Kromě toho nastaví výchozí schéma přihlašování na externí cookie IdentityConstants.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. Byla nahrazena novou sadu rozšiřujících metod HttpContext v oboru Microsoft.AspNetCore.Authentication názvů .
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);
V projektech 2.0 naimportujte obor Microsoft.AspNetCore.Authentication názvů a odstraňte Authentication odkazy na vlastnosti:
// Clear the existing external cookie to ensure a clean login process
await HttpContext.SignOutAsync(IdentityConstants.ExternalScheme);
Windows Ověřování (HTTP.sys / IISIntegration)
Existují dvě varianty ověřování Windows ověřování:
Hostitel povoluje pouze ověřené uživatele. Tato varianta není ovlivněna změnami 2.0.
Hostitel umožňuje anonymní i ověřené uživatele. Tato varianta je ovlivněna změnami 2.0. Aplikace by například měla povolit anonymní uživatele ve službě IIS neboHTTP.sys ale autorizovat uživatele na úrovni kontroleru. V tomto scénáři nastavte výchozí schéma v
Startup.ConfigureServicesmetodě .Pro Microsoft.AspNetCore.Server.IISIntegrationnastavte výchozí schéma na
IISDefaults.AuthenticationScheme:using Microsoft.AspNetCore.Server.IISIntegration; services.AddAuthentication(IISDefaults.AuthenticationScheme);Pro Microsoft.AspNetCore.Server.HttpSysnastavte výchozí schéma na
HttpSysDefaults.AuthenticationScheme:using Microsoft.AspNetCore.Server.HttpSys; services.AddAuthentication(HttpSysDefaults.AuthenticationScheme);Pokud se výchozí schéma nepovolí, zabráníte tomu, aby požadavek na autorizaci (výzvu) pracoval s následující výjimkou:
System.InvalidOperationException: Nebyl zadán žádný parametr authenticationScheme a nebyl nalezen žádný parametr DefaultChallengeScheme.
Další informace naleznete v tématu Konfigurace ověřování systému Windows v ASP.NET Core.
IdentityCookieInstance možností
Vedlejším efektem 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 Identity cookie názvy schémat je odebrána.
Například projekty 1.x používají injektáž konstruktoru k předání parametru IdentityCookieOptions do souborů AccountController.cs a ManageController.cs. K cookie externímu schématu ověřování se přistupuje ze zadané 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 v projektech 2.0 nepotřebuje a _externalCookieScheme pole je možné 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žily _externalCookieScheme pole následujícím způsobem:
// 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);
SignOutAsyncPomocí importu následujícího oboru názvů vyřešte nově přidané volání:
using Microsoft.AspNetCore.Authentication;
Přidat Identity vlastnosti navigace POCO uživatele
Byla odebrána základní navigační vlastnost Entity Framework (EF) základního IdentityUser POCO (prostý starý objekt CLR). Pokud váš projekt 1. x tyto vlastnosti používá, přidejte je ručně zpátky 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>>();
Chcete-li zabránit duplicitním cizím klíčům při spuštění EF Core migrace, přidejte následující do IdentityDbContext OnModelCreating metody Class (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 namísto asynchronní verze. projekty 1. x mají následující kód v Controllers/ManageController. cs:
var otherLogins = _signInManager.GetExternalAuthenticationSchemes().Where(auth => userLogins.All(ul => auth.AuthenticationScheme != ul.LoginProvider)).ToList();
Tato metoda se zobrazí v zobrazeních/účtech/přihlašovacích údajích. cshtml je 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 GetExternalAuthenticationSchemesAsync metodu. Změna v ManageController. cs 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();
V Login. cshtml se vlastnost, ke které se AuthenticationScheme přistupovalo v foreach smyčce, 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
ManageLoginsViewModelObjekt se používá v ManageLogins akci ManageController. cs. V projektech 1. x OtherLogins je návratový typ vlastnosti objektu IList<AuthenticationDescription> . 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; }
}
}
V projektech 2,0 se návratový typ změní na IList<AuthenticationScheme> . Tento nový návratový typ vyžaduje nahrazení Microsoft.AspNetCore.Http.Authentication importu pomocí Microsoft.AspNetCore.Authentication importu.
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ší zdroje informací
Další informace najdete v diskuzi o potížích s ověřením 2,0 na GitHub.