Aracılığıyla paylaş


SPA'lar için Web API arka ucu güvenliğini sağlamak için kullanma Identity

Not

Bu, bu makalenin en son sürümü değildir. Geçerli sürüm için bu makalenin .NET 8 sürümüne bakın.

Önemli

Bu bilgiler, ticari olarak piyasaya sürülmeden önce önemli ölçüde değiştirilebilen bir yayın öncesi ürünle ilgilidir. Burada verilen bilgilerle ilgili olarak Microsoft açık veya zımni hiçbir garanti vermez.

Geçerli sürüm için bu makalenin .NET 8 sürümüne bakın.

ASP.NET Core Identity , kimlik doğrulaması, yetkilendirme ve kimlik yönetimini işleyen API'ler sağlar. API'ler, tabanlı kimlik doğrulaması ile cookieWeb API'sinin arka uç noktalarının güvenliğini sağlamayı mümkün kılar. kullanamıyor cookieistemcileri için belirteç tabanlı bir seçenek vardır.

Bu makalede Angular, React ve Vue uygulamaları gibi SPA'lar için bir Web API arka ucu güvenliğini sağlamak için nasıl kullanılacağı Identity gösterilmektedir. Uygulamaların güvenliğini Blazor WebAssemblysağlamak için aynı arka uç API'leri kullanılabilir.

Önkoşullar

Bu makalede gösterilen adımlar, aşağıdaki ASP.NET Core Web API'sine kimlik doğrulaması ve yetkilendirme ekler:

  • kimlik doğrulaması için henüz yapılandırılmamış.
  • net8.0 Hedefler veya üzeri.
  • En düşük API veya denetleyici tabanlı API olabilir.

Bu makaledeki test yönergelerinden bazıları, proje şablonuna dahil edilen Swagger kullanıcı arabirimini kullanır. Swagger kullanıcı arabiriminin web API'sinin arka ucuyla kullanılması Identity gerekmez.

NuGet paketlerini yükleme

Aşağıdaki NuGet paketlerini yükleyin:

Başlamanın en hızlı yolu için bellek içi veritabanını kullanın.

Test veya üretim kullanımı sırasında oturumlar arasında kullanıcı verilerini kaydetmek için veritabanını daha sonra SQLite veya SQL Server olarak değiştirin. Bu, başlangıç öğreticisinde gösterildiğiEF Coregibi veritabanının geçişler aracılığıyla oluşturulmasını gerektirdiğinden bellek içiyle karşılaştırıldığında biraz karmaşıklık sağlar.

Visual Studio'da NuGet paket yöneticisini veya dotnet add package CLI komutunu kullanarak bu paketleri yükleyin.

Oluşturma IdentityDbContext

öğesinden IdentityDbContext<TUser>devralan adlı ApplicationDbContext bir sınıf ekleyin:

using Microsoft.AspNetCore.Identity.EntityFrameworkCore;
using Microsoft.AspNetCore.Identity;
using Microsoft.EntityFrameworkCore;

public class ApplicationDbContext : IdentityDbContext<IdentityUser>
{
    public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options) :
        base(options)
    { }
}

Gösterilen kod, veritabanını farklı ortamlar için yapılandırmayı mümkün kılan özel bir oluşturucu sağlar.

Bu using adımlarda gösterilen kodu eklerken aşağıdaki yönergelerden birini veya daha fazlasını gerektiği gibi ekleyin.

using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Identity.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore;

Bağlamı EF Core yapılandırma

Daha önce belirtildiği gibi, kullanmaya başlamanın en basit yolu bellek içi veritabanını kullanmaktır. Bellek içi ile her çalıştırma yeni bir veritabanıyla başlar ve geçişleri kullanmaya gerek yoktur. çağrısından WebApplication.CreateBuilder(args)sonra, bellek içi veritabanı kullanacak şekilde yapılandırmak Identity için aşağıdaki kodu ekleyin:

builder.Services.AddDbContext<ApplicationDbContext>(
    options => options.UseInMemoryDatabase("AppDb"));

Test veya üretim kullanımı sırasında oturumlar arasında kullanıcı verilerini kaydetmek için veritabanını daha sonra SQLite veya SQL Server olarak değiştirin.

Kapsayıcıya hizmet ekleme Identity

çağrısından WebApplication.CreateBuilder(args)sonra bağımlılık ekleme (DI) kapsayıcısına hizmet eklemek için çağrısı AddAuthorization yapın:

builder.Services.AddAuthorization();

API'leri etkinleştirme Identity

çağrısından WebApplication.CreateBuilder(args)sonra, çağrısı AddIdentityApiEndpoints<TUser>(IServiceCollection) ve AddEntityFrameworkStores<TContext>(IdentityBuilder).

builder.Services.AddIdentityApiEndpoints<IdentityUser>()
    .AddEntityFrameworkStores<ApplicationDbContext>();

Varsayılan olarak hem s hem de cookieözel belirteçler etkinleştirilir. Cookies ve belirteçleri, oturum açma uç noktasındaki useCookies sorgu dizesi parametresi ise trueoturum açma sırasında verilir.

Rotaları eşleme Identity

çağrısından builder.Build()sonra uç noktaları eşlemek Identity için çağrısında MapIdentityApi<TUser>(IEndpointRouteBuilder) bulunur:

app.MapIdentityApi<IdentityUser>();

Seçili uç noktaların güvenliğini sağlama

Bir uç noktanın RequireAuthorization güvenliğini sağlamak için, yolu tanımlayan çağrıda Map{Method} uzantı yöntemini kullanın. Örneğin:

app.MapGet("/weatherforecast", (HttpContext httpContext) =>
{
    var forecast = Enumerable.Range(1, 5).Select(index =>
        new WeatherForecast
        {
            Date = DateOnly.FromDateTime(DateTime.Now.AddDays(index)),
            TemperatureC = Random.Shared.Next(-20, 55),
            Summary = summaries[Random.Shared.Next(summaries.Length)]
        })
        .ToArray();
    return forecast;
})
.WithName("GetWeatherForecast")
.WithOpenApi()
.RequireAuthorization();

yöntemi RequireAuthorization aşağıdakiler için de kullanılabilir:

  • Aşağıdaki örnekte gösterildiği gibi Swagger UI uç noktalarının güvenliğini sağlama:

    app.MapSwagger().RequireAuthorization();
    
  • Aşağıdaki örnekte gösterildiği gibi belirli bir talep veya izinle güvenlidir:

    .RequireAuthorization("Admin");
    

Denetleyici tabanlı bir web API projesinde, [Authorize] özniteliğini bir denetleyiciye veya eyleme uygulayarak uç noktaların güvenliğini sağlayın.

API’yi test etme

Kimlik doğrulamasını test etmenin hızlı bir yolu, bellek içi veritabanını ve proje şablonuna dahil edilen Swagger kullanıcı arabirimini kullanmaktır. Aşağıdaki adımlar, API'nin Swagger kullanıcı arabirimiyle nasıl test yapılacağını gösterir. Swagger UI uç noktalarının güvenli olmadığından emin olun.

Güvenli uç noktaya erişme girişimi

  • Uygulamayı çalıştırın ve Swagger kullanıcı arabirimine gidin.
  • Web API şablonu tarafından oluşturulan bir projede olduğu gibi /weatherforecast güvenli bir uç noktayı genişletin.
  • Deneyin'i seçin.
  • Yürüt'ü seçin. Yanıt: 401 - not authorized.

Test kaydı

  • Genişletin /register ve Deneyin'i seçin.

  • Kullanıcı arabiriminin Parametreler bölümünde örnek bir istek gövdesi gösterilir:

    {
      "email": "string",
      "password": "string"
    }
    
  • "dize" yerine geçerli bir e-posta adresi ve parola yazın ve yürüt'e tıklayın.

    Varsayılan parola doğrulama kurallarına uymak için parola en az altı karakter uzunluğunda olmalı ve aşağıdaki karakterlerden en az birini içermelidir:

    • Büyük harf
    • Küçük harf
    • Sayısal basamak
    • Nonalphanumeric karakteri

    Geçersiz bir e-posta adresi veya hatalı parola girerseniz sonuç doğrulama hatalarını içerir. Aşağıda doğrulama hataları içeren bir yanıt gövdesi örneği verilmişti:

    {
      "type": "https://tools.ietf.org/html/rfc9110#section-15.5.1",
      "title": "One or more validation errors occurred.",
      "status": 400,
      "errors": {
        "PasswordTooShort": [
          "Passwords must be at least 6 characters."
        ],
        "PasswordRequiresNonAlphanumeric": [
          "Passwords must have at least one non alphanumeric character."
        ],
        "PasswordRequiresDigit": [
          "Passwords must have at least one digit ('0'-'9')."
        ],
        "PasswordRequiresLower": [
          "Passwords must have at least one lowercase ('a'-'z')."
        ]
      }
    }
    

    Hatalar ProblemDetails biçiminde döndürülür, böylece istemci bunları ayrıştırabilir ve gerektiğinde doğrulama hatalarını görüntüleyebilir.

    Başarılı bir kayıt yanıtla 200 - OK sonuçlanırsa.

Oturum açmayı test et

  • Genişletin /login ve Deneyin'i seçin. Örnek istek gövdesi iki ek parametre gösterir:

    {
      "email": "string",
      "password": "string",
      "twoFactorCode": "string",
      "twoFactorRecoveryCode": "string"
    }
    

    Bu örnek için fazladan JSON özellikleri gerekli değildir ve silinebilir. useCookies seçeneğini true olarak ayarlayın.

  • "string" değerini, kaydetmek için kullandığınız e-posta adresi ve parolayla değiştirin ve ardından Yürüt'e tıklayın.

    Başarılı bir oturum açma işlemi, yanıt üst bilgisinde bulunan bir 200 - OKcookie yanıtla sonuçlanır.

Güvenli uç noktayı yeniden test etme

Başarılı bir oturum açma işleminin ardından güvenli uç noktayı yeniden çalıştırın. Kimlik doğrulaması cookie istekle birlikte otomatik olarak gönderilir ve uç nokta yetkilendirilmiştir. Cookietabanlı kimlik doğrulaması, tarayıcıda güvenli bir şekilde yerleşiktir ve "yalnızca çalışır."

Uyuşmayan istemcilerle test etme

Bazı web istemcileri varsayılan olarak üst bilgide s içermeyebilir cookie:

  • API'leri test etmek için bir araç kullanıyorsanız ayarlarda etkinleştirmeniz cookiegerekebilir.

  • JavaScript fetch API'sinde varsayılan olarak s yoktur cookie. Seçeneklerdeki değere include ayarlayarak credentials bunları etkinleştirin.

  • Bir HttpClientBlazor WebAssembly uygulamada çalışan, aşağıdaki örnekte olduğu gibi kimlik bilgilerini içermesi gerekir HttpRequestMessage :

    request.SetBrowserRequestCredential(BrowserRequestCredentials.Include);
    

Belirteç tabanlı kimlik doğrulamayı kullanma

Desteklemeyen cookieistemciler için oturum açma API'si belirteç istemek için bir parametre sağlar. Sonraki isteklerin kimliğini doğrulamak için kullanılabilecek özel bir belirteç (ASP.NET Core kimlik platformuna özel bir belirteç) verilir. Belirteç üst bilgisinde Authorization taşıyıcı belirteç olarak geçirilir. Yenileme belirteci de sağlanır. Bu belirteç, kullanıcının yeniden oturum açmaya zorlamadan eskisinin süresi dolduğunda uygulamanın yeni bir belirteç istemesine olanak tanır.

Belirteçler standart JSON Web Belirteçleri (JWT) değildir. Yerleşik Identity API öncelikli olarak basit senaryolar için tasarlandığından özel belirteçlerin kullanımı kasıtlıdır. Belirteç seçeneğinin tam özellikli bir kimlik hizmeti sağlayıcısı veya belirteç sunucusu olması amaçlanmamıştır, bunun yerine kullanamayabilen cookieistemciler için bir alternatiftircookie.

Belirteç tabanlı kimlik doğrulamasını useCookies kullanmak için, uç noktayı çağırırken sorgu dizesi parametresini /loginfalse olarak ayarlayın. Belirteçler taşıyıcı kimlik doğrulama düzenini kullanır. çağrısından /logindöndürülen belirteci kullanarak, korumalı uç noktalara yapılan sonraki çağrılar erişim belirtecinin bulunduğu üst <token> bilgiyi Authorization: Bearer <token> eklemelidir. Daha fazla bilgi için bu makalenin devamında yer alan POST /login Uç noktayı kullanma bölümüne bakın.

Oturumu kapat

Kullanıcının oturumu kapatması için bir yol sağlamak için aşağıdaki örneğe benzer bir /logout uç nokta tanımlayın:

app.MapPost("/logout", async (SignInManager<IdentityUser> signInManager,
    [FromBody] object empty) =>
{
    if (empty != null)
    {
        await signInManager.SignOutAsync();
        return Results.Ok();
    }
    return Results.Unauthorized();
})
.WithOpenApi()
.RequireAuthorization();

Bu uç nokta çağrılırken istek gövdesinde boş JSbir ON nesnesi ({}) sağlayın. Aşağıdaki kod, oturumu kapatma uç noktasına yönelik bir çağrı örneğidir:

public signOut() {
  return this.http.post('/logout', {}, {
    withCredentials: true,
    observe: 'response',
    responseType: 'text'

MapIdentityApi<TUser> noktalar

çağrısı MapIdentityApi<TUser> aşağıdaki uç noktaları uygulamaya ekler:

Uç noktayı POST /register kullanma

İstek gövdesinin ve Password özellikleri olmalıdırEmail:

{
  "email": "string",
  "password": "string",
}

Daha fazla bilgi için bkz.

Uç noktayı POST /login kullanma

İstek gövdesinde Email ve Password gereklidir. İki öğeli kimlik doğrulaması (2FA) etkinse TwoFactorCode veya TwoFactorRecoveryCode gereklidir. 2FA etkin değilse, hem hem twoFactorRecoveryCodede twoFactorCode atla. Daha fazla bilgi için bu makalenin devamında yer alan POST /manage/2fa Uç noktayı kullanma bölümüne bakın.

2FA'nın etkinleştirilmediği bir istek gövdesi örneği aşağıda verilmişti:

{
  "email": "string",
  "password": "string"
}

2FA'nın etkinleştirildiği istek gövdesi örnekleri aşağıda verilmiştir:

  • {
      "email": "string",
      "password": "string",
      "twoFactorCode": "string",
    }
    
  • {
      "email": "string",
      "password": "string",
      "twoFactorRecoveryCode": "string"
    }
    

Uç nokta bir sorgu dizesi parametresi bekler:

  • useCookies- Tabanlı kimlik doğrulaması için cookieolarak true ayarlanır. Belirteç tabanlı kimlik doğrulaması için olarak false ayarlayın veya atla seçeneğini belirleyin.

Tabanlı kimlik doğrulaması hakkında cookiedaha fazla bilgi için bu makalenin önceki bölümlerindeki Oturum açmayı test edin bölümüne bakın.

Belirteç tabanlı kimlik doğrulaması

Belirteç useCookies tabanlı kimlik doğrulaması etkinleştirilir false veya atlanırsa. Yanıt gövdesi aşağıdaki özellikleri içerir:

{
  "tokenType": "string",
  "accessToken": "string",
  "expiresIn": 0,
  "refreshToken": "string"
}

Bu özellikler hakkında daha fazla bilgi için bkz AccessTokenResponse. .

Aşağıdaki örnekte gösterildiği gibi kimliği doğrulanmış istekler yapmak için erişim belirtecini bir üst bilgi içine yerleştirin

Authorization: Bearer {access token}

Erişim belirtecinin süresi dolmak üzereyken /refresh uç noktasını çağırın.

Uç noktayı POST /refresh kullanma

Yalnızca belirteç tabanlı kimlik doğrulaması ile kullanmak için. Kullanıcıyı yeniden oturum açmaya zorlamadan yeni bir erişim belirteci alır. Erişim belirtecinin süresi dolmak üzereyken bu uç noktayı çağırın.

İstek gövdesi yalnızca öğesini RefreshTokeniçerir. aşağıda bir istek gövdesi örneği verilmişti:

{
  "refreshToken": "string"
}

Çağrı başarılı olursa, yanıt gövdesi aşağıdaki örnekte gösterildiği gibi yeni AccessTokenResponsebir olur:

{
  "tokenType": "string",
  "accessToken": "string",
  "expiresIn": 0,
  "refreshToken": "string"
}

Uç noktayı GET /confirmEmail kullanma

E-posta onayı için ayarlanırsa Identity , uç noktaya yapılan başarılı bir çağrı /register uç noktaya bağlantı /confirmEmail içeren bir e-posta gönderir. Bağlantı aşağıdaki sorgu dizesi parametrelerini içerir:

  • userId
  • code
  • changedEmail - Yalnızca kullanıcı kayıt sırasında e-posta adresini değiştirdiyse eklenir.

Identity onay e-postası için varsayılan metin sağlar. Varsayılan olarak, e-posta konusu "E-postanızı onaylayın" şeklindedir ve e-posta gövdesi aşağıdaki örneğe benzer:

 Please confirm your account by <a href='https://contoso.com/confirmEmail?userId={user ID}&code={generated code}&changedEmail={new email address}'>clicking here</a>.

RequireConfirmedEmail özelliği olarak ayarlanırsatrue, kullanıcı e-postadaki bağlantıya tıklayarak e-posta adresi onaylanana kadar oturum açamaz. Uç /confirmEmail nokta:

  • E-posta adresini onaylar ve kullanıcının oturum açmasını sağlar.
  • Yanıt gövdesinde "E-postanızı onayladığınız için teşekkür ederiz" metnini döndürür.

E-posta onayı için ayarlamak Identity üzere içine kod trueProgram.csRequireConfirmedEmail ekleyin ve DI kapsayıcısına uygulayan IEmailSender bir sınıf ekleyin. Örneğin:

builder.Services.Configure<IdentityOptions>(options =>
{
    options.SignIn.RequireConfirmedEmail = true;
});

builder.Services.AddTransient<IEmailSender, EmailSender>();

Daha fazla bilgi için bkz . ASP.NET Core'da hesap onayı ve parola kurtarma.

Identity , 2FA ve parola sıfırlama gibi gönderilmesi gereken diğer e-postalar için varsayılan metin sağlar. Bu e-postaları özelleştirmek için arabiriminin IEmailSender özel bir uygulamasını sağlayın. Yukarıdaki örnekte, EmailSender uygulayan bir sınıftır IEmailSender. uygulayan IEmailSenderbir sınıf örneği de dahil olmak üzere daha fazla bilgi için bkz . ASP.NET Core'da hesap onayı ve parola kurtarma.

Uç noktayı POST /resendConfirmationEmail kullanma

Yalnızca adres kayıtlı bir kullanıcı için geçerliyse e-posta gönderir.

İstek gövdesi yalnızca öğesini Emailiçerir. aşağıda bir istek gövdesi örneği verilmişti:

{
  "email": "string"
}

Daha fazla bilgi için bu makalenin önceki bölümlerinde yer alan GET /confirmEmail Uç noktayı kullanma bölümüne bakın.

Uç noktayı POST /forgotPassword kullanma

Parola sıfırlama kodu içeren bir e-posta oluşturur. Bu kodu yeni bir parolayla adresine /resetPassword gönderin.

İstek gövdesi yalnızca öğesini Emailiçerir. Bir örnek aşağıda verilmiştir:

{
  "email": "string"
}

E-posta göndermeyi etkinleştirme Identity hakkında bilgi için bkz. Uç noktayı kullanmaGET /confirmEmail.

Uç noktayı POST /resetPassword kullanma

Sıfırlama kodunu aldıktan sonra uç noktayı çağırarak bu uç noktayı çağırın /forgotPassword .

İstek gövdesi için , ResetCodeve NewPasswordgerekirEmail. Bir örnek aşağıda verilmiştir:

{
  "email": "string",
  "resetCode": "string",
  "newPassword": "string"
}

Uç noktayı POST /manage/2fa kullanma

Kullanıcı için iki öğeli kimlik doğrulamasını (2FA) yapılandırıyor. 2FA etkinleştirildiğinde, başarılı oturum açma işlemi için e-posta adresi ve parolaya ek olarak bir kimlik doğrulayıcı uygulaması tarafından oluşturulan bir kod gerekir.

2FA'yı etkinleştirme

Şu anda kimliği doğrulanmış olan kullanıcı için 2FA'yı etkinleştirmek için:

  • İstek gövdesinde /manage/2fa boş JSbir ON nesnesi ({}) göndererek uç noktayı çağırın.

  • Yanıt gövdesi, bu noktada gerekli olmayan bazı diğer özelliklerle birlikte öğesini sağlar SharedKey . Kimlik doğrulayıcı uygulamasını ayarlamak için paylaşılan anahtar kullanılır. Yanıt gövdesi örneği:

    {
      "sharedKey": "string",
      "recoveryCodesLeft": 0,
      "recoveryCodes": null,
      "isTwoFactorEnabled": false,
      "isMachineRemembered": false
    }
    
  • Zaman tabanlı tek seferlik parola (TOTP) almak için paylaşılan anahtarı kullanın. Daha fazla bilgi için bkz . ASP.NET Core'da TOTP kimlik doğrulayıcı uygulamaları için QR kodu oluşturmayı etkinleştirme.

  • /manage/2fa TOTP'yi ve "enable": true istek gövdesinde göndererek uç noktayı çağırın. Örneğin:

    {
      "enable": true,
      "twoFactorCode": "string"
    }
    
  • Yanıt gövdesi bunun doğru olduğunu IsTwoFactorEnabled onaylar ve sağlar RecoveryCodes. Kimlik doğrulayıcı uygulaması kullanılabilir olmadığında oturum açmak için kurtarma kodları kullanılır. 2FA başarıyla etkinleştirildikten sonra yanıt gövdesi örneği:

    {
      "sharedKey": "string",
      "recoveryCodesLeft": 10,
      "recoveryCodes": [
        "string",
        "string",
        "string",
        "string",
        "string",
        "string",
        "string",
        "string",
        "string",
        "string"
      ],
      "isTwoFactorEnabled": true,
      "isMachineRemembered": false
    }
    

2FA ile oturum açma

İstek gövdesinde /login e-posta adresini, parolayı ve TOTP'yi göndererek uç noktayı çağırın. Örneğin:

{
  "email": "string",
  "password": "string",
  "twoFactorCode": "string"
}

Kullanıcının kimlik doğrulayıcı uygulamasına erişimi yoksa, 2FA etkinleştirildiğinde sağlanan kurtarma kodlarından biriyle uç noktayı çağırarak /login oturum açın. İstek gövdesi aşağıdaki örneğe benzer:

{
  "email": "string",
  "password": "string",
  "twoFactorRecoveryCode": "string"
}

Kurtarma kodlarını sıfırlama

Yeni bir kurtarma kodları koleksiyonu almak için, olarak ayarlanmış trueolarak bu uç noktayı ResetRecoveryCodes çağırın. aşağıda bir istek gövdesi örneği verilmişti:

{
  "resetRecoveryCodes": true
}

Paylaşılan anahtarı sıfırlama

Yeni bir rastgele paylaşılan anahtar almak için bu uç noktayı ResetSharedKey olarak ayarlayın true. aşağıda bir istek gövdesi örneği verilmişti:

{
  "resetSharedKey": true
}

Anahtarın sıfırlanması, kimliği doğrulanmış kullanıcının daha sonraki bir istek tarafından yeniden etkinleştirilene kadar iki öğeli oturum açma gereksinimini otomatik olarak devre dışı bırakır.

Makineyi unutun

Varsa "beni anımsa bayrağını" temizlemek cookie için bu uç noktayı ForgetMachine true olarak ayarlayın. aşağıda bir istek gövdesi örneği verilmişti:

{
  "forgetMachine": true
}

Bu uç noktanın belirteç tabanlı kimlik doğrulaması üzerinde hiçbir etkisi yoktur.

Uç noktayı GET /manage/info kullanma

Oturum açmış kullanıcının e-posta adresini ve e-posta onay durumunu alır. Talepler güvenlik nedeniyle bu uç noktadan atlandı. Talep gerekiyorsa, talepler için bir uç nokta ayarlamak üzere sunucu tarafı API'lerini kullanın. Ya da tüm kullanıcıların taleplerini paylaşmak yerine, bir talebi kabul eden ve kullanıcının sahip olup olmadığını yanıtlayan bir doğrulama uç noktası sağlayın.

İstek herhangi bir parametre gerektirmez. Yanıt gövdesi, aşağıdaki örnekte olduğu gibi ve IsEmailConfirmed özelliklerini içerirEmail:

{
  "email": "string",
  "isEmailConfirmed": true
}

Uç noktayı POST /manage/info kullanma

Oturum açmış kullanıcının e-posta adresini ve parolasını Güncelleştirmeler. Aşağıdaki örnekte gösterildiği gibi istek gövdesinde , NewPasswordve OldPassword gönderinNewEmail:

{
  "newEmail": "string",
  "newPassword": "string",
  "oldPassword": "string"
}

Yanıt gövdesinin bir örneği aşağıda verilmişti:

{
  "email": "string",
  "isEmailConfirmed": false
}

Ayrıca bkz.

Daha fazla bilgi edinmek için aşağıdaki kaynaklara bakın:

ASP.NET Core şablonları, API yetkilendirme desteğini kullanarak Tek Sayfalı Uygulamalarda (SPA) kimlik doğrulaması sunar. Kullanıcıların kimliğini doğrulamak ve depolamak için ASP.NET CoreIdentity, OpenID Bağlan uygulamak için Duende Identity Server ile birleştirilir.

Önemli

Duende Yazılımı, Duende Identity Server'ın üretim kullanımı için lisans ücreti ödemenizi gerektirebilir. Daha fazla bilgi için, bkz. ASP.NET Core 5.0'den 6.0'a geçiş.

Angular ve React proje şablonlarına, Web Uygulaması (Model-View-Controller) (MVC) ve Web Uygulaması (RazorSayfalar) proje şablonlarındaki kimlik doğrulama parametresine benzer bir kimlik doğrulama parametresi eklendi. İzin verilen parametre değerleri None ve Individual'dır. React.js ve Redux proje şablonu şu anda kimlik doğrulama parametresini desteklemiyor.

API yetkilendirme desteğiyle uygulama oluşturma

Kullanıcı kimlik doğrulaması ve yetkilendirme hem Angular hem de React SPA'ları ile kullanılabilir. Bir komut kabuğu açın ve aşağıdaki komutu çalıştırın:

Angular:

dotnet new angular -au Individual

Tepki:

dotnet new react -au Individual

Yukarıdaki komut, SPA içeren bir ClientApp diziniyle bir ASP.NET Core uygulaması oluşturur.

Uygulamanın ASP.NET Core bileşenlerinin genel açıklaması

Aşağıdaki bölümlerde, kimlik doğrulama desteği dahil edildiğinde projeye yapılan eklemeler açıklanmaktadır:

Program.cs

Aşağıdaki kod örnekleri Microsoft.AspNetCore.ApiAuthorization'a dayanır .IdentitySunucu NuGet paketi. Örneklerde ve uzantı yöntemlerini kullanarak AddApiAuthorization API kimlik doğrulaması ve AddIdentityServerJwt yetkilendirmesi yapılandırılır. Kimlik doğrulamasıyla React veya Angular SPA proje şablonlarını kullanan projeler bu pakete bir başvuru içerir.

dotnet new angular -au Individual aşağıdaki Program.cs dosyayı oluşturur:

using Microsoft.AspNetCore.Authentication;
using Microsoft.EntityFrameworkCore;
using output_directory_name.Data;
using output_directory_name.Models;

var builder = WebApplication.CreateBuilder(args);

var connectionString = builder.Configuration.GetConnectionString("DefaultConnection") ?? throw new InvalidOperationException("Connection string 'DefaultConnection' not found.");
builder.Services.AddDbContext<ApplicationDbContext>(options =>
    options.UseSqlite(connectionString));
builder.Services.AddDatabaseDeveloperPageExceptionFilter();

builder.Services.AddDefaultIdentity<ApplicationUser>(options => options.SignIn.RequireConfirmedAccount = true)
    .AddEntityFrameworkStores<ApplicationDbContext>();

builder.Services.AddIdentityServer()
    .AddApiAuthorization<ApplicationUser, ApplicationDbContext>();

builder.Services.AddAuthentication()
    .AddIdentityServerJwt();

builder.Services.AddControllersWithViews();
builder.Services.AddRazorPages();

var app = builder.Build();

if (app.Environment.IsDevelopment())
{
    app.UseMigrationsEndPoint();
}
else
{
    app.UseHsts();
}

app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();

app.UseAuthentication();
app.UseIdentityServer();
app.UseAuthorization();

app.MapControllerRoute(
    name: "default",
    pattern: "{controller}/{action=Index}/{id?}");
app.MapRazorPages();

app.MapFallbackToFile("index.html");

app.Run();

Yukarıdaki kod aşağıdakileri yapılandırıyor:

  • Identity varsayılan kullanıcı arabirimiyle:

    builder.Services.AddDbContext<ApplicationDbContext>(options =>
        options.UseSqlite(connectionString));
    builder.Services.AddDatabaseDeveloperPageExceptionFilter();
    
    builder.Services.AddDefaultIdentity<ApplicationUser>(options => options.SignIn.RequireConfirmedAccount = true)
        .AddEntityFrameworkStores<ApplicationDbContext>();
    
  • IdentitySunucu'nun üzerinde bazı varsayılan ASP.NET Core kurallarını ayarlayan ek AddApiAuthorization bir yardımcı yöntemi olan Identitysunucu:

    builder.Services.AddIdentityServer()
        .AddApiAuthorization<ApplicationUser, ApplicationDbContext>();
    
  • Uygulamayı Sunucu tarafından Identityüretilen JWT belirteçlerini doğrulayacak şekilde yapılandıran ek AddIdentityServerJwt bir yardımcı yöntemiyle kimlik doğrulaması:

    builder.Services.AddAuthentication()
    .AddIdentityServerJwt();
    
  • İstek kimlik bilgilerini doğrulamak ve kullanıcıyı istek bağlamında ayarlamakla sorumlu kimlik doğrulama ara yazılımı:

    app.UseAuthentication();
    
  • IdentityOpenID Bağlan uç noktalarını kullanıma sunan Sunucu ara yazılımı:

    app.UseIdentityServer();
    

Linux'ta Azure Uygulaması Hizmeti

Linux'ta Azure Uygulaması Hizmeti dağıtımları için vereni açıkça belirtin:

builder.Services.Configure<JwtBearerOptions>(
    IdentityServerJwtConstants.IdentityServerJwtBearerScheme, 
    options =>
    {
        options.Authority = "{AUTHORITY}";
    });

Yukarıdaki kodda {AUTHORITY} yer tutucu, OpenID Bağlan çağrıları yapılırken kullanılacak yer tutucudurAuthority.

Örnek:

options.Authority = "https://contoso-service.azurewebsites.net";

AddApiAuthorization

Bu yardımcı yöntem, Sunucu'ya desteklenen yapılandırmamızı kullanacak şekilde yapılandırılır Identity. IdentitySunucu, uygulama güvenliği sorunlarını işlemeye yönelik güçlü ve genişletilebilir bir çerçevedir. Aynı zamanda, en yaygın senaryolar için gereksiz karmaşıklığı ortaya çıkarır. Sonuç olarak, iyi bir başlangıç noktası olarak kabul edilen bir dizi kural ve yapılandırma seçeneği sağlanır. Kimlik doğrulaması gereksinimleriniz değiştikten sonra, kimlik doğrulamasını gereksinimlerinize uyacak şekilde özelleştirmek için Sunucu'nun Identitytüm gücü kullanılabilir duruma gelir.

AddIdentityServerJwt

Bu yardımcı yöntem, uygulama için varsayılan kimlik doğrulama işleyicisi olarak bir ilke şeması yapılandırıyor. İlke, "/Identity" URL alanında herhangi bir alt yola yönlendirilen tüm isteklerin işlenmesine Identity izin verecek Identity şekilde yapılandırılmıştır. diğer JwtBearerHandler tüm istekleri işler. Ayrıca, bu yöntem varsayılan kapsamı <<ApplicationName>>API olan Identitybir <<ApplicationName>>API API kaynağını Sunucu'ya kaydeder ve uygulama için Sunucu tarafından Identityverilen belirteçleri doğrulamak için JWT Taşıyıcı belirteç ara yazılımını yapılandırılır.

WeatherForecastController

dosyasında, kaynağa erişmek için kullanıcının varsayılan ilkeye göre yetkilendirilmiş olması gerektiğini belirten sınıfına uygulanan özniteliğine dikkat edin [Authorize] . Varsayılan yetkilendirme ilkesi, yukarıda bahsedilen ilke düzeni tarafından AddIdentityServerJwt ayarlanan varsayılan kimlik doğrulama düzenini kullanacak şekilde yapılandırılır ve bu da bu tür yardımcı yöntemle yapılandırılanı uygulamaya yönelik istekler için varsayılan işleyici haline getirir JwtBearerHandler .

ApplicationDbContext

Dosyasında, aynı değerin DbContext içinde kullanıldığına Identity dikkat edin; özel durum, sunucu şemasını Identityiçerecek şekilde genişletir ApiAuthorizationDbContext (öğesinden IdentityDbContextdaha türetilmiş bir sınıf).

Veritabanı şemasının tam denetimini elde etmek için, kullanılabilir IdentityDbContext sınıflardan birini devralın ve yöntemini çağırarak builder.ConfigurePersistedGrantContext(_operationalStoreOptions.Value)OnModelCreating bağlamı şemayı Identity içerecek şekilde yapılandırın.

OidcConfigurationController

dosyasında, istemcinin kullanması gereken OIDC parametrelerini sunmak için sağlanan uç noktaya dikkat edin.

appsettings.json

appsettings.json Proje kökü dosyasında, yapılandırılmış istemcilerin listesini açıklayan yeni IdentityServer bir bölüm vardır. Aşağıdaki örnekte tek bir istemci vardır. İstemci adı uygulama adına karşılık gelir ve kural tarafından OAuth ClientId parametresine eşlenir. Profil, yapılandırılan uygulama türünü gösterir. Sunucu için yapılandırma işlemini basitleştiren kuralları yönlendirmek için dahili olarak kullanılır. Uygulama profilleri bölümünde açıklandığı gibi, kullanılabilir birkaç profil vardır.

"IdentityServer": {
  "Clients": {
    "angularindividualpreview3final": {
      "Profile": "IdentityServerSPA"
    }
  }
}

appsettings.Development.json

appsettings.Development.json Proje kökü dosyasında belirteçleri imzalamak için kullanılan anahtarı açıklayan bir IdentityServer bölüm vardır. Üretime dağıtılırken, Üretime dağıt bölümünde açıklandığı gibi bir anahtarın uygulamayla birlikte sağlanması ve dağıtılması gerekir.

"IdentityServer": {
  "Key": {
    "Type": "Development"
  }
}

Angular uygulamasının genel açıklaması

Angular şablonundaki kimlik doğrulaması ve API yetkilendirme desteği, ClientApp/src/api-authorization dizinindeki kendi Angular modülünde bulunur. Modül aşağıdaki öğelerden oluşur:

  • 3 bileşen:
    • login.component.ts: Uygulamanın oturum açma akışını işler.
    • logout.component.ts: Uygulamanın oturum kapatma akışını işler.
    • login-menu.component.ts: Aşağıdaki bağlantı kümelerinden birini görüntüleyen pencere öğesi:
      • Kullanıcı kimliği doğrulandığında kullanıcı profili yönetimi ve oturumu kapatma bağlantıları.
      • Kullanıcının kimliği doğrulanmamışsa kayıt ve oturum açma bağlantıları.
  • Yollara eklenebilen ve bir kullanıcının yolu ziyaret etmeden önce kimliğinin doğrulanması gereken bir yol koruyucusu AuthorizeGuard .
  • Kullanıcının kimliği doğrulandığında API'yi hedefleyen giden HTTP isteklerine erişim belirtecini ekleyen bir HTTP kesme noktası AuthorizeInterceptor .
  • Kimlik doğrulama işleminin alt düzey ayrıntılarını işleyen ve kimliği doğrulanmış kullanıcı hakkındaki bilgileri uygulamanın geri kalanında kullanıma sunan bir hizmet AuthorizeService .
  • Uygulamanın kimlik doğrulama bölümleriyle ilişkili yolları tanımlayan bir Angular modülü. Oturum açma menüsü bileşenini, kesme noktasını, korumayı ve hizmeti uygulamanın geri kalanından tüketim için kullanıma sunar.

React uygulamasının genel açıklaması

React şablonundaki kimlik doğrulaması ve API yetkilendirme desteği ClientApp/src/components/api-authorization dizininde bulunur. Aşağıdaki öğelerden oluşur:

  • 4 bileşen:
    • Login.js: Uygulamanın oturum açma akışını işler.
    • Logout.js: Uygulamanın oturum kapatma akışını işler.
    • LoginMenu.js: Aşağıdaki bağlantı kümelerinden birini görüntüleyen pencere öğesi:
      • Kullanıcı kimliği doğrulandığında kullanıcı profili yönetimi ve oturumu kapatma bağlantıları.
      • Kullanıcının kimliği doğrulanmamışsa kayıt ve oturum açma bağlantıları.
    • AuthorizeRoute.js: Parametresinde Component belirtilen bileşeni işlemeden önce kullanıcının kimliğinin doğrulanması gereken bir yol bileşeni.
  • Kimlik doğrulama işleminin alt düzey ayrıntılarını işleyen ve kimliği doğrulanmış kullanıcı hakkındaki bilgileri tüketim için uygulamanın geri kalanında kullanıma sunan dışarı aktarılan authService sınıf AuthorizeService örneği.

Çözümün ana bileşenlerini gördüğünüze göre, uygulama senaryolarına daha ayrıntılı bir şekilde göz atabilirsiniz.

Yeni BIR API'de yetkilendirme iste

Varsayılan olarak, sistem yeni API'ler için kolayca yetkilendirme gerektirecek şekilde yapılandırılır. Bunu yapmak için yeni bir denetleyici oluşturun ve özniteliğini denetleyici sınıfına veya denetleyici içindeki herhangi bir eyleme ekleyin [Authorize] .

API kimlik doğrulama işleyicisini özelleştirme

API'nin JWT işleyicisinin yapılandırmasını özelleştirmek için örneğini JwtBearerOptions yapılandırın:

builder.Services.AddAuthentication()
    .AddIdentityServerJwt();

builder.Services.Configure<JwtBearerOptions>(
    IdentityServerJwtConstants.IdentityServerJwtBearerScheme,
    options =>
    {
        ...
    });

API'nin JWT işleyicisi, kullanarak JwtBearerEventskimlik doğrulama işlemi üzerinde denetimi etkinleştiren olaylar oluşturur. API yetkilendirme AddIdentityServerJwt desteği sağlamak için kendi olay işleyicilerini kaydeder.

Bir olayın işlenmesini özelleştirmek için mevcut olay işleyicisini gerektiği gibi ek mantıkla sarmalar. Örneğin:

builder.Services.Configure<JwtBearerOptions>(
    IdentityServerJwtConstants.IdentityServerJwtBearerScheme,
    options =>
    {
        var onTokenValidated = options.Events.OnTokenValidated;       

        options.Events.OnTokenValidated = async context =>
        {
            await onTokenValidated(context);
            ...
        }
    });

Yukarıdaki kodda OnTokenValidated , olay işleyicisi özel bir uygulamayla değiştirilir. Bu uygulama:

  1. API yetkilendirme desteği tarafından sağlanan özgün uygulamayı çağırır.
  2. Kendi özel mantığını çalıştırın.

İstemci tarafı yolunu koruma (Angular)

İstemci tarafı yolunun korunması, bir yol yapılandırılırken çalıştırılacak koruma listesine yetkili koruma eklenerek yapılır. Örneğin, ana uygulama Angular modülünde yolun nasıl fetch-data yapılandırıldığını görebilirsiniz:

RouterModule.forRoot([
  // ...
  { path: 'fetch-data', component: FetchDataComponent, canActivate: [AuthorizeGuard] },
])

Bir yolu korumanın gerçek uç noktayı korumadığını (buna hala bir [Authorize] özniteliğin uygulanmasını gerektirdiğini) ancak kullanıcının yalnızca kimliği doğrulanmadığında verilen istemci tarafı yoluna geçmesini engellediğini belirtmek önemlidir.

API isteklerinin kimliğini doğrulama (Angular)

Uygulamayla birlikte barındırılan API'lere yönelik isteklerin kimlik doğrulaması, uygulama tarafından tanımlanan HTTP istemci kesme aracının kullanılmasıyla otomatik olarak gerçekleştirilir.

İstemci tarafı yolunu koruma (React)

İstemci tarafı yolu, düz Route bileşen yerine bileşeni kullanarak AuthorizeRoute koruyun. Örneğin, yolun bileşen içinde nasıl fetch-data yapılandırıldığına App dikkat edin:

<AuthorizeRoute path='/fetch-data' component={FetchData} />

Bir yolu koruma:

  • Gerçek uç noktayı korumaz (yine de buna bir [Authorize] öznitelik uygulanmasını gerektirir).
  • Kullanıcının yalnızca kimliği doğrulanmadığında verilen istemci tarafı yoluna geçmesini engeller.

API isteklerinin kimliğini doğrulama (React)

React ile isteklerin kimlik doğrulaması, önce örneğin içinden AuthorizeServiceiçeri aktarılarak authService gerçekleştirilir. Erişim belirteci' nden authService alınır ve aşağıda gösterildiği gibi isteğe eklenir. React bileşenlerinde bu iş genellikle yaşam döngüsü yönteminde componentDidMount veya bazı kullanıcı etkileşimlerinin sonucu olarak gerçekleştirilir.

authService bileşenini bir bileşene aktarma

import authService from './api-authorization/AuthorizeService'

Erişim belirtecini alma ve yanıta ekleme

async populateWeatherData() {
  const token = await authService.getAccessToken();
  const response = await fetch('api/SampleData/WeatherForecasts', {
    headers: !token ? {} : { 'Authorization': `Bearer ${token}` }
  });
  const data = await response.json();
  this.setState({ forecasts: data, loading: false });
}

Üretime dağıt

Uygulamayı üretim ortamına dağıtmak için aşağıdaki kaynakların sağlanması gerekir:

  • Kullanıcı hesaplarını ve Sunucu tarafından atananları depolamak Identity için bir Identityveritabanı.
  • İmzalama belirteçleri için kullanılacak bir üretim sertifikası.
    • Bu sertifika için belirli bir gereksinim yoktur; otomatik olarak imzalanan bir sertifika veya CA yetkilisi aracılığıyla sağlanan bir sertifika olabilir.
    • PowerShell veya OpenSSL gibi standart araçlar aracılığıyla oluşturulabilir.
    • Hedef makinelerde sertifika deposuna yüklenebilir veya güçlü bir parolayla .pfx dosyası olarak dağıtılabilir.

Örnek: Azure dışı bir web barındırma sağlayıcısına dağıtma

Web barındırma panelinizde sertifikanızı oluşturun veya yükleyin. Ardından uygulamanın appsettings.json dosyasında, bölümü anahtar ayrıntılarını içerecek şekilde değiştirin IdentityServer . Örneğin:

"IdentityServer": {
  "Key": {
    "Type": "Store",
    "StoreName": "WebHosting",
    "StoreLocation": "CurrentUser",
    "Name": "CN=MyApplication"
  }
}

Yukarıdaki örnekte:

  • StoreName , sertifikanın depolandığı sertifika deposunun adını temsil eder. Bu durumda, web barındırma mağazasını işaret eder.
  • StoreLocation , (CurrentUser bu durumda) sertifikanın yüklendiği yeri temsil eder.
  • Name sertifikanın ayırt edici konusuna karşılık gelir.

Örnek: Azure Uygulaması Hizmetine Dağıtma

Bu bölümde, sertifika deposunda depolanan bir sertifika kullanarak uygulamanın Azure Uygulaması Hizmetine dağıtılması açıklanmaktadır. Uygulamayı sertifika deposundan bir sertifika yüklenecek şekilde değiştirmek için, sonraki bir adımda Azure portalında uygulamayı yapılandırırken Standart katman hizmet planı veya daha iyisi gerekir.

Uygulamanın appsettings.json dosyasında, bölümü anahtar ayrıntılarını içerecek şekilde değiştirin IdentityServer :

"IdentityServer": {
  "Key": {
    "Type": "Store",
    "StoreName": "My",
    "StoreLocation": "CurrentUser",
    "Name": "CN=MyApplication"
  }
}
  • Depo adı, sertifikanın depolandığı sertifika deposunun adını temsil eder. Bu durumda, kişisel kullanıcı deposuna işaret eder.
  • Depo konumu, (CurrentUser veya LocalMachine) konumundan sertifikanın yüklendiği yeri temsil eder.
  • Sertifikadaki name özelliği, sertifikanın ayırt edici konusuna karşılık gelir.

Azure Uygulaması Hizmeti'ne dağıtmak için, gerekli Azure kaynaklarının nasıl oluşturulacağını ve uygulamanın üretime nasıl dağıtılacağına ilişkin adımları izleyerek uygulamayı Azure'a dağıtma.

Önceki yönergeleri takip ettikten sonra uygulama Azure'a dağıtılır ancak henüz işlevsel değildir. Uygulama tarafından kullanılan sertifikaNın Azure portalında yapılandırılması gerekir. Sertifikanın parmak izini bulun ve Sertifikalarınızı yükleme bölümünde açıklanan adımları izleyin.

Bu adımlarda SSL'den bahsedilirken, Azure portalında sağlanan sertifikayı uygulamayla birlikte kullanmak üzere karşıya yükleyebileceğiniz bir Özel sertifikalar bölümü vardır.

Azure portalında uygulamayı ve uygulamanın ayarlarını yapılandırdıktan sonra portalda uygulamayı yeniden başlatın.

Diğer yapılandırma seçenekleri

API yetkilendirme desteği, SPA'lara yönelik deneyimi basitleştirmek için bir dizi kural, varsayılan değer ve geliştirme ile Sunucu'nun üzerine Identitykurulur. ASP.NET Core tümleştirmeleri senaryonuzu kapsamazsa, sunucunun tüm gücü Identityarka planda kullanılabilir. ASP.NET Core desteği, tüm uygulamaların kuruluşumuz tarafından oluşturulduğu ve dağıtıldığı "birinci taraf" uygulamalara odaklanmıştır. Bu nedenle, onay veya federasyon gibi şeyler için destek sunulmaz. Bu senaryolar için Server'ı kullanın Identityve belgelerini izleyin.

Uygulama profilleri

Uygulama profilleri, parametrelerini daha fazla tanımlayan uygulamalar için önceden tanımlanmış yapılandırmalardır. Şu anda aşağıdaki profiller desteklenir:

  • IdentityServerSPA: Sunucu ile Identitybirlikte barındırılan spayı tek bir birim olarak temsil eder.
    • redirect_uri varsayılan değeridir/authentication/login-callback.
    • post_logout_redirect_uri varsayılan değeridir/authentication/logout-callback.
    • Kapsam kümesi, profile, ve uygulamadaki API'ler için tanımlanan her kapsamı içeriropenid.
    • İzin verilen OIDC yanıt türleri kümesi veya id_token token bunların her biri tek tek (id_token, token).
    • İzin verilen yanıt modu şeklindedir fragment.
  • SPA: Sunucu ile Identitybarındırılan bir SPA'yı temsil eder.
    • Kapsam kümesi, profile, ve uygulamadaki API'ler için tanımlanan her kapsamı içeriropenid.
    • İzin verilen OIDC yanıt türleri kümesi veya id_token token bunların her biri tek tek (id_token, token).
    • İzin verilen yanıt modu şeklindedir fragment.
  • IdentityServerJwt: Sunucu ile Identitybirlikte barındırılan bir API'yi temsil eder.
    • Uygulama, varsayılan olarak uygulama adı olan tek bir kapsama sahip olacak şekilde yapılandırılır.
  • API: Sunucu ile Identitybarındırılan bir API'yi temsil eder.
    • Uygulama, varsayılan olarak uygulama adı olan tek bir kapsama sahip olacak şekilde yapılandırılır.

Aracılığıyla yapılandırma AppSettings

Veya listesine ClientsResourcesekleyerek yapılandırma sistemi aracılığıyla uygulamaları yapılandırın.

Aşağıdaki örnekte gösterildiği gibi her istemcinin redirect_uri ve post_logout_redirect_uri özelliğini yapılandırın:

"IdentityServer": {
  "Clients": {
    "MySPA": {
      "Profile": "SPA",
      "RedirectUri": "https://www.example.com/authentication/login-callback",
      "LogoutUri": "https://www.example.com/authentication/logout-callback"
    }
  }
}

Kaynakları yapılandırırken, aşağıda gösterildiği gibi kaynağın kapsamlarını yapılandırabilirsiniz:

"IdentityServer": {
  "Resources": {
    "MyExternalApi": {
      "Profile": "API",
      "Scopes": "a b c"
    }
  }
}

Kod aracılığıyla yapılandırma

İstemcileri ve kaynakları, seçenekleri yapılandırmak için eylemde bulunan bir aşırı yüklemesini AddApiAuthorization kullanarak kod aracılığıyla da yapılandırabilirsiniz.

AddApiAuthorization<ApplicationUser, ApplicationDbContext>(options =>
{
    options.Clients.AddSPA(
        "My SPA", spa =>
        spa.WithRedirectUri("http://www.example.com/authentication/login-callback")
           .WithLogoutRedirectUri(
               "http://www.example.com/authentication/logout-callback"));

    options.ApiResources.AddApiResource("MyExternalApi", resource =>
        resource.WithScopes("a", "b", "c"));
});

Ek kaynaklar

ASP.NET Core 3.1 ve üzeri şablonlar, API yetkilendirme desteği kullanılarak Tek Sayfalı Uygulamalarda (SPA) kimlik doğrulaması sunar. Kullanıcıların kimliğini doğrulamak ve depolamak için ASP.NET CoreIdentity, OpenID Bağlan uygulamak için Sunucu ile Identitybirleştirilir.

Angular ve React proje şablonlarına, Web Uygulaması (Model-View-Controller) (MVC) ve Web Uygulaması (RazorSayfalar) proje şablonlarındaki kimlik doğrulama parametresine benzer bir kimlik doğrulama parametresi eklendi. İzin verilen parametre değerleri None ve Individual'dır. React.js ve Redux proje şablonu şu anda kimlik doğrulama parametresini desteklemiyor.

API yetkilendirme desteğiyle uygulama oluşturma

Kullanıcı kimlik doğrulaması ve yetkilendirme hem Angular hem de React SPA'ları ile kullanılabilir. Bir komut kabuğu açın ve aşağıdaki komutu çalıştırın:

Angular:

dotnet new angular -o <output_directory_name> 

Tepki:

dotnet new react -o <output_directory_name> -au Individual

Yukarıdaki komut, SPA içeren bir ClientApp diziniyle bir ASP.NET Core uygulaması oluşturur.

Uygulamanın ASP.NET Core bileşenlerinin genel açıklaması

Aşağıdaki bölümlerde, kimlik doğrulama desteği dahil edildiğinde projeye yapılan eklemeler açıklanmaktadır:

Startup sınıfı

Aşağıdaki kod örnekleri Microsoft.AspNetCore.ApiAuthorization'a dayanır .IdentitySunucu NuGet paketi. Örneklerde ve uzantı yöntemlerini kullanarak AddApiAuthorization API kimlik doğrulaması ve AddIdentityServerJwt yetkilendirmesi yapılandırılır. Kimlik doğrulamasıyla React veya Angular SPA proje şablonlarını kullanan projeler bu pakete bir başvuru içerir.

sınıfı Startup aşağıdaki eklemelere sahiptir:

  • yönteminin Startup.ConfigureServices içinde:

    • Identity varsayılan kullanıcı arabirimiyle:

      services.AddDbContext<ApplicationDbContext>(options =>
          options.UseSqlite(Configuration.GetConnectionString("DefaultConnection")));
      
      services.AddDefaultIdentity<ApplicationUser>()
          .AddEntityFrameworkStores<ApplicationDbContext>();
      
    • IdentitySunucu'nun üzerinde bazı varsayılan ASP.NET Core kurallarını ayarlayan ek AddApiAuthorization bir yardımcı yöntemi olan Identitysunucu:

      services.AddIdentityServer()
          .AddApiAuthorization<ApplicationUser, ApplicationDbContext>();
      
    • Uygulamayı Sunucu tarafından Identityüretilen JWT belirteçlerini doğrulayacak şekilde yapılandıran ek AddIdentityServerJwt bir yardımcı yöntemiyle kimlik doğrulaması:

      services.AddAuthentication()
          .AddIdentityServerJwt();
      
  • yönteminin Startup.Configure içinde:

    • İstek kimlik bilgilerini doğrulamak ve kullanıcıyı istek bağlamında ayarlamakla sorumlu kimlik doğrulama ara yazılımı:

      app.UseAuthentication();
      
    • IdentityOpenID Bağlan uç noktalarını kullanıma sunan Sunucu ara yazılımı:

      app.UseIdentityServer();
      

Linux'ta Azure Uygulaması Hizmeti

Linux'ta Azure Uygulaması Hizmeti dağıtımları için, vereni içinde açıkça Startup.ConfigureServicesbelirtin:

services.Configure<JwtBearerOptions>(
    IdentityServerJwtConstants.IdentityServerJwtBearerScheme, 
    options =>
    {
        options.Authority = "{AUTHORITY}";
    });

Yukarıdaki kodda {AUTHORITY} yer tutucu, OpenID Bağlan çağrıları yapılırken kullanılacak yer tutucudurAuthority.

Örnek:

options.Authority = "https://contoso-service.azurewebsites.net";

AddApiAuthorization

Bu yardımcı yöntem, Sunucu'ya desteklenen yapılandırmamızı kullanacak şekilde yapılandırılır Identity. IdentitySunucu, uygulama güvenliği sorunlarını işlemeye yönelik güçlü ve genişletilebilir bir çerçevedir. Aynı zamanda, en yaygın senaryolar için gereksiz karmaşıklığı ortaya çıkarır. Sonuç olarak, iyi bir başlangıç noktası olarak kabul edilen bir dizi kural ve yapılandırma seçeneği sağlanır. Kimlik doğrulaması gereksinimleriniz değiştikten sonra, kimlik doğrulamasını gereksinimlerinize uyacak şekilde özelleştirmek için Sunucu'nun Identitytüm gücü kullanılabilir duruma gelir.

AddIdentityServerJwt

Bu yardımcı yöntem, uygulama için varsayılan kimlik doğrulama işleyicisi olarak bir ilke şeması yapılandırıyor. İlke, "/Identity" URL alanında herhangi bir alt yola yönlendirilen tüm isteklerin işlenmesine Identity izin verecek Identity şekilde yapılandırılmıştır. diğer JwtBearerHandler tüm istekleri işler. Ayrıca, bu yöntem varsayılan kapsamı <<ApplicationName>>API olan Identitybir <<ApplicationName>>API API kaynağını Sunucu'ya kaydeder ve uygulama için Sunucu tarafından Identityverilen belirteçleri doğrulamak için JWT Taşıyıcı belirteç ara yazılımını yapılandırılır.

WeatherForecastController

dosyasında, kaynağa erişmek için kullanıcının varsayılan ilkeye göre yetkilendirilmiş olması gerektiğini belirten sınıfına uygulanan özniteliğine dikkat edin [Authorize] . Varsayılan yetkilendirme ilkesi, yukarıda bahsedilen ilke düzeni tarafından AddIdentityServerJwt ayarlanan varsayılan kimlik doğrulama düzenini kullanacak şekilde yapılandırılır ve bu da bu tür yardımcı yöntemle yapılandırılanı uygulamaya yönelik istekler için varsayılan işleyici haline getirir JwtBearerHandler .

ApplicationDbContext

Dosyasında, aynı değerin DbContext içinde kullanıldığına Identity dikkat edin; özel durum, sunucu şemasını Identityiçerecek şekilde genişletir ApiAuthorizationDbContext (öğesinden IdentityDbContextdaha türetilmiş bir sınıf).

Veritabanı şemasının tam denetimini elde etmek için, kullanılabilir IdentityDbContext sınıflardan birini devralın ve yöntemini çağırarak builder.ConfigurePersistedGrantContext(_operationalStoreOptions.Value)OnModelCreating bağlamı şemayı Identity içerecek şekilde yapılandırın.

OidcConfigurationController

dosyasında, istemcinin kullanması gereken OIDC parametrelerini sunmak için sağlanan uç noktaya dikkat edin.

appsettings.json

appsettings.json Proje kökü dosyasında, yapılandırılmış istemcilerin listesini açıklayan yeni IdentityServer bir bölüm vardır. Aşağıdaki örnekte tek bir istemci vardır. İstemci adı uygulama adına karşılık gelir ve kural tarafından OAuth ClientId parametresine eşlenir. Profil, yapılandırılan uygulama türünü gösterir. Sunucu için yapılandırma işlemini basitleştiren kuralları yönlendirmek için dahili olarak kullanılır. Uygulama profilleri bölümünde açıklandığı gibi, kullanılabilir birkaç profil vardır.

"IdentityServer": {
  "Clients": {
    "angularindividualpreview3final": {
      "Profile": "IdentityServerSPA"
    }
  }
}

appsettings.Development.json

appsettings.Development.json Proje kökü dosyasında belirteçleri imzalamak için kullanılan anahtarı açıklayan bir IdentityServer bölüm vardır. Üretime dağıtılırken, Üretime dağıt bölümünde açıklandığı gibi bir anahtarın uygulamayla birlikte sağlanması ve dağıtılması gerekir.

"IdentityServer": {
  "Key": {
    "Type": "Development"
  }
}

Angular uygulamasının genel açıklaması

Angular şablonundaki kimlik doğrulaması ve API yetkilendirme desteği, ClientApp/src/api-authorization dizinindeki kendi Angular modülünde bulunur. Modül aşağıdaki öğelerden oluşur:

  • 3 bileşen:
    • login.component.ts: Uygulamanın oturum açma akışını işler.
    • logout.component.ts: Uygulamanın oturum kapatma akışını işler.
    • login-menu.component.ts: Aşağıdaki bağlantı kümelerinden birini görüntüleyen pencere öğesi:
      • Kullanıcı kimliği doğrulandığında kullanıcı profili yönetimi ve oturumu kapatma bağlantıları.
      • Kullanıcının kimliği doğrulanmamışsa kayıt ve oturum açma bağlantıları.
  • Yollara eklenebilen ve bir kullanıcının yolu ziyaret etmeden önce kimliğinin doğrulanması gereken bir yol koruyucusu AuthorizeGuard .
  • Kullanıcının kimliği doğrulandığında API'yi hedefleyen giden HTTP isteklerine erişim belirtecini ekleyen bir HTTP kesme noktası AuthorizeInterceptor .
  • Kimlik doğrulama işleminin alt düzey ayrıntılarını işleyen ve kimliği doğrulanmış kullanıcı hakkındaki bilgileri uygulamanın geri kalanında kullanıma sunan bir hizmet AuthorizeService .
  • Uygulamanın kimlik doğrulama bölümleriyle ilişkili yolları tanımlayan bir Angular modülü. Oturum açma menüsü bileşenini, kesme noktasını, korumayı ve hizmeti uygulamanın geri kalanından tüketim için kullanıma sunar.

React uygulamasının genel açıklaması

React şablonundaki kimlik doğrulaması ve API yetkilendirme desteği ClientApp/src/components/api-authorization dizininde bulunur. Aşağıdaki öğelerden oluşur:

  • 4 bileşen:
    • Login.js: Uygulamanın oturum açma akışını işler.
    • Logout.js: Uygulamanın oturum kapatma akışını işler.
    • LoginMenu.js: Aşağıdaki bağlantı kümelerinden birini görüntüleyen pencere öğesi:
      • Kullanıcı kimliği doğrulandığında kullanıcı profili yönetimi ve oturumu kapatma bağlantıları.
      • Kullanıcının kimliği doğrulanmamışsa kayıt ve oturum açma bağlantıları.
    • AuthorizeRoute.js: Parametresinde Component belirtilen bileşeni işlemeden önce kullanıcının kimliğinin doğrulanması gereken bir yol bileşeni.
  • Kimlik doğrulama işleminin alt düzey ayrıntılarını işleyen ve kimliği doğrulanmış kullanıcı hakkındaki bilgileri tüketim için uygulamanın geri kalanında kullanıma sunan dışarı aktarılan authService sınıf AuthorizeService örneği.

Çözümün ana bileşenlerini gördüğünüze göre, uygulama senaryolarına daha ayrıntılı bir şekilde göz atabilirsiniz.

Yeni BIR API'de yetkilendirme iste

Varsayılan olarak, sistem yeni API'ler için kolayca yetkilendirme gerektirecek şekilde yapılandırılır. Bunu yapmak için yeni bir denetleyici oluşturun ve özniteliğini denetleyici sınıfına veya denetleyici içindeki herhangi bir eyleme ekleyin [Authorize] .

API kimlik doğrulama işleyicisini özelleştirme

API'nin JWT işleyicisinin yapılandırmasını özelleştirmek için örneğini JwtBearerOptions yapılandırın:

services.AddAuthentication()
    .AddIdentityServerJwt();

services.Configure<JwtBearerOptions>(
    IdentityServerJwtConstants.IdentityServerJwtBearerScheme,
    options =>
    {
        ...
    });

API'nin JWT işleyicisi, kullanarak JwtBearerEventskimlik doğrulama işlemi üzerinde denetimi etkinleştiren olaylar oluşturur. API yetkilendirme AddIdentityServerJwt desteği sağlamak için kendi olay işleyicilerini kaydeder.

Bir olayın işlenmesini özelleştirmek için mevcut olay işleyicisini gerektiği gibi ek mantıkla sarmalar. Örneğin:

services.Configure<JwtBearerOptions>(
    IdentityServerJwtConstants.IdentityServerJwtBearerScheme,
    options =>
    {
        var onTokenValidated = options.Events.OnTokenValidated;       

        options.Events.OnTokenValidated = async context =>
        {
            await onTokenValidated(context);
            ...
        }
    });

Yukarıdaki kodda OnTokenValidated , olay işleyicisi özel bir uygulamayla değiştirilir. Bu uygulama:

  1. API yetkilendirme desteği tarafından sağlanan özgün uygulamayı çağırır.
  2. Kendi özel mantığını çalıştırın.

İstemci tarafı yolunu koruma (Angular)

İstemci tarafı yolunun korunması, bir yol yapılandırılırken çalıştırılacak koruma listesine yetkili koruma eklenerek yapılır. Örneğin, ana uygulama Angular modülünde yolun nasıl fetch-data yapılandırıldığını görebilirsiniz:

RouterModule.forRoot([
  // ...
  { path: 'fetch-data', component: FetchDataComponent, canActivate: [AuthorizeGuard] },
])

Bir yolu korumanın gerçek uç noktayı korumadığını (buna hala bir [Authorize] özniteliğin uygulanmasını gerektirdiğini) ancak kullanıcının yalnızca kimliği doğrulanmadığında verilen istemci tarafı yoluna geçmesini engellediğini belirtmek önemlidir.

API isteklerinin kimliğini doğrulama (Angular)

Uygulamayla birlikte barındırılan API'lere yönelik isteklerin kimlik doğrulaması, uygulama tarafından tanımlanan HTTP istemci kesme aracının kullanılmasıyla otomatik olarak gerçekleştirilir.

İstemci tarafı yolunu koruma (React)

İstemci tarafı yolu, düz Route bileşen yerine bileşeni kullanarak AuthorizeRoute koruyun. Örneğin, yolun bileşen içinde nasıl fetch-data yapılandırıldığına App dikkat edin:

<AuthorizeRoute path='/fetch-data' component={FetchData} />

Bir yolu koruma:

  • Gerçek uç noktayı korumaz (yine de buna bir [Authorize] öznitelik uygulanmasını gerektirir).
  • Kullanıcının yalnızca kimliği doğrulanmadığında verilen istemci tarafı yoluna geçmesini engeller.

API isteklerinin kimliğini doğrulama (React)

React ile isteklerin kimlik doğrulaması, önce örneğin içinden AuthorizeServiceiçeri aktarılarak authService gerçekleştirilir. Erişim belirteci' nden authService alınır ve aşağıda gösterildiği gibi isteğe eklenir. React bileşenlerinde bu iş genellikle yaşam döngüsü yönteminde componentDidMount veya bazı kullanıcı etkileşimlerinin sonucu olarak gerçekleştirilir.

authService bileşenini bir bileşene aktarma

import authService from './api-authorization/AuthorizeService'

Erişim belirtecini alma ve yanıta ekleme

async populateWeatherData() {
  const token = await authService.getAccessToken();
  const response = await fetch('api/SampleData/WeatherForecasts', {
    headers: !token ? {} : { 'Authorization': `Bearer ${token}` }
  });
  const data = await response.json();
  this.setState({ forecasts: data, loading: false });
}

Üretime dağıt

Uygulamayı üretim ortamına dağıtmak için aşağıdaki kaynakların sağlanması gerekir:

  • Kullanıcı hesaplarını ve Sunucu tarafından atananları depolamak Identity için bir Identityveritabanı.
  • İmzalama belirteçleri için kullanılacak bir üretim sertifikası.
    • Bu sertifika için belirli bir gereksinim yoktur; otomatik olarak imzalanan bir sertifika veya CA yetkilisi aracılığıyla sağlanan bir sertifika olabilir.
    • PowerShell veya OpenSSL gibi standart araçlar aracılığıyla oluşturulabilir.
    • Hedef makinelerde sertifika deposuna yüklenebilir veya güçlü bir parolayla .pfx dosyası olarak dağıtılabilir.

Örnek: Azure dışı bir web barındırma sağlayıcısına dağıtma

Web barındırma panelinizde sertifikanızı oluşturun veya yükleyin. Ardından uygulamanın appsettings.json dosyasında, bölümü anahtar ayrıntılarını içerecek şekilde değiştirin IdentityServer . Örneğin:

"IdentityServer": {
  "Key": {
    "Type": "Store",
    "StoreName": "WebHosting",
    "StoreLocation": "CurrentUser",
    "Name": "CN=MyApplication"
  }
}

Yukarıdaki örnekte:

  • StoreName , sertifikanın depolandığı sertifika deposunun adını temsil eder. Bu durumda, web barındırma mağazasını işaret eder.
  • StoreLocation , (CurrentUser bu durumda) sertifikanın yüklendiği yeri temsil eder.
  • Name sertifikanın ayırt edici konusuna karşılık gelir.

Örnek: Azure Uygulaması Hizmetine Dağıtma

Bu bölümde, sertifika deposunda depolanan bir sertifika kullanarak uygulamanın Azure Uygulaması Hizmetine dağıtılması açıklanmaktadır. Uygulamayı sertifika deposundan bir sertifika yüklenecek şekilde değiştirmek için, sonraki bir adımda Azure portalında uygulamayı yapılandırırken Standart katman hizmet planı veya daha iyisi gerekir.

Uygulamanın appsettings.json dosyasında, bölümü anahtar ayrıntılarını içerecek şekilde değiştirin IdentityServer :

"IdentityServer": {
  "Key": {
    "Type": "Store",
    "StoreName": "My",
    "StoreLocation": "CurrentUser",
    "Name": "CN=MyApplication"
  }
}
  • Depo adı, sertifikanın depolandığı sertifika deposunun adını temsil eder. Bu durumda, kişisel kullanıcı deposuna işaret eder.
  • Depo konumu, (CurrentUser veya LocalMachine) konumundan sertifikanın yüklendiği yeri temsil eder.
  • Sertifikadaki name özelliği, sertifikanın ayırt edici konusuna karşılık gelir.

Azure Uygulaması Hizmeti'ne dağıtmak için, gerekli Azure kaynaklarının nasıl oluşturulacağını ve uygulamanın üretime nasıl dağıtılacağına ilişkin adımları izleyerek uygulamayı Azure'a dağıtma.

Önceki yönergeleri takip ettikten sonra uygulama Azure'a dağıtılır ancak henüz işlevsel değildir. Uygulama tarafından kullanılan sertifikaNın Azure portalında yapılandırılması gerekir. Sertifikanın parmak izini bulun ve Sertifikalarınızı yükleme bölümünde açıklanan adımları izleyin.

Bu adımlarda SSL'den bahsedilirken, Azure portalında sağlanan sertifikayı uygulamayla birlikte kullanmak üzere karşıya yükleyebileceğiniz bir Özel sertifikalar bölümü vardır.

Azure portalında uygulamayı ve uygulamanın ayarlarını yapılandırdıktan sonra portalda uygulamayı yeniden başlatın.

Diğer yapılandırma seçenekleri

API yetkilendirme desteği, SPA'lara yönelik deneyimi basitleştirmek için bir dizi kural, varsayılan değer ve geliştirme ile Sunucu'nun üzerine Identitykurulur. ASP.NET Core tümleştirmeleri senaryonuzu kapsamazsa, sunucunun tüm gücü Identityarka planda kullanılabilir. ASP.NET Core desteği, tüm uygulamaların kuruluşumuz tarafından oluşturulduğu ve dağıtıldığı "birinci taraf" uygulamalara odaklanmıştır. Bu nedenle, onay veya federasyon gibi şeyler için destek sunulmaz. Bu senaryolar için Server'ı kullanın Identityve belgelerini izleyin.

Uygulama profilleri

Uygulama profilleri, parametrelerini daha fazla tanımlayan uygulamalar için önceden tanımlanmış yapılandırmalardır. Şu anda aşağıdaki profiller desteklenir:

  • IdentityServerSPA: Sunucu ile Identitybirlikte barındırılan spayı tek bir birim olarak temsil eder.
    • redirect_uri varsayılan değeridir/authentication/login-callback.
    • post_logout_redirect_uri varsayılan değeridir/authentication/logout-callback.
    • Kapsam kümesi, profile, ve uygulamadaki API'ler için tanımlanan her kapsamı içeriropenid.
    • İzin verilen OIDC yanıt türleri kümesi veya id_token token bunların her biri tek tek (id_token, token).
    • İzin verilen yanıt modu şeklindedir fragment.
  • SPA: Sunucu ile Identitybarındırılan bir SPA'yı temsil eder.
    • Kapsam kümesi, profile, ve uygulamadaki API'ler için tanımlanan her kapsamı içeriropenid.
    • İzin verilen OIDC yanıt türleri kümesi veya id_token token bunların her biri tek tek (id_token, token).
    • İzin verilen yanıt modu şeklindedir fragment.
  • IdentityServerJwt: Sunucu ile Identitybirlikte barındırılan bir API'yi temsil eder.
    • Uygulama, varsayılan olarak uygulama adı olan tek bir kapsama sahip olacak şekilde yapılandırılır.
  • API: Sunucu ile Identitybarındırılan bir API'yi temsil eder.
    • Uygulama, varsayılan olarak uygulama adı olan tek bir kapsama sahip olacak şekilde yapılandırılır.

Aracılığıyla yapılandırma AppSettings

Veya listesine ClientsResourcesekleyerek yapılandırma sistemi aracılığıyla uygulamaları yapılandırın.

Aşağıdaki örnekte gösterildiği gibi her istemcinin redirect_uri ve post_logout_redirect_uri özelliğini yapılandırın:

"IdentityServer": {
  "Clients": {
    "MySPA": {
      "Profile": "SPA",
      "RedirectUri": "https://www.example.com/authentication/login-callback",
      "LogoutUri": "https://www.example.com/authentication/logout-callback"
    }
  }
}

Kaynakları yapılandırırken, aşağıda gösterildiği gibi kaynağın kapsamlarını yapılandırabilirsiniz:

"IdentityServer": {
  "Resources": {
    "MyExternalApi": {
      "Profile": "API",
      "Scopes": "a b c"
    }
  }
}

Kod aracılığıyla yapılandırma

İstemcileri ve kaynakları, seçenekleri yapılandırmak için eylemde bulunan bir aşırı yüklemesini AddApiAuthorization kullanarak kod aracılığıyla da yapılandırabilirsiniz.

AddApiAuthorization<ApplicationUser, ApplicationDbContext>(options =>
{
    options.Clients.AddSPA(
        "My SPA", spa =>
        spa.WithRedirectUri("http://www.example.com/authentication/login-callback")
           .WithLogoutRedirectUri(
               "http://www.example.com/authentication/logout-callback"));

    options.ApiResources.AddApiResource("MyExternalApi", resource =>
        resource.WithScopes("a", "b", "c"));
});

Ek kaynaklar