kimlik doğrulamasını Identity ASP.NET Core ve 2,0 'e geçirin

Scott Ade ve Hao Kung tarafından

ASP.NET Core 2,0, kimlik doğrulaması için yeni bir modele sahiptir ve Identity hizmetleri kullanarak yapılandırmayı basitleştirir. ASP.NET Core kimlik doğrulaması kullanan 1. x uygulamaları ve Identity aşağıda özetlenen yeni modeli kullanacak şekilde güncelleştirilemeyebilir.

Ad alanlarını güncelleştirme

  1. x içinde IdentityRole ve IdentityUser ad alanında bulunan sınıflar Microsoft.AspNetCore.Identity.EntityFrameworkCore .

2,0 ' de, Microsoft.AspNetCore.Identity ad alanı bu tür sınıfların birkaçı için yeni giriş haline geldi. Varsayılan Identity kodla, etkilenen sınıflar ApplicationUser ve içerir Startup . usingEtkilenen başvuruları çözümlemek için deyimlerinizi ayarlayın.

Kimlik doğrulama ara yazılımı ve Hizmetleri

  1. x projelerinde kimlik doğrulaması, ara yazılım aracılığıyla yapılandırılır. Desteklemek istediğiniz her kimlik doğrulama düzeni için bir ara yazılım yöntemi çağırılır.

Aşağıdaki 1. x örneği, ile Facebook kimlik doğrulamasını Identity Başlangıç. cs olarak yapılandırır:

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"]
    });
}

2,0 projesinde, kimlik doğrulaması hizmetler aracılığıyla yapılandırılır. Her kimlik doğrulama düzeni ConfigureServices Başlangıç. cs yöntemine kaydedilir. UseIdentityYöntemi ile değiştirilmiştir UseAuthentication .

Aşağıdaki 2,0 örneği, Facebook kimlik doğrulamasını Identity Açılışta, Başlangıç. cs' de yapılandırır:

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

UseAuthenticationYöntemi otomatik kimlik doğrulamasından ve uzak kimlik doğrulama isteklerinin işlenmesinden sorumlu olan tek bir kimlik doğrulama ara yazılım bileşeni ekler. Tek, ortak bir ara yazılım bileşeniyle tüm bireysel ara yazılım bileşenlerini değiştirir.

Her bir büyük kimlik doğrulama şeması için 2,0 geçiş yönergeleri aşağıda verilmiştir.

Aşağıdaki iki seçenekten birini seçin ve Başlangıç. cs dosyasında gerekli değişiklikleri yapın:

  1. cookieİle s kullanınIdentity

    • UseIdentityYönteminde ile değiştirin UseAuthentication Configure :

      app.UseAuthentication();
      
    • AddIdentity ConfigureServices Kimlik doğrulama hizmetlerini eklemek için yöntemindeki yöntemi çağırın cookie .

    • İsteğe bağlı olarak, ConfigureApplicationCookie ConfigureExternalCookie ConfigureServices ayarları ince ayar için yöntemi içindeki or metodunu çağırın Identity cookie .

      services.AddIdentity<ApplicationUser, IdentityRole>()
              .AddEntityFrameworkStores<ApplicationDbContext>()
              .AddDefaultTokenProviders();
      
      services.ConfigureApplicationCookie(options => options.LoginPath = "/Account/LogIn");
      
  2. Şunu cookie olmadan s kullan Identity

    • UseCookieAuthenticationYöntemindeki yöntem çağrısını Configure ile değiştirin UseAuthentication :

      app.UseAuthentication();
      
    • AddAuthentication AddCookie Yöntemi içindeki ve yöntemlerini çağırın ConfigureServices :

      // 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 taşıyıcı kimlik doğrulaması

Başlangıç. cs dosyasında aşağıdaki değişiklikleri yapın:

  • UseJwtBearerAuthenticationYöntemindeki yöntem çağrısını Configure ile değiştirin UseAuthentication :

    app.UseAuthentication();
    
  • Yönteminde AddJwtBearer yöntemi çağırın ConfigureServices :

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

    Bu kod parçacığı kullanmaz Identity , bu nedenle varsayılan şema yöntemine geçirerek ayarlanmalıdır JwtBearerDefaults.AuthenticationScheme AddAuthentication .

openıd Bağlan (oıdc) kimlik doğrulaması

Başlangıç. cs dosyasında aşağıdaki değişiklikleri yapın:

  • UseOpenIdConnectAuthenticationYöntemindeki yöntem çağrısını Configure ile değiştirin UseAuthentication :

    app.UseAuthentication();
    
  • Yönteminde AddOpenIdConnect yöntemi çağırın ConfigureServices :

    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 OpenIdConnectOptions Eylemdeki özelliğini ile değiştirin SignedOutRedirectUri :

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

Facebook kimlik doğrulaması

Başlangıç. cs dosyasında aşağıdaki değişiklikleri yapın:

  • UseFacebookAuthenticationYöntemindeki yöntem çağrısını Configure ile değiştirin UseAuthentication :

    app.UseAuthentication();
    
  • Yönteminde AddFacebook yöntemi çağırın ConfigureServices :

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

Google kimlik doğrulaması

Başlangıç. cs dosyasında aşağıdaki değişiklikleri yapın:

  • UseGoogleAuthenticationYöntemindeki yöntem çağrısını Configure ile değiştirin UseAuthentication :

    app.UseAuthentication();
    
  • Yönteminde AddGoogle yöntemi çağırın ConfigureServices :

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

Microsoft Hesabı kimlik doğrulaması

Microsoft hesabı kimlik doğrulaması hakkında daha fazla bilgi için bu GitHub sorunabakın.

Başlangıç. cs dosyasında aşağıdaki değişiklikleri yapın:

  • UseMicrosoftAccountAuthenticationYöntemindeki yöntem çağrısını Configure ile değiştirin UseAuthentication :

    app.UseAuthentication();
    
  • Yönteminde AddMicrosoftAccount yöntemi çağırın ConfigureServices :

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

Twitter kimlik doğrulaması

Başlangıç. cs dosyasında aşağıdaki değişiklikleri yapın:

  • UseTwitterAuthenticationYöntemindeki yöntem çağrısını Configure ile değiştirin UseAuthentication :

    app.UseAuthentication();
    
  • Yönteminde AddTwitter yöntemi çağırın ConfigureServices :

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

Varsayılan kimlik doğrulama düzenlerini ayarlama

  1. x içinde, AutomaticAuthenticate AutomaticChallenge authenticationoptions temel sınıfının ve özellikleri tek bir kimlik doğrulama düzeninde ayarlamaya yöneliktir. Bunu zorlayacağından iyi bir yol yoktu.

2,0 ' de, bu iki özellik ayrı bir örnekteki özellikler olarak kaldırılmıştır AuthenticationOptions . AddAuthentication ConfigureServices Başlangıç. cs yöntemi içindeki yöntem çağrısında yapılandırılabilirler:

services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme);

Yukarıdaki kod parçacığında, varsayılan düzen CookieAuthenticationDefaults.AuthenticationScheme (" Cookie s") olarak ayarlanır.

Alternatif olarak, birden AddAuthentication fazla özellik ayarlamak için yönteminin aşırı yüklenmiş bir sürümünü kullanın. Aşağıdaki aşırı yüklenmiş yöntem örneğinde, varsayılan düzen olarak ayarlanır CookieAuthenticationDefaults.AuthenticationScheme . Kimlik doğrulama düzeni, farklı [Authorize] özniteliklerde veya yetkilendirme ilkeleriniz içinde de belirtilebilir.

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

Aşağıdaki koşullardan biri doğru ise, 2,0 'de varsayılan bir düzen tanımlayın:

  • Kullanıcının otomatik olarak oturum açabilmesi istiyorsunuz
  • [Authorize]Şemaları belirtmeden özniteliği veya yetkilendirme ilkelerini kullanın

Bu kural için bir özel durum AddIdentity yöntemidir. Bu yöntem cookie sizin için ekler ve varsayılan kimlik doğrulama ve zorluk düzenlerini uygulamaya ayarlar cookie IdentityConstants.ApplicationScheme . Ayrıca, varsayılan oturum açma düzenini dış olarak ayarlar cookie IdentityConstants.ExternalScheme .

HttpContext kimlik doğrulama uzantılarını kullanma

IAuthenticationManagerArabirim, 1. x kimlik doğrulama sistemine ana giriş noktasıdır. HttpContextAd alanındaki yeni bir genişletme yöntemleri kümesiyle değiştirilmiştir Microsoft.AspNetCore.Authentication .

Örneğin, 1. x projeleri bir özelliğe başvurur Authentication :

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

2,0 projesinde, Microsoft.AspNetCore.Authentication ad alanını içeri aktarın ve Authentication özellik başvurularını silin:

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

Windows Kimlik doğrulaması (HTTP.sys/Iisıntegration)

Windows kimlik doğrulamasının iki çeşidi vardır:

  • Konak yalnızca kimliği doğrulanmış kullanıcılara izin verir. Bu çeşitleme 2,0 değişikliklerden etkilenmez.

  • Konak hem anonim hem de kimliği doğrulanmış kullanıcılara izin verir. Bu çeşitleme 2,0 değişikliklerden etkilenir. Örneğin, uygulama IIS veya HTTP.sys katmanında anonim kullanıcılara izin vermeli, ancak kullanıcıları denetleyici düzeyinde yetkilendirebilmelidir. Bu senaryoda, yönteminde varsayılan düzeni ayarlayın Startup.ConfigureServices .

    Microsoft. AspNetCore. Server. ıısıntegrationiçin varsayılan düzeni şu şekilde ayarlayın IISDefaults.AuthenticationScheme :

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

    Microsoft. AspNetCore. Server. HttpSysiçin varsayılan düzeni olarak ayarlayın HttpSysDefaults.AuthenticationScheme :

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

    Varsayılan düzenin ayarlanamaması, yetkilendirme (sınama) isteğinin şu özel durumla çalışmasını engeller:

    System.InvalidOperationException: Hiçbir authenticationScheme belirtilmedi ve hiç Defaultchallenbescheme bulunamadı.

Daha fazla bilgi için bkz. ASP.NET Core 'da Windows kimlik doğrulamasını yapılandırma.

IdentityCookieSeçenek örnekleri

2,0 değişikliğin yan etkisi, seçenek örnekleri yerine adlandırılmış seçenekleri kullanma anahtarıdır cookie . Identity cookie Düzen adlarını özelleştirme özelliği kaldırılır.

Örneğin, 1. x projeleri bir IdentityCookieOptions parametreyi accountcontroller. cs ve managecontroller. cs öğesine geçirmek için Oluşturucu Ekleme kullanır. Dış cookie kimlik doğrulama düzenine, belirtilen örnekten erişilir:

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

Belirtilen Oluşturucu Ekleme, 2,0 projesinde gereksiz hale gelir ve _externalCookieScheme alan silinebilir:

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>();
}
  1. x projeleri _externalCookieScheme alanı şu şekilde kullandı:
// Clear the existing external cookie to ensure a clean login process
await HttpContext.Authentication.SignOutAsync(_externalCookieScheme);

2,0 projesinde, yukarıdaki kodu aşağıdaki kodla değiştirin. IdentityConstants.ExternalSchemeSabit doğrudan kullanılabilir.

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

Aşağıdaki ad alanını SignOutAsync içeri aktararak yeni eklenen çağrıyı çözümle:

using Microsoft.AspNetCore.Authentication;

Kullanıcı Identity POCO gezinti özellikleri ekleme

Temel POCO Entity Framework (Düz Eski CLR Nesnesi) temel IdentityUser (EF) Core gezinti özellikleri kaldırıldı. 1.x projeniz bu özellikleri kullandısa, bunları 2.0 projesine el ile ekleyin:

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

Geçişler'i çalıştırma sırasında EF Core yabancı anahtarları önlemek için sınıf yönteminize IdentityDbContext OnModelCreating (çağrısından sonra) aşağıdakini base.OnModelCreating(); ekleyin:

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'i değiştirme

Zaman uyumlu GetExternalAuthenticationSchemes yöntem, zaman uyumsuz bir sürüm için kaldırıldı. 1.x projeleri Controllers/ManageController.cs içinde aşağıdaki koda sahip:

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

Bu yöntem Views/Account/Login.cshtml içinde de görünür:

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

2.0 projelerinde yöntemini GetExternalAuthenticationSchemesAsync kullanın. ManageController.cs'de yapılan değişiklik aşağıdaki koda benzer:

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

Login.cshtml içinde, AuthenticationScheme döngüsünde erişilen foreach özellik olarak Name değişir:

@{
    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 özellik değişikliği

ManageLoginsViewModel ManageLogins ManageController.cs eylemde bir nesnesi kullanılır. 1.x projelerinde nesnenin özellik dönüş OtherLogins türü IList<AuthenticationDescription> olur. Bu dönüş türü için içeri aktarma Microsoft.AspNetCore.Http.Authentication gerekir:

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

2.0 projelerinde dönüş türü olarak IList<AuthenticationScheme> değişir. Bu yeni dönüş türü, içeri aktarmanın Microsoft.AspNetCore.Http.Authentication bir içeri aktarma ile Microsoft.AspNetCore.Authentication değiştirilmesini gerektirir.

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

Ek kaynaklar

Daha fazla bilgi için bkz. Kimlik Doğrulaması için Tartışma 2.0 sorunu GitHub.