Kimlik doğrulamasını ve Identity ASP.NET Core 2.0'a geçirme

Scott Addie 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 Kimlik doğrulaması kullanan veya Identity aşağıda açıklandığı gibi yeni modeli kullanacak şekilde güncelleştirilebilen Core 1.x uygulamaları.

Ad alanlarını güncelleştirme

1.x'te ve gibi IdentityRole IdentityUser sınıflar ad alanında Microsoft.AspNetCore.Identity.EntityFrameworkCore bulundu.

2.0'da ad alanı, Microsoft.AspNetCore.Identity bu tür sınıfların birkaçı için yeni home haline geldi. Varsayılan Identity kodla, etkilenen sınıflar ve StartupiçerirApplicationUser. Etkilenen başvuruları çözümlemek için deyimlerinizi using 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 Identity Startup.csFacebook kimlik doğrulamasını yapılandırıyor:

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 projelerinde kimlik doğrulaması hizmetler aracılığıyla yapılandırılır. Her kimlik doğrulama düzeni yöntemine ConfigureServices Startup.cskaydedilir. UseIdentity yöntemi ile UseAuthenticationdeğiştirilir.

Aşağıdaki 2.0 örneği ile Identity Startup.csFacebook kimlik doğrulamasını yapılandırıyor:

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

yöntemi, UseAuthentication 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 tek ara yazılım bileşenlerinin tümünü tek bir ortak ara yazılım bileşeniyle değiştirir.

Her bir ana kimlik doğrulama şeması için 2.0 geçiş yönergeleri aşağıdadır.

Aşağıdaki iki seçenek arasından birini belirleyin ve içinde gerekli değişiklikleri Startup.csyapın:

  1. Tanımlama bilgilerini şu şekilde kullanma: Identity

    • yönteminde şununla Configure UseAuthentication değiştirinUseIdentity:

      app.UseAuthentication();
      
    • AddIdentity Kimlik doğrulama hizmetlerini eklemek için yönteminde ConfigureServices yöntemini çağırıncookie.

    • İsteğe bağlı olarak, ayarları değiştirmek için yönteminde veya yöntemini çağırın ConfigureApplicationCookiecookie Identity.ConfigureExternalCookie ConfigureServices

      services.AddIdentity<ApplicationUser, IdentityRole>()
              .AddEntityFrameworkStores<ApplicationDbContext>()
              .AddDefaultTokenProviders();
      
      services.ConfigureApplicationCookie(options => options.LoginPath = "/Account/LogIn");
      
  2. Tanımlama bilgilerini kullanmadan kullanma Identity

    • yöntemindeki UseCookieAuthentication yöntem çağrısını Configure ile UseAuthenticationdeğiştirin:

      app.UseAuthentication();
      
    • yönteminde AddAuthentication ve AddCookie 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ı

içinde Startup.csaşağıdaki değişiklikleri yapın:

  • yöntemindeki UseJwtBearerAuthentication yöntem çağrısını Configure ile UseAuthenticationdeğiştirin:

    app.UseAuthentication();
    
  • AddJwtBearer yönteminde yöntemini çağırınConfigureServices:

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

    Bu kod parçacığı kullanmazIdentity, bu nedenle varsayılan düzen yöntemine AddAuthentication geçirilerek JwtBearerDefaults.AuthenticationScheme ayarlanmalıdır.

OpenID Connect (OIDC) kimlik doğrulaması

içinde Startup.csaşağıdaki değişiklikleri yapın:

  • yöntemindeki UseOpenIdConnectAuthentication yöntem çağrısını Configure ile UseAuthenticationdeğiştirin:

    app.UseAuthentication();
    
  • AddOpenIdConnect yönteminde yöntemini çağırınConfigureServices:

    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"];
    });
    
  • eylemindeki PostLogoutRedirectUri OpenIdConnectOptions özelliğini ile SignedOutRedirectUrideğiştirin:

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

Facebook kimlik doğrulaması

içinde Startup.csaşağıdaki değişiklikleri yapın:

  • yöntemindeki UseFacebookAuthentication yöntem çağrısını Configure ile UseAuthenticationdeğiştirin:

    app.UseAuthentication();
    
  • AddFacebook yönteminde yöntemini çağırınConfigureServices:

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

Google kimlik doğrulaması

içinde Startup.csaşağıdaki değişiklikleri yapın:

  • yöntemindeki UseGoogleAuthentication yöntem çağrısını Configure ile UseAuthenticationdeğiştirin:

    app.UseAuthentication();
    
  • AddGoogle yönteminde yöntemini çağırınConfigureServices:

    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 sorununa bakın.

içinde Startup.csaşağıdaki değişiklikleri yapın:

  • yöntemindeki UseMicrosoftAccountAuthentication yöntem çağrısını Configure ile UseAuthenticationdeğiştirin:

    app.UseAuthentication();
    
  • AddMicrosoftAccount yönteminde yöntemini çağırınConfigureServices:

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

Twitter kimlik doğrulaması

içinde Startup.csaşağıdaki değişiklikleri yapın:

  • yöntemindeki UseTwitterAuthentication yöntem çağrısını Configure ile UseAuthenticationdeğiştirin:

    app.UseAuthentication();
    
  • AddTwitter yönteminde yöntemini çağırınConfigureServices:

    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'te, AutomaticAuthenticate temel sınıfın AuthenticationOptions ve AutomaticChallenge özellikleri tek bir kimlik doğrulama düzeninde ayarlanması amaçlanmıştır. Bunu zorlamanın iyi bir yolu yoktu.

2.0'da, bu iki özellik tek bir AuthenticationOptions örnekte özellik olarak kaldırılmıştır. Yöntemi çağrısında AddAuthentication yönteminin ConfigureServices Startup.csiçinde yapılandırılabilirler:

services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme);

Yukarıdaki kod parçacığında varsayılan düzen ("Tanımlama Bilgileri") olarak CookieAuthenticationDefaults.AuthenticationScheme ayarlanmıştır.

Alternatif olarak, birden fazla özellik ayarlamak için yönteminin AddAuthentication 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 CookieAuthenticationDefaults.AuthenticationSchemeayarlanmıştır. Kimlik doğrulama düzeni alternatif olarak tek tek [Authorize] öznitelikleriniz veya yetkilendirme ilkeleriniz içinde belirtilebilir.

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

Aşağıdaki koşullardan biri doğruysa 2.0'da varsayılan bir düzen tanımlayın:

  • Kullanıcının otomatik olarak oturum açmasını istiyorsunuz
  • Düzenleri belirtmeden öznitelik veya yetkilendirme ilkelerini kullanırsınız [Authorize]

Bu kuralın bir özel durumu yöntemidir AddIdentity . Bu yöntem sizin için tanımlama bilgileri ekler ve uygulamaya cookieIdentityConstants.ApplicationSchemevarsayılan kimlik doğrulama ve sınama düzenlerini ayarlar. Ayrıca, varsayılan oturum açma düzenini dış cookieIdentityConstants.ExternalSchemeolarak ayarlar.

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

IAuthenticationManager Arabirim, 1.x kimlik doğrulama sisteminin ana giriş noktasıdır. Ad alanında yeni bir uzantı yöntemleri Microsoft.AspNetCore.Authentication kümesiyle HttpContext değiştirildi.

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

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

2.0 projelerinde ad alanını içeri aktarın Microsoft.AspNetCore.Authentication ve özellik başvurularını silin Authentication :

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

Windows Kimlik Doğrulaması (HTTP.sys / IISIntegration)

Windows kimlik doğrulamasının iki varyasyonu vardır:

  • Konak yalnızca kimliği doğrulanmış kullanıcılara izin verir. Bu varyasyon 2.0 değişikliklerini etkilemez.

  • Konak hem anonim hem de kimliği doğrulanmış kullanıcılara izin verir. Bu varyasyon 2.0 değişikliklerini etkiler. Örneğin, uygulamanın IIS veya HTTP.sys katmanında anonim kullanıcılara izin vermesi ancak denetleyici düzeyinde kullanıcıları yetkilendirmesi gerekir. Bu senaryoda, yönteminde Startup.ConfigureServices varsayılan düzeni ayarlayın.

    Microsoft.AspNetCore.Server.IISIntegration için varsayılan düzeni olarak IISDefaults.AuthenticationSchemeayarlayın:

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

    Microsoft.AspNetCore.Server.HttpSys için varsayılan düzeni olarak HttpSysDefaults.AuthenticationSchemeayarlayın:

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

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

    System.InvalidOperationException: AuthenticationScheme belirtilmedi ve DefaultChallengeScheme bulunamadı.

Daha fazla bilgi için bkz . ASP.NET Core'da Windows Kimlik Doğrulamasını Yapılandırma.

IdentityCookieOptions örnekleri

2.0 değişikliklerinin bir yan etkisi, seçenek örnekleri yerine cookie adlandırılmış seçenekleri kullanmaya geçiştir. Düzen adlarını özelleştirme Identitycookie özelliği kaldırılır.

Örneğin, 1.x projeleri ve ManageController.csiçine AccountController.cs bir IdentityCookieOptions parametre geçirmek için oluşturucu ekleme kullanır. Dış cookie kimlik doğrulama düzenine sağlanan ö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>();
}

Yukarıda belirtilen oluşturucu ekleme işlemi 2.0 projelerinde 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 alanı şu şekilde kullanmıştı _externalCookieScheme :

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

2.0 projelerinde, önceki kodu aşağıdakiyle değiştirin. Sabit IdentityConstants.ExternalScheme 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ı içeri aktararak yeni eklenen SignOutAsync çağrıyı çözün:

using Microsoft.AspNetCore.Authentication;

IdentityUser POCO gezinti özellikleri ekleme

Temel IdentityUser POCO'nun (Düz Eski CLR Nesnesi) Entity Framework (EF) Çekirdek gezinti özellikleri kaldırıldı. 1.x projeniz bu özellikleri kullandıysa, bunları el ile 2.0 projesine geri 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>>();

Migrations'ı çalıştırırken EF Core yinelenen yabancı anahtarları önlemek için sınıfınızın IdentityDbContext OnModelCreating yöntemine aşağıdakileri ekleyin (çağrıdan base.OnModelCreating(); sonra):

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

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

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

Bu yöntem de şu şekilde Views/Account/Login.cshtml 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 kullanın GetExternalAuthenticationSchemesAsync . içindeki ManageController.cs değişikliği aşağıdaki koda benzer:

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

içinde Login.cshtml, AuthenticationScheme döngüsünde foreach erişilen özellik olarak Namedeğ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

nesnesi ManageLoginsViewModel eyleminde ManageLogins ManageController.cskullanılır. 1.x projelerinde nesnenin OtherLogins özellik dönüş türü olur IList<AuthenticationDescription>. Bu dönüş türü için içeri aktarma Microsoft.AspNetCore.Http.Authenticationgerekir:

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 içeri Microsoft.AspNetCore.Authentication aktarma ile 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 GitHub'da Auth 2.0 tartışması sorununa bakın.