Megosztás a következőn keresztül:


Hitelesítés és Identity migrálása az ASP.NET Core 2.0-ra.

Készítette: Scott Addie és Hao Kung

ASP.NET Core 2.0 egy új hitelesítési modellel rendelkezik, amely Identity leegyszerűsíti a konfigurációt a szolgáltatások használatával. Azok az ASP.NET Core 1.x alkalmazások, amelyek hitelesítést vagy Identity használnak, az alábbiakban leírtak szerint frissíthetők az új modell használatára.

Névterek frissítése

Az 1.x-ben ilyen IdentityRoleIdentityUser osztályok találhatók a Microsoft.AspNetCore.Identity.EntityFrameworkCore névtérben.

2.0-ban a Microsoft.AspNetCore.Identity névtér több ilyen osztály új otthonává vált. Az alapértelmezett Identity kóddal az érintett osztályok közé tartozik a ApplicationUser és a Startup. Módosítsa az using utasításokat az érintett hivatkozások feloldásához.

Hitelesítési köztes szoftver és szolgáltatások

Az 1.x-projektekben a hitelesítés köztes szoftveren keresztül van konfigurálva. A rendszer minden támogatni kívánt hitelesítési sémához meghív egy köztes szoftvermetódust.

A következő 1.x példa konfigurálja a Facebook-hitelesítést a Identity a 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"]
    });
}

A 2.0-s projektekben a hitelesítés szolgáltatásokon keresztül van konfigurálva. Minden hitelesítési séma regisztrálva van a ConfigureServices metódusban Startup.cs. A UseIdentity metódus helyébe UseAuthenticationa következő lép: .

A következő példa 2.0 konfigurálja a Facebook-hitelesítést IdentityStartup.cs segítségével.

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();
}

A UseAuthentication metódus egyetlen hitelesítési köztes szoftverösszetevőt ad hozzá, amely az automatikus hitelesítésért és a távoli hitelesítési kérelmek kezeléséért felelős. Az összes köztes szoftverösszetevőt egyetlen, közös köztes szoftverösszetevőre cseréli.

Az alábbiakban 2.0-s migrálási utasításokat talál az egyes fő hitelesítési sémákhoz.

Válassza ki az alábbi két lehetőség egyikét, és végezze el a szükséges módosításokat a következőben Startup.cs:

  1. Cookiek használata Identity

    • Cserélje le UseIdentity a UseAuthentication következő metódusraConfigure:

      app.UseAuthentication();
      
    • AddIdentity A hitelesítési szolgáltatások hozzáadásához hívja meg a ConfigureServices metódus metódusátcookie.

    • Igény szerint meghívhatja a ConfigureApplicationCookie metódust vagy ConfigureExternalCookie metódust a ConfigureServicesIdentitycookie beállítások finomhangolásához.

      services.AddIdentity<ApplicationUser, IdentityRole>()
              .AddEntityFrameworkStores<ApplicationDbContext>()
              .AddDefaultTokenProviders();
      
      services.ConfigureApplicationCookie(options => options.LoginPath = "/Account/LogIn");
      
  2. Cookie-k használata Identity nélkül

    • Cserélje le a UseCookieAuthentication metódushívást a Configure metódusban a UseAuthentication metódusra.

      app.UseAuthentication();
      
    • A AddAuthentication metódusban hívja meg a AddCookie és ConfigureServices metódusokat.

      // 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-tulajdonos hitelesítése

Végezze el a következő módosításokat itt Startup.cs:

  • Cserélje le a UseJwtBearerAuthentication metódushívást a Configure metódusban a UseAuthentication metódusra.

    app.UseAuthentication();
    
  • AddJwtBearer A metódus meghívása a ConfigureServices metódusban:

    services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
            .AddJwtBearer(options =>
            {
                options.Audience = "http://localhost:5001/";
                options.Authority = "http://localhost:5000/";
            });
    

    Ez a kódrészlet nem használ Identity, ezért az alapértelmezett sémát a JwtBearerDefaults.AuthenticationScheme-t a AddAuthentication metódusnak való átadásával kell beállítani.

OpenID Connect -hitelesítés (OIDC)

Végezze el a következő módosításokat itt Startup.cs:

  • Cserélje le a UseOpenIdConnectAuthentication metódushívást a Configure metódusban a UseAuthentication metódusra.

    app.UseAuthentication();
    
  • AddOpenIdConnect A metódus meghívása a ConfigureServices metódusban:

    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"];
    });
    
  • Cserélje le az PostLogoutRedirectUri művelet OpenIdConnectOptions tulajdonságát SignedOutRedirectUri-ra/-re:

    .AddOpenIdConnect(options =>
    {
        options.SignedOutRedirectUri = "https://contoso.com";
    });
    

Facebook-hitelesítés

Végezze el a következő módosításokat itt Startup.cs:

  • Cserélje le a UseFacebookAuthentication metódushívást a Configure metódusban a UseAuthentication metódusra.

    app.UseAuthentication();
    
  • AddFacebook A metódus meghívása a ConfigureServices metódusban:

    services.AddAuthentication()
            .AddFacebook(options =>
            {
                options.AppId = Configuration["auth:facebook:appid"];
                options.AppSecret = Configuration["auth:facebook:appsecret"];
            });
    

Google-hitelesítés

Végezze el a következő módosításokat itt Startup.cs:

  • Cserélje le a UseGoogleAuthentication metódushívást a Configure metódusban a UseAuthentication metódusra.

    app.UseAuthentication();
    
  • AddGoogle A metódus meghívása a ConfigureServices metódusban:

    services.AddAuthentication()
            .AddGoogle(options =>
            {
                options.ClientId = Configuration["auth:google:clientid"];
                options.ClientSecret = Configuration["auth:google:clientsecret"];
            });
    

Microsoft-fiók hitelesítése

A Microsoft-fiók hitelesítésével kapcsolatos további információkért tekintse meg ezt a GitHub-problémát.

Végezze el a következő módosításokat itt Startup.cs:

  • Cserélje le a UseMicrosoftAccountAuthentication metódushívást a Configure metódusban a UseAuthentication metódusra.

    app.UseAuthentication();
    
  • AddMicrosoftAccount A metódus meghívása a ConfigureServices metódusban:

    services.AddAuthentication()
            .AddMicrosoftAccount(options =>
            {
                options.ClientId = Configuration["auth:microsoft:clientid"];
                options.ClientSecret = Configuration["auth:microsoft:clientsecret"];
            });
    

Twitter-hitelesítés

Végezze el a következő módosításokat itt Startup.cs:

  • Cserélje le a UseTwitterAuthentication metódushívást a Configure metódusban a UseAuthentication metódusra.

    app.UseAuthentication();
    
  • AddTwitter A metódus meghívása a ConfigureServices metódusban:

    services.AddAuthentication()
            .AddTwitter(options =>
            {
                options.ConsumerKey = Configuration["auth:twitter:consumerkey"];
                options.ConsumerSecret = Configuration["auth:twitter:consumersecret"];
            });
    

Alapértelmezett hitelesítési sémák beállítása

Az 1.x-ben az AutomaticAuthenticate alaposztály és AutomaticChallenge a AuthenticationOptions tulajdonságok egyetlen hitelesítési sémára voltak beállítva. Nem volt jó módszer erre.

A 2.0-ban ez a két tulajdonság el lett távolítva az egyes AuthenticationOptions példány tulajdonságaiként. A metódushívásban AddAuthentication konfigurálhatók a ConfigureServices metóduson belül Startup.cs.

services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme);

Az előző kódrészletben az alapértelmezett séma a "Cookie-k" értékre CookieAuthenticationDefaults.AuthenticationScheme van állítva.

Másik lehetőségként használja a AddAuthentication metódus túlterhelt verzióját egynél több tulajdonság beállításához. A következő túlterhelt metódus példában az alapértelmezett séma a következőre CookieAuthenticationDefaults.AuthenticationSchemevan állítva. A hitelesítési séma megadható az egyes [Authorize] attribútumokon vagy engedélyezési szabályzatokon belül is.

services.AddAuthentication(options =>
{
    options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
    options.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
});

Adjon meg egy alapértelmezett sémát a 2.0-ban, ha az alábbi feltételek egyike teljesül:

  • Azt szeretné, hogy a felhasználó automatikusan be legyen jelentkezve
  • Az attribútum- [Authorize] vagy engedélyezési szabályzatokat sémák megadása nélkül használhatja

A szabály alól kivételt képez a AddIdentity metódus. Ez a módszer cookie-kat ad hozzá Önhöz, és beállítja az alapértelmezett hitelesítési és kihívási sémákat az alkalmazáshoz cookieIdentityConstants.ApplicationScheme. Emellett beállítja az alapértelmezett bejelentkezési sémát a külsőre cookieIdentityConstants.ExternalScheme.

HttpContext hitelesítési bővítmények használata

Az IAuthenticationManager interfész az 1.x hitelesítési rendszer fő belépési pontja. Az HttpContext névtérben új Microsoft.AspNetCore.Authentication kiterjesztési metóduskészlet váltotta fel.

Az 1.x projektek például egy Authentication tulajdonságra hivatkoznak:

// Clear the existing external cookie to ensure a clean login process
await HttpContext.Authentication.SignOutAsync(_externalCookieScheme);

A 2.0-s projektekben importálja a Microsoft.AspNetCore.Authentication névteret, és törölje a Authentication tulajdonsághivatkozásokat:

// Clear the existing external cookie to ensure a clean login process
await HttpContext.SignOutAsync(IdentityConstants.ExternalScheme);

Windows-hitelesítés (HTTP.sys/IISIntegration)

A Windows-hitelesítésnek két változata létezik:

  • A gazdagép csak hitelesített felhasználókat enged be. Ezt a változatot a 2.0-s módosítások nem befolyásolják.

  • A szerver névtelen és hitelesített felhasználókat is engedélyez. Ezt a változatot a 2.0-s módosítások befolyásolják. Az alkalmazásnak például engedélyeznie kell a névtelen felhasználókat az IIS vagy HTTP.sys rétegben, de engedélyeznie kell a felhasználókat a vezérlő szintjén. Ebben a forgatókönyvben állítsa be az alapértelmezett sémát a Startup.ConfigureServices metódusban.

    A Microsoft.AspNetCore.Server.IISIntegration esetében állítsa az alapértelmezett sémát a következőre IISDefaults.AuthenticationScheme:

    using Microsoft.AspNetCore.Server.IISIntegration;
    
    services.AddAuthentication(IISDefaults.AuthenticationScheme);
    

    A Microsoft.AspNetCore.Server.HttpSys esetében állítsa az alapértelmezett sémát a következőre HttpSysDefaults.AuthenticationScheme:

    using Microsoft.AspNetCore.Server.HttpSys;
    
    services.AddAuthentication(HttpSysDefaults.AuthenticationScheme);
    

    Az alapértelmezett séma beállításának sikertelensége megakadályozza, hogy az engedélyezési (kihívást tartalmazó) kérés a következő kivétellel működjön:

    System.InvalidOperationException: Nincs megadva authenticationScheme, és nem található DefaultChallengeScheme.

További információ: Windows-hitelesítés konfigurálása a ASP.NET Core-ban.

IdentityCookieOptions-példányok

A 2.0-s módosítások egyik mellékhatása a névvel ellátott beállítások használatára való váltás a beállításpéldányok helyett cookie . A rendszer eltávolítja a sémanevek testreszabásának Identitycookie lehetőségét.

Az 1.x projektek például konstruktorinjektálás segítségével adnak át egy paramétert IdentityCookieOptionsAccountController.cs és ManageController.cs. A külső cookie hitelesítési séma a megadott példányról érhető el:

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>();
}

A fent említett konstruktorinjektálás szükségtelenné válik a 2.0-s projektekben, és a _externalCookieScheme mező törölhető:

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>();
}

Az 1.x-projektek a következő módon használták a _externalCookieScheme mezőt:

// Clear the existing external cookie to ensure a clean login process
await HttpContext.Authentication.SignOutAsync(_externalCookieScheme);

A 2.0-s projektekben cserélje le az előző kódot a következőre. Az IdentityConstants.ExternalScheme állandó közvetlenül használható.

// Clear the existing external cookie to ensure a clean login process
await HttpContext.SignOutAsync(IdentityConstants.ExternalScheme);

Az újonnan hozzáadott SignOutAsync hívás feloldása a következő névtér importálásával:

using Microsoft.AspNetCore.Authentication;

IdentityUser POCO navigációs tulajdonságok hozzáadása

A rendszer eltávolította az alap IdentityUser POCO (egyszerű régi CLR-objektum) entitás-keretrendszer (EF) alapvető navigációs tulajdonságait. Ha az 1.x projekt ezeket a tulajdonságokat használta, manuálisan adja hozzá őket a 2.0-s projekthez:

/// <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>>();

Ha meg szeretné akadályozni, hogy ismétlődő idegen kulcsok jöjjenek létre az EF Core áttelepítések futtatásakor, adja hozzá a következőket az IdentityDbContext osztály OnModelCreating metódusához (a base.OnModelCreating(); hívás utá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);
}

GetExternalAuthenticationSchemes cseréje

A szinkron metódus GetExternalAuthenticationSchemes el lett távolítva az aszinkron verzió javára. Az 1.x projektek a következő kóddal Controllers/ManageController.csrendelkeznek:

var otherLogins = _signInManager.GetExternalAuthenticationSchemes().Where(auth => userLogins.All(ul => auth.AuthenticationScheme != ul.LoginProvider)).ToList();

Ez a metódus a következőben is megjelenik Views/Account/Login.cshtml :

@{
    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>
    }
}

A 2.0-s projektekben használja a metódust GetExternalAuthenticationSchemesAsync . A változás a ManageController.cs következő kódhoz hasonlít:

var schemes = await _signInManager.GetExternalAuthenticationSchemesAsync();
var otherLogins = schemes.Where(auth => userLogins.All(ul => auth.Name != ul.LoginProvider)).ToList();

A Login.cshtml ciklusban a AuthenticationScheme elért foreach tulajdonság Name-re változik:

@{
    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>
    }
}

ManageLoginsViewModel tulajdonság módosítása

Egy ManageLoginsViewModel objektumot használnak a ManageLogins műveletben ManageController.cs. Az 1.x projektekben az objektum OtherLogins tulajdonságvisszaadó típusa .IList<AuthenticationDescription> Ehhez a visszatérési típushoz a következő importálás szükséges 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; }
    }
}

A 2.0-s projektekben a visszatérési típus a következőre változik IList<AuthenticationScheme>: . Az új visszatérési típushoz az Microsoft.AspNetCore.Http.Authentication importot egy Microsoft.AspNetCore.Authentication importra kell cserélni.

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; }
    }
}

További erőforrások

További információ: Auth 2.0 vitafórum a GitHubon.