Sunucu ile Identity barındırılan ASP.NET Core uygulamasının Blazor WebAssembly güvenliğini sağlama

Bu makalede, kullanıcıların ve API çağrılarının kimliğini doğrulamak için Duende Server kullanan barındırılan IdentityBlazor WebAssembly bir çözümün nasıl oluşturulacağı açıklanmaktadır.

Ö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ş.

Not

Tek başına veya barındırılan Blazor WebAssembly bir uygulamayı mevcut bir dış Identity Sunucu örneğini kullanacak şekilde yapılandırmak için Kimlik Doğrulama kitaplığıyla ASP.NET Core Blazor WebAssembly tek başına uygulamasının güvenliğini sağlama başlığındaki yönergeleri izleyin.

Bu makaleyi okuduktan sonra ek güvenlik senaryosu kapsamı için bkz . ASP.NET Çekirdek Blazor WebAssembly ek güvenlik senaryoları.

İzlenecek yol

İzlenecek kılavuzun alt bölümlerinde aşağıdakilerin nasıl yapılacağı açıklanmaktadır:

  • Blazor Uygulamayı oluşturma
  • Uygulamayı çalıştırma

Blazor Uygulama oluşturma

Kimlik doğrulama mekanizmasıyla yeni Blazor WebAssembly bir proje oluşturmak için:

  1. Yeni bir proje oluşturma.

  2. Blazor WebAssembly Uygulama şablonunu seçin. İleri'yi seçin.

  3. Tire kullanmadan bir Proje adı sağlayın. Konum'un doğru olduğunu onaylayın. İleri'yi seçin.

    Proje adında OIDC uygulama tanımlayıcısının oluşumunu bozan tireler (-) kullanmaktan kaçının. Proje şablonundaki mantık, çözümün Blazor WebAssembly yapılandırmasında bir OIDC uygulama tanımlayıcısı için proje adını kullanır ve OIDC uygulama tanımlayıcısında tirelere izin verilmez. Pascal büyük/küçük harf (BlazorSample) veya alt çizgi (Blazor_Sample) kabul edilebilir alternatiflerdir.

  4. Ek bilgiler iletişim kutusunda, ASP.NET Core'un sistemini kullanarak kullanıcıları uygulamada depolamak için Kimlik Doğrulama türü olarak Bireysel Hesaplar'ıIdentity seçin.

  5. ASP.NET Temel Barındırılan onay kutusunu seçin.

  6. Uygulamayı oluşturmak için Oluştur düğmesini seçin.

Uygulamayı çalıştırma

Uygulamayı projeden Server çalıştırın. Visual Studio kullanırken, aşağıdakilerden birini yapabilirsiniz:

  • Çalıştır düğmesinin yanındaki açılan oku seçin. Açılan listeden Başlangıç Projelerini Yapılandır'ı açın. Tek başlangıç projesi seçeneğini belirleyin. Başlangıç projesinin projesini onaylayın veya proje olarak Server değiştirin.

  • Server Aşağıdaki yaklaşımlardan herhangi biriyle uygulamayı başlatmadan önce projenin Çözüm Gezgini vurgulandığını onaylayın:

    • Çalıştır düğmesini seçin.
    • Menüden Hata AyıklamaYı>Başlat Hata Ayıklamayı Kullanın.
    • F5 tuşuna basın.
  • Komut kabuğunda çözümün Server proje klasörüne gidin. dotnet run komutunu yürütün.

Çözümün parçaları

Bu bölümde, bir çözümün proje şablonundan Blazor WebAssembly oluşturulan bölümleri açıklanır ve çözümün Client ve Server projelerin başvuru için nasıl yapılandırıldığı açıklanır. Uygulamayı İzlenecek Yol bölümündeki yönergeleri kullanarak oluşturduysanız temel bir çalışma uygulaması için bu bölümde izlenecek belirli bir kılavuz yoktur. Bu bölümdeki yönergeler, kullanıcıların kimliğini doğrulamak ve yetkilendirmek için bir uygulamayı güncelleştirmeye yardımcı olur. Ancak, bir uygulamayı güncelleştirmeye alternatif bir yaklaşım, İzlenecek Yol bölümündeki kılavuzdan yeni bir uygulama oluşturmak ve uygulamanın bileşenlerini, sınıflarını ve kaynaklarını yeni uygulamaya taşımaktır.

Server uygulama hizmetleri

Bu bölüm çözümün uygulamasıyla ilgili.Server

Aşağıdaki hizmetler kaydedilir.

  • Program dosyasında:

    • Entity Framework Core ve ASP.NET Core Identity:

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

      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();
      
  • Startup.csiçindeStartup.ConfigureServices:

    • Entity Framework Core ve ASP.NET Core Identity:

      services.AddDbContext<ApplicationDbContext>(options =>
          options.UseSqlite(
              Configuration.GetConnectionString("DefaultConnection")));
      
      services.AddDefaultIdentity<ApplicationUser>(options => 
              options.SignIn.RequireConfirmedAccount = true)
          .AddEntityFrameworkStores<ApplicationDbContext>();
      
    • Identity Sunucu'nun üstünde varsayılan ASP.NET Core kurallarını ayarlayan ek AddApiAuthorization bir yardımcı yöntemi olan Identity sunucu:

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

Not

Tek bir kimlik doğrulama düzeni kaydedildiğinde, kimlik doğrulama düzeni otomatik olarak uygulamanın varsayılan şeması olarak kullanılır ve düzenin veya AddAuthentication aracılığıyla AuthenticationOptionsbelirtilmesi gerekmez. Daha fazla bilgi için bkz . ASP.NET Çekirdek Kimlik DoğrulamasınaGenel Bakış ve ASP.NET Core duyurusu (aspnet/Announcements #490).

  • Program dosyasında:
  • Startup.csiçindeStartup.Configure:
  • Sunucu Ara Yazılımı OpenID Identity Bağlan (OIDC) uç noktalarını kullanıma sunar:

    app.UseIdentityServer();
    
  • Kimlik Doğrulama Ara Yazılımı, istek kimlik bilgilerini doğrulamak ve kullanıcıyı istek bağlamında ayarlamakla sorumludur:

    app.UseAuthentication();
    
  • Yetkilendirme Ara Yazılımı yetkilendirme özelliklerini etkinleştirir:

    app.UseAuthorization();
    

API yetkilendirmesi

Bu bölüm çözümün uygulamasıyla ilgili.Server

yardımcı yöntemi, AddApiAuthorization ASP.NET Core senaryoları için Sunucu'ya yapılandırılırIdentity. Identity Sunucu, uygulama güvenliği sorunlarını işlemeye yönelik güçlü ve genişletilebilir bir çerçevedir. Identity Sunucu, en yaygın senaryolar için gereksiz karmaşıklığı ortaya çıkarır. Sonuç olarak, iyi bir başlangıç noktası olarak değerlendirdiğimiz 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ı Identity uygulamanın gereksinimlerine uyacak şekilde özelleştirmek için Sunucu'nun tüm gücü kullanılabilir.

Sunucu ile Identity birlikte bulunan bir API için kimlik doğrulama işleyicisi ekleme

Bu bölüm çözümün uygulamasıyla ilgili.Server

Yardımcı yöntemi, AddIdentityServerJwt uygulama için varsayılan kimlik doğrulama işleyicisi olarak bir ilke şeması yapılandırıyor. İlke, altındaki /IdentityURL alanında herhangi bir alt yola Identity yönlendirilen tüm istekleri işlemeye izin verecek Identity şekilde yapılandırılmıştır. diğer JwtBearerHandler tüm istekleri işler. Ayrıca, bu yöntem:

  • Bir API kaynağını Identity varsayılan kapsamı {PROJECT NAME}APIolan Sunucu'ya kaydeder; burada {PROJECT NAME} yer tutucu, uygulama oluşturma sırasında projenin adıdır.
  • Uygulama için Sunucu tarafından Identity verilen belirteçleri doğrulamak için JWT Taşıyıcı Belirteci Ara Yazılımını yapılandırılır.

Hava durumu tahmin denetleyicisi

Bu bölüm çözümün uygulamasıyla ilgili.Server

WeatherForecastController içindeControllers/WeatherForecastController.cs özniteliği [Authorize] sınıfına uygulanır. özniteliği, kullanıcının kaynağa erişmek için varsayılan ilkeye göre yetkilendirilmiş olması gerektiğini gösterir. Varsayılan yetkilendirme ilkesi, tarafından AddIdentityServerJwtayarlanan varsayılan kimlik doğrulama düzenini kullanacak şekilde yapılandırılır. Yardımcı yöntemi, uygulamaya yönelik istekler JwtBearerHandler için varsayılan işleyici olarak yapılandırılır.

Uygulama veritabanı bağlamı

Bu bölüm çözümün uygulamasıyla ilgili.Server

ApplicationDbContext içinde ,Data/ApplicationDbContext.csDbContext Sunucu şemasını Identity içerecek şekilde genişletirApiAuthorizationDbContext<TUser>. ApiAuthorizationDbContext<TUser> , 'den IdentityDbContexttüretilir.

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.

OIDC yapılandırma denetleyicisi

Bu bölüm çözümün uygulamasıyla ilgili.Server

OidcConfigurationController içinde,Controllers/OidcConfigurationController.cs istemci uç noktası OIDC parametrelerine hizmet vermek için sağlanır.

Uygulama ayarları

Bu bölüm çözümün uygulamasıyla ilgili.Server

Proje kökündeki uygulama ayarları dosyasında (appsettings.json) bölümünde yapılandırılan IdentityServer istemcilerin listesi açıklanmaktadır. Aşağıdaki örnekte tek bir istemci vardır. İstemci adı uygulamanın derleme adına karşılık gelir Client ve kural tarafından OAuth ClientId parametresine eşlenir. Profil, yapılandırılan uygulama türünü gösterir. Profil, sunucu için yapılandırma işlemini basitleştiren kuralları yönlendirmek için dahili olarak kullanılır.

"IdentityServer": {
  "Clients": {
    "{ASSEMBLY NAME}": {
      "Profile": "IdentityServerSPA"
    }
  }
}

Yer tutucu {ASSEMBLY NAME} , uygulamanın derleme adıdır Client (örneğin, BlazorSample.Client).

Kimlik doğrulama paketi

Bu bölüm çözümün uygulamasıyla ilgili.Client

Tek Tek Kullanıcı HesaplarınıIndividual () kullanmak üzere bir uygulama oluşturulduğunda, uygulama otomatik olarak paket için Microsoft.AspNetCore.Components.WebAssembly.Authentication bir paket başvurusu alır. Paket, uygulamanın kullanıcıların kimliğini doğrulamasına ve korumalı API'leri çağırmak için belirteçleri almasına yardımcı olan bir dizi temel öğe sağlar.

Uygulamaya kimlik doğrulaması ekliyorsanız paketi uygulamaya el ile ekleyin Microsoft.AspNetCore.Components.WebAssembly.Authentication .

Not

.NET uygulamalarına paket ekleme hakkında yönergeler için, Paket tüketimi iş akışında (NuGet belgeleri)paketleri yüklemek ve yönetmek altındaki makalelere bakın. NuGet.org'da doğru paket sürümlerini onaylayın.

HttpClient yapılandırması

Bu bölüm çözümün uygulamasıyla ilgili.Client

DosyadaProgram, sunucu API'sine istekte bulunurken erişim belirteçleri içeren örnekleri sağlamak HttpClient için adlandırılmış bir yapılandırılırHttpClient. Çözüm oluşturma sırasında varsayılan olarak, yer tutucunun projenin adı olduğu {PROJECT NAME} adlandırılmış HttpClient{PROJECT NAME}.ServerAPIdeğeridir.

builder.Services.AddHttpClient("{PROJECT NAME}.ServerAPI", 
        client => client.BaseAddress = new Uri(builder.HostEnvironment.BaseAddress))
    .AddHttpMessageHandler<BaseAddressAuthorizationMessageHandler>();

builder.Services.AddScoped(sp => sp.GetRequiredService<IHttpClientFactory>()
    .CreateClient("{PROJECT NAME}.ServerAPI"));

Yer tutucu {PROJECT NAME} , çözüm oluşturma sırasındaki proje adıdır. Örneğin, proje adını BlazorSample sağlamak adlı HttpClientBlazorSample.ServerAPIbir oluşturur.

Not

Bir uygulamayı barındırılan Blazor çözümün parçası olmayan mevcut Identity bir Sunucu örneğini kullanacak şekilde yapılandırıyorsanız, temel adres kaydını IWebAssemblyHostEnvironment.BaseAddress (builder.HostEnvironment.BaseAddress) yerine sunucu uygulamasının API yetkilendirme uç noktası URL'si olarak değiştirinHttpClient.Blazor WebAssembly

API yetkilendirme desteği

Bu bölüm çözümün uygulamasıyla ilgili.Client

Kullanıcıların kimliğini doğrulama desteği, paketin içinde sağlanan uzantı yöntemi tarafından hizmet kapsayıcısına Microsoft.AspNetCore.Components.WebAssembly.Authentication eklenir. Bu yöntem, mevcut yetkilendirme sistemiyle etkileşim kurmak için uygulamanın gerektirdiği hizmetleri ayarlar.

builder.Services.AddApiAuthorization();

Varsayılan olarak, uygulamanın yapılandırması kuralına göre yüklenir _configuration/{client-id}. Kural gereği, istemci kimliği uygulamanın derleme adına ayarlanır. Bu URL, seçeneklerle aşırı yükleme çağrılarak ayrı bir uç noktaya işaret etmek üzere değiştirilebilir.

Imports dosyası

Bu bölüm çözümün uygulamasıyla ilgili.Client

Ad Microsoft.AspNetCore.Components.Authorization alanı, uygulama genelinde şu dosya aracılığıyla _Imports.razor kullanılabilir hale getirilir:

@using System.Net.Http
@using System.Net.Http.Json
@using Microsoft.AspNetCore.Components.Authorization
@using Microsoft.AspNetCore.Components.Forms
@using Microsoft.AspNetCore.Components.Routing
@using Microsoft.AspNetCore.Components.Web
@using Microsoft.AspNetCore.Components.Web.Virtualization
@using Microsoft.AspNetCore.Components.WebAssembly.Http
@using Microsoft.JSInterop
@using {APPLICATION ASSEMBLY}
@using {APPLICATION ASSEMBLY}.Shared

Index Sayfası

Bu bölüm çözümün uygulamasıyla ilgili.Client

Dizin sayfası (wwwroot/index.html) sayfası, JavaScript'te öğesini AuthenticationService tanımlayan bir betik içerir. AuthenticationService OIDC protokolünün alt düzey ayrıntılarını işler. Uygulama, kimlik doğrulama işlemlerini gerçekleştirmek için betikte tanımlanan yöntemleri dahili olarak çağırır.

<script src="_content/Microsoft.AspNetCore.Components.WebAssembly.Authentication/AuthenticationService.js"></script>

App bileşeni

Bu bölüm çözümün uygulamasıyla ilgili.Client

Bileşen App (App.razor), uygulamalarda bulunan Blazor Server bileşene App benzer:

  • Bileşen, CascadingAuthenticationState öğesini uygulamanın geri kalanına ifşa etme işlemini yönetir AuthenticationState .
  • Bileşen, AuthorizeRouteView geçerli kullanıcının belirli bir sayfaya erişme yetkisine sahip olduğundan veya bileşeni başka bir şekilde işlendiğinden RedirectToLogin emin olur.
  • Bileşen, RedirectToLogin yetkisiz kullanıcıları oturum açma sayfasına yönlendirmeyi yönetir.

ASP.NET Core sürümleri arasında çerçevedeki değişiklikler nedeniyle, Razor bileşen (App.razor) için App işaretleme bu bölümde gösterilmez. Belirli bir sürüm için bileşenin işaretlemesini incelemek için aşağıdaki yaklaşımlardan birini kullanın:

  • Kullanmak istediğiniz ASP.NET Core sürümü için varsayılan Blazor WebAssembly proje şablonundan kimlik doğrulaması için sağlanan bir uygulama oluşturun. App Oluşturulan uygulamadaki bileşeni (App.razor) inceleyin.

  • Başvuru kaynağındaki Appbileşeni (App.razor) inceleyin. Dal seçiciden sürümü seçin ve yıllar içinde taşındığından deponun klasöründe bileşeni ProjectTemplates arayın.

    Not

    .NET başvuru kaynağına yönelik belge bağlantıları genellikle deponun varsayılan dalını yükler ve bu dal .NET'in sonraki sürümü için geçerli geliştirmeyi temsil eder. Belirli bir sürümün etiketini seçmek için Dalları veya etiketleri değiştir açılan listesini kullanın. Daha fazla bilgi için bkz. ASP.NET Core kaynak kodunun sürüm etiketini seçme (dotnet/AspNetCore.Docs #26205).

RedirectToLogin bileşeni

Bu bölüm çözümün uygulamasıyla ilgili.Client

Bileşen RedirectToLogin (RedirectToLogin.razor):

  • Yetkisiz kullanıcıları oturum açma sayfasına yönlendirmeyi yönetir.
  • Kullanıcının erişmeye çalıştığı geçerli URL tarafından korunur, böylece kimlik doğrulaması başarılı olursa bu sayfaya döndürülebilir:

Başvuru kaynağındaki RedirectToLoginbileşeni inceleyin. Bileşenin konumu zaman içinde değiştiğinden, bileşeni bulmak için GitHub arama araçlarını kullanın.

Not

.NET başvuru kaynağına yönelik belge bağlantıları genellikle deponun varsayılan dalını yükler ve bu dal .NET'in sonraki sürümü için geçerli geliştirmeyi temsil eder. Belirli bir sürümün etiketini seçmek için Dalları veya etiketleri değiştir açılan listesini kullanın. Daha fazla bilgi için bkz. ASP.NET Core kaynak kodunun sürüm etiketini seçme (dotnet/AspNetCore.Docs #26205).

LoginDisplay bileşeni

Bu bölüm çözümün uygulamasıyla ilgili.Client

Bileşen LoginDisplay (LoginDisplay.razor) bileşeninde MainLayout işlenir (MainLayout.razor) ve aşağıdaki davranışları yönetir:

  • Kimliği doğrulanmış kullanıcılar için:
    • Geçerli kullanıcı adını görüntüler.
    • ASP.NET Core'da Identitykullanıcı profili sayfasına bir bağlantı sunar.
    • Uygulamanın oturumunu kapatmaya ilişkin bir düğme sunar.
  • Anonim kullanıcılar için:
    • Kaydolma seçeneği sunar.
    • Oturum açma seçeneği sunar.

ASP.NET Core sürümleri arasında çerçevedeki değişiklikler nedeniyle, Razor bileşen için LoginDisplay işaretleme bu bölümde gösterilmez. Belirli bir sürüm için bileşenin işaretlemesini incelemek için aşağıdaki yaklaşımlardan birini kullanın:

  • Kullanmak istediğiniz ASP.NET Core sürümü için varsayılan Blazor WebAssembly proje şablonundan kimlik doğrulaması için sağlanan bir uygulama oluşturun. LoginDisplay Oluşturulan uygulamadaki bileşeni inceleyin.

  • Başvuru kaynağındaki LoginDisplaybileşeni inceleyin. Bileşenin konumu zaman içinde değiştiğinden, bileşeni bulmak için GitHub arama araçlarını kullanın. eşittir true için Hosted şablonlu içerik kullanılır.

    Not

    .NET başvuru kaynağına yönelik belge bağlantıları genellikle deponun varsayılan dalını yükler ve bu dal .NET'in sonraki sürümü için geçerli geliştirmeyi temsil eder. Belirli bir sürümün etiketini seçmek için Dalları veya etiketleri değiştir açılan listesini kullanın. Daha fazla bilgi için bkz. ASP.NET Core kaynak kodunun sürüm etiketini seçme (dotnet/AspNetCore.Docs #26205).

Authentication bileşeni

Bu bölüm çözümün uygulamasıyla ilgili.Client

Bileşen (Pages/Authentication.razor) tarafından Authentication oluşturulan sayfa, farklı kimlik doğrulama aşamalarını işlemek için gereken yolları tanımlar.

Bileşen RemoteAuthenticatorView :

@page "/authentication/{action}"
@using Microsoft.AspNetCore.Components.WebAssembly.Authentication

<RemoteAuthenticatorView Action="Action" />

@code {
    [Parameter]
    public string? Action { get; set; }
}

Not

Null atanabilir başvuru türleri (NTS) ve .NET derleyici null durum statik çözümlemesi .NET 6 veya sonraki sürümlerde ASP.NET Core'da desteklenir. .NET 6'da ASP.NET Core'un yayımlanmasından önce, string tür null tür ataması (?) olmadan görünür.

FetchData bileşeni

Bu bölüm çözümün uygulamasıyla ilgili.Client

Bileşen şunların FetchData nasıl yapılacağını gösterir:

  • Erişim belirteci sağlama.
  • Sunucu uygulamasında korumalı bir kaynak API'sini çağırmak için erişim belirtecini kullanın.

yönergesi @attribute [Authorize] , yetkilendirme sistemine bu bileşeni ziyaret etmek için kullanıcının yetkilendirilmiş olması gerektiğini belirtir Blazor WebAssembly . Özniteliğin Client uygulamada bulunması, sunucudaki API'nin düzgün kimlik bilgileri olmadan çağrılmasını engellemez. Uygulamanın Server bunları doğru şekilde korumak için uygun uç noktalarda da kullanması [Authorize] gerekir.

IAccessTokenProvider.RequestAccessToken API'yi çağırma isteğine eklenebilen bir erişim belirteci isteme işlemini üstlenir. Belirteç önbelleğe alınmışsa veya hizmet kullanıcı etkileşimi olmadan yeni bir erişim belirteci sağlayabiliyorsa, belirteç isteği başarılı olur. Aksi takdirde, belirteç isteği deyiminde yakalanan ile AccessTokenNotAvailableExceptiontry-catch başarısız olur.

İstekte yer alacak gerçek belirteci elde etmek için, uygulamanın çağrısı tokenResult.TryGetToken(out var token)yaparak isteğin başarılı olup olmadığını denetlemesi gerekir.

İstek başarılı olursa belirteç değişkeni erişim belirteci ile doldurulur. AccessToken.Value Belirtecin özelliği, istek üst bilgisine eklenecek değişmez dizeyi Authorization kullanıma sunar.

Belirteç kullanıcı etkileşimi olmadan sağlanamadığı için istek başarısız olduysa:

  • .NET 7 veya sonraki sürümlerinde ASP.NET Core: Uygulama, erişim belirtecinin yenilenmesine AccessTokenResult.InteractiveRequestUrl izin vermek için verilen AccessTokenResult.InteractionOptions öğesini kullanmaya gider.
  • .NET 6 veya önceki sürümlerinde ASP.NET Core: Belirteç sonucu bir yeniden yönlendirme URL'si içerir. Bu URL'ye gitmek, kullanıcıyı oturum açma sayfasına ve başarılı bir kimlik doğrulamasından sonra geçerli sayfaya geri götürür.
@page "/fetchdata"
@using Microsoft.AspNetCore.Authorization
@using Microsoft.AspNetCore.Components.WebAssembly.Authentication
@using {APP NAMESPACE}.Shared
@attribute [Authorize]
@inject HttpClient Http

...

@code {
    private WeatherForecast[] forecasts;

    protected override async Task OnInitializedAsync()
    {
        try
        {
            forecasts = await Http.GetFromJsonAsync<WeatherForecast[]>("WeatherForecast");
        }
        catch (AccessTokenNotAvailableException exception)
        {
            exception.Redirect();
        }
    }
}

Linux'ta Azure Uygulaması Hizmeti

Linux üzerinde Azure Uygulaması Hizmetine dağıtırken vereni açıkça belirtin. Daha fazla bilgi için bkz. SPA'lar için Web API arka ucu güvenliğini sağlamak için kullanmaIdentity.

API yetkilendirmesi ile ad ve rol talebi

Özel kullanıcı fabrikası

Client Uygulamada özel bir kullanıcı fabrikası oluşturun. IdentitySunucu, tek role bir JStalepte on dizisi olarak birden çok rol gönderir. Tek bir rol, talepte dize değeri olarak gönderilir. Fabrika, kullanıcının rollerinin her biri için ayrı role bir talep oluşturur.

CustomUserFactory.cs:

using System.Security.Claims;
using System.Text.Json;
using Microsoft.AspNetCore.Components.WebAssembly.Authentication;
using Microsoft.AspNetCore.Components.WebAssembly.Authentication.Internal;

public class CustomUserFactory
    : AccountClaimsPrincipalFactory<RemoteUserAccount>
{
    public CustomUserFactory(IAccessTokenProviderAccessor accessor)
        : base(accessor)
    {
    }

    public override async ValueTask<ClaimsPrincipal> CreateUserAsync(
        RemoteUserAccount account,
        RemoteAuthenticationUserOptions options)
    {
        var user = await base.CreateUserAsync(account, options);

        if (user.Identity is not null && user.Identity.IsAuthenticated)
        {
            var identity = (ClaimsIdentity)user.Identity;
            var roleClaims = identity.FindAll(identity.RoleClaimType).ToArray();

            if (roleClaims.Any())
            {
                foreach (var existingClaim in roleClaims)
                {
                    identity.RemoveClaim(existingClaim);
                }

                var rolesElem = 
                    account.AdditionalProperties[identity.RoleClaimType];

                if (options.RoleClaim is not null && rolesElem is JsonElement roles)
                {
                    if (roles.ValueKind == JsonValueKind.Array)
                    {
                        foreach (var role in roles.EnumerateArray())
                        {
                            var roleValue = role.GetString();

                            if (!string.IsNullOrEmpty(roleValue))
                            {
                                identity.AddClaim(
                                  new Claim(options.RoleClaim, roleValue));
                            }

                        }
                    }
                    else
                    {
                        var roleValue = roles.GetString();

                        if (!string.IsNullOrEmpty(roleValue))
                        {
                            identity.AddClaim(
                              new Claim(options.RoleClaim, roleValue));
                        }
                    }
                }
            }
        }

        return user;
    }
}
using System.Linq;
using System.Security.Claims;
using System.Text.Json;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Components.WebAssembly.Authentication;
using Microsoft.AspNetCore.Components.WebAssembly.Authentication.Internal;

public class CustomUserFactory
    : AccountClaimsPrincipalFactory<RemoteUserAccount>
{
    public CustomUserFactory(IAccessTokenProviderAccessor accessor)
        : base(accessor)
    {
    }

    public override async ValueTask<ClaimsPrincipal> CreateUserAsync(
        RemoteUserAccount account,
        RemoteAuthenticationUserOptions options)
    {
        var user = await base.CreateUserAsync(account, options);

        if (user.Identity.IsAuthenticated)
        {
            var identity = (ClaimsIdentity)user.Identity;
            var roleClaims = identity.FindAll(identity.RoleClaimType).ToArray();

            if (roleClaims.Any())
            {
                foreach (var existingClaim in roleClaims)
                {
                    identity.RemoveClaim(existingClaim);
                }

                var rolesElem = account.AdditionalProperties[identity.RoleClaimType];

                if (rolesElem is JsonElement roles)
                {
                    if (roles.ValueKind == JsonValueKind.Array)
                    {
                        foreach (var role in roles.EnumerateArray())
                        {
                            identity.AddClaim(new Claim(options.RoleClaim, role.GetString()));
                        }
                    }
                    else
                    {
                        identity.AddClaim(new Claim(options.RoleClaim, roles.GetString()));
                    }
                }
            }
        }

        return user;
    }
}

Client Uygulamada, fabrikayı Program dosyasına kaydedin:

builder.Services.AddApiAuthorization()
    .AddAccountClaimsPrincipalFactory<CustomUserFactory>();

Server Uygulamada, rolle ilgili hizmetler ekleyen oluşturucuyu Identity arayınAddRoles.

Program dosyasında:

using Microsoft.AspNetCore.Identity;

...

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

Startup.cs içinde:

using Microsoft.AspNetCore.Identity;

...

services.AddDefaultIdentity<ApplicationUser>(options => 
    options.SignIn.RequireConfirmedAccount = true)
    .AddRoles<IdentityRole>()
    .AddEntityFrameworkStores<ApplicationDbContext>();

Sunucuyu Yapılandırma Identity

Aşağıdaki yaklaşımlardan birini kullanın:

API yetkilendirme seçenekleri

Server Uygulamada:

  • Ve taleplerini kimlik belirtecine name ve role erişim belirtecine yerleştirecek şekilde Sunucuyu yapılandırınIdentity.
  • JWT belirteci işleyicisindeki roller için varsayılan eşlemeyi engelleyin.

Program dosyasında:

using System.IdentityModel.Tokens.Jwt;

...

builder.Services.AddIdentityServer()
    .AddApiAuthorization<ApplicationUser, ApplicationDbContext>(options => {
        options.IdentityResources["openid"].UserClaims.Add("name");
        options.ApiResources.Single().UserClaims.Add("name");
        options.IdentityResources["openid"].UserClaims.Add("role");
        options.ApiResources.Single().UserClaims.Add("role");
    });

JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Remove("role");

Startup.cs içinde:

using System.IdentityModel.Tokens.Jwt;
using System.Linq;

...

services.AddIdentityServer()
    .AddApiAuthorization<ApplicationUser, ApplicationDbContext>(options => {
        options.IdentityResources["openid"].UserClaims.Add("name");
        options.ApiResources.Single().UserClaims.Add("name");
        options.IdentityResources["openid"].UserClaims.Add("role");
        options.ApiResources.Single().UserClaims.Add("role");
    });

JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Remove("role");

Profil Hizmeti

Server Uygulamada bir ProfileService uygulama oluşturun.

ProfileService.cs:

using IdentityModel;
using Duende.IdentityServer.Models;
using Duende.IdentityServer.Services;

public class ProfileService : IProfileService
{
    public ProfileService()
    {
    }

    public async Task GetProfileDataAsync(ProfileDataRequestContext context)
    {
        var nameClaim = context.Subject.FindAll(JwtClaimTypes.Name);
        context.IssuedClaims.AddRange(nameClaim);

        var roleClaims = context.Subject.FindAll(JwtClaimTypes.Role);
        context.IssuedClaims.AddRange(roleClaims);

        await Task.CompletedTask;
    }

    public async Task IsActiveAsync(IsActiveContext context)
    {
        await Task.CompletedTask;
    }
}
using IdentityModel;
using Duende.IdentityServer.Models;
using Duende.IdentityServer.Services;
using System.Threading.Tasks;

public class ProfileService : IProfileService
{
    public ProfileService()
    {
    }

    public async Task GetProfileDataAsync(ProfileDataRequestContext context)
    {
        var nameClaim = context.Subject.FindAll(JwtClaimTypes.Name);
        context.IssuedClaims.AddRange(nameClaim);

        var roleClaims = context.Subject.FindAll(JwtClaimTypes.Role);
        context.IssuedClaims.AddRange(roleClaims);

        await Task.CompletedTask;
    }

    public async Task IsActiveAsync(IsActiveContext context)
    {
        await Task.CompletedTask;
    }
}

Server Uygulamada Profil Hizmeti'ni Program dosyasına kaydedin:

using Duende.IdentityServer.Services;

...

builder.Services.AddTransient<IProfileService, ProfileService>();

JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Remove("role");

Server Uygulamada Profil Hizmeti'ni içinde Startup.ConfigureServicesStartup.cskaydedin:

using IdentityServer4.Services;

...

services.AddTransient<IProfileService, ProfileService>();

JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Remove("role");

Yetkilendirme mekanizmalarını kullanma

Client Uygulamada, bileşen yetkilendirme yaklaşımları bu noktada işlevseldir. Bileşenlerdeki yetkilendirme mekanizmalarından herhangi biri kullanıcıyı yetkilendirmek için bir rol kullanabilir:

User.Identity.Name , uygulamada genellikle oturum açma e-posta adresi olan kullanıcının kullanıcı adıyla doldurulur Client .

UserManager ve SignInManager

Sunucu uygulaması şunları gerektirdiğinde kullanıcı tanımlayıcısı talep türünü ayarlayın:

Program.cs.NET 6 veya sonraki sürümlerinde ASP.NET Core için:

using System.Security.Claims;

...

builder.Services.Configure<IdentityOptions>(options => 
    options.ClaimsIdentity.UserIdClaimType = ClaimTypes.NameIdentifier);

Startup.ConfigureServices 6.0'dan önceki ASP.NET Core sürümleri için:

using System.Security.Claims;

...

services.Configure<IdentityOptions>(options => 
    options.ClaimsIdentity.UserIdClaimType = ClaimTypes.NameIdentifier);

WeatherForecastController Aşağıdaki, yöntemi çağrıldığında günlüğe Get kaydederUserName.

Not

Aşağıdaki örnek, C# 10 veya üzeri (.NET 6 veya üzeri) bir özellik olan dosya kapsamlı bir ad alanı kullanır.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Identity;
using Microsoft.Extensions.Logging;
using BlazorSample.Server.Models;
using BlazorSample.Shared;

namespace BlazorSample.Server.Controllers;

[Authorize]
[ApiController]
[Route("[controller]")]
public class WeatherForecastController : ControllerBase
{
    private readonly UserManager<ApplicationUser> userManager;

    private static readonly string[] Summaries = new[]
    {
        "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", 
        "Balmy", "Hot", "Sweltering", "Scorching"
    };

    private readonly ILogger<WeatherForecastController> logger;

    public WeatherForecastController(ILogger<WeatherForecastController> logger, 
        UserManager<ApplicationUser> userManager)
    {
        this.logger = logger;
        this.userManager = userManager;
    }

    [HttpGet]
    public async Task<IEnumerable<WeatherForecast>> Get()
    {
        var rng = new Random();

        var user = await userManager.GetUserAsync(User);

        if (user != null)
        {
            logger.LogInformation("User.Identity.Name: {UserIdentityName}", user.UserName);
        }

        return Enumerable.Range(1, 5).Select(index => new WeatherForecast
        {
            Date = DateTime.Now.AddDays(index),
            TemperatureC = rng.Next(-20, 55),
            Summary = Summaries[rng.Next(Summaries.Length)]
        })
        .ToArray();
    }
}

Yukarıdaki örnekte:

  • Projenin Server ad alanı şeklindedir BlazorSample.Server.
  • Projenin Shared ad alanı şeklindedir BlazorSample.Shared.

Özel bir etki alanı ve sertifika ile Azure Uygulaması Hizmeti'nde barındırma

Aşağıdaki kılavuzda açıklanmaktadır:

  • Sunucu ile barındırılan Blazor WebAssembly bir uygulamayı özel etki alanıyla Identity Azure Uygulaması Hizmeti'ne dağıtma.
  • Tarayıcılarla HTTPS protokolü iletişimi için TLS sertifikası oluşturma ve kullanma. Kılavuz, sertifikayı özel bir etki alanıyla kullanmaya odaklansa da, örneğin, varsayılan Azure Uygulaması etki alanını kullanmak için contoso.azurewebsites.netde aynı şekilde geçerlidir.

Bu barındırma senaryosunda, Sunucunun belirteç imzalama anahtarı ve sitenin tarayıcılarla HTTPS güvenli iletişimi için Identity aynı sertifikayı kullanmayın:

  • Bu iki gereksinim için farklı sertifikalar kullanmak, her amaç için özel anahtarları yalıttığı için iyi bir güvenlik uygulamasıdır.
  • Tarayıcılarla iletişim için TLS sertifikaları, Sunucunun belirteç imzalamasını Identity etkilemeden bağımsız olarak yönetilir.
  • Azure Key Vault özel etki alanı bağlaması için app Service uygulamasına bir sertifika sağladığında, Identity Sunucu belirteç imzalama için Azure Key Vault'tan aynı sertifikayı alamıyor. Sunucuyu fiziksel bir yoldan aynı TLS sertifikasını kullanacak şekilde yapılandırmak Identity mümkün olsa da, güvenlik sertifikalarını kaynak denetimine yerleştirmek kötü bir uygulamadır ve çoğu senaryoda bundan kaçınılmalıdır.

Aşağıdaki kılavuzda, Azure Key Vault'ta yalnızca Sunucu belirteci imzalama için Identity otomatik olarak imzalanan bir sertifika oluşturulur. Sunucu yapılandırması, Identity uygulamanın CurrentUser>My sertifika deposu aracılığıyla anahtar kasası sertifikasını kullanır. Özel etki alanları olan HTTPS trafiği için kullanılan diğer sertifikalar, Sunucu imzalama sertifikasından Identity ayrı olarak oluşturulur ve yapılandırılır.

Bir uygulamayı, Azure Uygulaması Hizmetini ve Azure Key Vault'u özel bir etki alanı ve HTTPS ile barındıracak şekilde yapılandırmak için:

  1. Plan düzeyi Basic B1 veya daha yüksek olan bir App Service planı oluşturun. App Service,özel etki alanlarını kullanmak için bir veya daha yüksek bir Basic B1 hizmet katmanı gerektirir.

  2. Sitenin güvenli tarayıcı iletişimi (HTTPS protokolü) için, kuruluşunuzun denetlediğini tam etki alanı adının (FQDN) ortak adıyla (örneğin, www.contoso.com) bir PFX sertifikası oluşturun. Sertifikayı şu şekilde oluşturun:

    • Anahtar kullanımları
      • Dijital imza doğrulama (digitalSignature)
      • Anahtar şifreleme (keyEncipherment)
    • Gelişmiş/genişletilmiş anahtar kullanımları
      • İstemci Kimlik Doğrulaması (1.3.6.1.5.5.7.3.2)
      • Sunucu Kimlik Doğrulaması (1.3.6.1.5.5.7.3.1)

    Sertifikayı oluşturmak için aşağıdaki yaklaşımlardan birini veya diğer uygun araçları veya çevrimiçi hizmeti kullanın:

    Daha sonra sertifikayı Azure Key Vault'a aktarmak için kullanılan parolayı not edin.

    Azure Key Vault sertifikaları hakkında daha fazla bilgi için bkz . Azure Key Vault: Sertifikalar.

  3. Yeni bir Azure Key Vault oluşturun veya Azure aboneliğinizde mevcut bir anahtar kasayı kullanın.

  4. Anahtar kasasının Sertifikalar alanında PFX site sertifikasını içeri aktarın. Daha sonra uygulamanın yapılandırmasında kullanılan sertifikanın parmak izini kaydedin.

  5. Azure Key Vault'ta Sunucu belirteci imzalama için Identity yeni bir otomatik olarak imzalanan sertifika oluşturun. Sertifikaya bir Sertifika Adı ve Konu verin. Konu olarak CN={COMMON NAME}belirtilir ve burada {COMMON NAME} yer tutucu sertifikanın ortak adıdır. Ortak ad herhangi bir alfasayısal dize olabilir. Örneğin, CN=IdentityServerSigning geçerli bir sertifika Konusudur. Verme İlkesi>Gelişmiş İlke Yapılandırması'nda varsayılan ayarları kullanın. Daha sonra uygulamanın yapılandırmasında kullanılan sertifikanın parmak izini kaydedin.

  6. Azure portalında Azure Uygulaması Hizmeti'ne gidin ve aşağıdaki yapılandırmayla yeni bir App Service oluşturun:

    • Yayımlama ayarı olarak Codeayarlanır.
    • Çalışma zamanı yığını , uygulamanın çalışma zamanına ayarlanır.
    • Sku ve boyut için App Service katmanının veya daha yüksek olduğunu Basic B1 onaylayın. App Service,özel etki alanlarını kullanmak için bir veya daha yüksek bir Basic B1 hizmet katmanı gerektirir.
  7. Azure App Service'i oluşturulduktan sonra uygulamanın Yapılandırması'nı açın ve daha önce kaydedilen sertifika parmak izlerini belirten yeni bir uygulama ayarı ekleyin. Uygulama ayarı anahtarı şeklindedir WEBSITE_LOAD_CERTIFICATES. Aşağıdaki örnekte gösterildiği gibi, uygulama ayarı değerindeki sertifika parmak izlerini virgülle ayırın:

    • Anahtar: WEBSITE_LOAD_CERTIFICATES
    • Değer: 57443A552A46DB...D55E28D412B943565,29F43A772CB6AF...1D04F0C67F85FB0B1

    Azure portalında uygulama ayarlarını kaydetmek iki adımlı bir işlemdir: Anahtar-değer ayarını kaydedinWEBSITE_LOAD_CERTIFICATES, ardından dikey penceresinin üst kısmındaki Kaydet düğmesini seçin.

  8. Uygulamanın TLS/SSL ayarlarını seçin. Özel Anahtar Sertifikaları (.pfx) öğesini seçin. Key Vault Sertifikasını İçeri Aktar işlemini kullanın. hem HTTPS iletişimi için sitenin sertifikasını hem de sitenin otomatik olarak imzalanan Identity Sunucu belirteci imzalama sertifikasını içeri aktarmak için işlemi iki kez kullanın.

  9. Özel etki alanları dikey penceresine gidin. Etki alanı kayıt şirketinizin web sitesinde, etki alanını yapılandırmak için IP adresini ve Özel Etki Alanı Doğrulama Kimliğini kullanın. Tipik bir etki alanı yapılandırması şunları içerir:

    • Azure portalından BIR Ana Bilgisayarı@ ve IP adresinin değeri olan bir A Kaydı.
    • Ana Bilgisayarı asuid ve Azure tarafından oluşturulan ve Azure portalı tarafından sağlanan doğrulama kimliğinin değeriyle txt kaydı.

    Etki alanı kayıt şirketinizin web sitesine yaptığınız değişiklikleri doğru kaydettiğinizden emin olun. Bazı kayıt şirketi web siteleri, etki alanı kayıtlarını kaydetmek için iki aşamalı bir işlem gerektirir: Bir veya daha fazla kayıt tek tek kaydedilir ve ardından etki alanının kaydı ayrı bir düğmeyle güncelleştiriler.

  10. Azure portalında Özel etki alanları dikey penceresine dönün. Özel etki alanı ekle'yi seçin. Kayıt seçeneğini belirleyin. Etki alanını sağlayın ve Doğrula'yı seçin. Etki alanı kayıtları doğruysa ve İnternet'e yayılırsa portal, Özel etki alanı ekle düğmesini seçmenize olanak tanır.

    Etki alanı kayıt şirketiniz tarafından işlendikten sonra etki alanı kayıt değişikliklerinin İnternet etki alanı adı sunucuları (DNS) arasında yayılması birkaç gün sürebilir. Etki alanı kayıtları üç iş günü içinde güncelleştirilmezse, kayıtların etki alanı kayıt şirketiyle doğru şekilde ayarlandığını onaylayın ve müşteri desteğine başvurun.

  11. Özel etki alanları dikey penceresinde, etki alanının SSL DURUMU olarak işaretlenirNot Secure. Bağlama ekle bağlantısını seçin. Özel etki alanı bağlaması için anahtar kasasından site HTTPS sertifikasını seçin.

  12. Visual Studio'da Sunucu projesinin uygulama ayarları dosyasını (appsettings.json veya appsettings.Production.json) açın. Sunucu yapılandırmasına Identity aşağıdaki Key bölümü ekleyin. Anahtar için Name otomatik olarak imzalanan sertifika Konusunu belirtin. Aşağıdaki örnekte, sertifikanın anahtar kasasında atanan ortak adı şu şekildedir:IdentityServerSigningCN=IdentityServerSigning

    "IdentityServer": {
    
      ...
    
      "Key": {
        "Type": "Store",
        "StoreName": "My",
        "StoreLocation": "CurrentUser",
        "Name": "CN=IdentityServerSigning"
      }
    },
    
  13. Visual Studio'da, Sunucu projesi için bir Azure Uygulaması Hizmeti yayımlama profili oluşturun. Menü çubuğundan şunları seçin: Derleme>>Yeni>Azure> Azure Uygulaması Hizmeti (Windows veya Linux). Visual Studio bir Azure aboneliğine bağlandığında, Kaynak türüne göre Azure kaynaklarının görünümünü ayarlayabilirsiniz. Web Uygulaması listesinde gezinerek uygulamanın App Service'ini bulun ve seçin. Bitir'i seçin.

  14. Visual Studio Yayımla penceresine döndüğünde, anahtar kasası ve SQL Server veritabanı hizmeti bağımlılıkları otomatik olarak algılenir.

    Anahtar kasası hizmeti için varsayılan ayarlarda yapılandırma değişikliği gerekmez.

    Test amacıyla, bir uygulamanın şablon tarafından Blazor varsayılan olarak yapılandırılan yerel SQLite veritabanı, ek yapılandırma olmadan uygulamayla dağıtılabilir. Üretimde Sunucu için Identity farklı bir veritabanı yapılandırmak bu makalenin kapsamı dışındadır. Daha fazla bilgi için aşağıdaki belge kümelerindeki veritabanı kaynaklarına bakın:

  15. Pencerenin üst kısmındaki dağıtım profili adının altındaki Düzenle bağlantısını seçin. Hedef URL'yi sitenin özel etki alanı URL'si (örneğin, https://www.contoso.com) olarak değiştirin. Ayarları kaydedin.

  16. Uygulamayı yayımlayın. Visual Studio bir tarayıcı penceresi açar ve siteyi özel etki alanında istemektedir.

Azure belgeleri, Azure hizmetlerini ve özel etki alanlarını App Service'te TLS bağlaması ile kullanma hakkında ek ayrıntılar içerir. Bu bilgiler arasında A kayıtları yerine CNAME kayıtlarını kullanma hakkında bilgiler de yer alır. Daha fazla bilgi edinmek için aşağıdaki kaynaklara bakın:

Azure portalında uygulama, uygulama yapılandırması veya Azure hizmetlerinde yapılan bir değişiklik sonrasında her uygulama testi çalıştırması için yeni bir özel mod tarayıcı penceresi (örneğin, Microsoft Edge InPrivate modu veya Google Chrome Gizli modu) kullanmanızı öneririz. cookieÖnceki bir test çalıştırmasından kalanlar, site yapılandırması doğru olsa bile siteyi test ederken kimlik doğrulaması veya yetkilendirmenin başarısız olmasına neden olabilir. Visual Studio'yu her test çalıştırması için yeni bir özel tarayıcı penceresi açacak şekilde yapılandırma hakkında daha fazla bilgi için s ve site verileri bölümüne bakın.Cookie

Azure portalında App Service yapılandırması değiştirildiğinde, güncelleştirmeler genellikle hızlı bir şekilde etkinleşir ancak anında uygulanmaz. Bazı durumlarda, yapılandırma değişikliğinin etkili olması için App Service'in yeniden başlatılması için kısa bir süre beklemeniz gerekir.

Sunucu anahtar imzalama sertifikası yükleme sorununu gideriyorsanız Identity azure portalı Kudu PowerShell komut kabuğunda aşağıdaki komutu yürütebilirsiniz. komutu, uygulamanın sertifika deposundan erişebileceği sertifikaların CurrentUser>My listesini sağlar. Çıktı, bir uygulamada hata ayıklarken yararlı olan sertifika konularını ve parmak izlerini içerir:

Get-ChildItem -path Cert:\CurrentUser\My -Recurse | Format-List DnsNameList, Subject, Thumbprint, EnhancedKeyUsageList

Sorun giderme

Günlük Kaydı

Kimlik doğrulaması için hata ayıklama veya izleme günlüğünü etkinleştirmek içinBlazor WebAssembly, makale sürümü seçicisinin ASP.NET Core 7.0 veya üzeri olarak ayarlandığı ASP.NET Core Blazor günlüğünün İstemci tarafı kimlik doğrulama günlüğü bölümüne bakın.

Sık karşılaşılan hatalar

  • Uygulamanın veya Identity Sağlayıcının (IP) yanlış yapılandırılması

    En yaygın hatalar yanlış yapılandırmadan kaynaklanıyor. Aşağıda birkaç örnek verilmiştir:

    • Senaryonun gereksinimlerine bağlı olarak, eksik veya yanlış bir Yetkili, Örnek, Kiracı Kimliği, Kiracı etki alanı, İstemci Kimliği veya Yeniden Yönlendirme URI'si bir uygulamanın istemcilerin kimliğini doğrulamasını engeller.
    • Yanlış istek kapsamları istemcilerin sunucu web API'leri uç noktalarına erişmesini engeller.
    • Hatalı veya eksik sunucu API'si izinleri istemcilerin sunucu web API'si uç noktalarına erişmesini engeller.
    • Uygulamayı IP'nin uygulama kaydının Yeniden Yönlendirme URI'sinde yapılandırılandan farklı bir bağlantı noktasında çalıştırma. Microsoft Entra Kimliği ve geliştirme testi adresinde çalışan bir localhost uygulama için bağlantı noktası gerekli değildir, ancak uygulamanın bağlantı noktası yapılandırması ve uygulamanın çalıştırıldığı bağlantı noktası, adres olmayanlarlocalhost için eşleşmelidir.

    Bu makalenin kılavuzunun yapılandırma bölümlerinde doğru yapılandırma örnekleri gösterilir. Uygulama ve IP yanlış yapılandırması olup olmadığını bulmak için makalenin her bölümünü dikkatle denetleyin.

    Yapılandırma doğru görünüyorsa:

    • Uygulama günlüklerini analiz edin.

    • tarayıcının geliştirici araçlarıyla istemci uygulaması ile IP veya sunucu uygulaması arasındaki ağ trafiğini inceleyin. Genellikle, soruna neyin neden olduğuna dair ipucu içeren tam bir hata iletisi veya ileti, istekte bulunduktan sonra IP veya sunucu uygulaması tarafından istemciye döndürülür. Geliştirici araçları kılavuzu aşağıdaki makalelerde bulunur:

    • ON Web Belirteci'nin BlazorJS(JWT) kullanıldığı sürümler için, sorunun oluştuğu yere bağlı olarak istemcinin kimliğini doğrulamak veya sunucu web API'sine erişmek için kullanılan belirtecin içeriğinin kodunu kaldırın. Daha fazla bilgi için bkz. ON Web Token (JWT) içeriğini JSinceleme.

    Belge ekibi makalelerdeki belge geri bildirimlerine ve hatalarına yanıt verir (Bu sayfa geri bildirimi bölümünden bir sorun açın) ancak ürün desteği sağlayamaz. Bir uygulamada sorun gidermeye yardımcı olmak için çeşitli genel destek forumları mevcuttur. Aşağıdakileri öneririz:

    Önceki forumlar Microsoft'a ait değildir veya microsoft tarafından denetlenmemektedir.

    Güvenlikle ilgili olmayan, hassas olmayan ve gizli olmayan yeniden üretilebilir çerçeve hata raporları için ASP.NET Core ürün birimiyle ilgili bir sorun açın. Sorunun nedenini ayrıntılı bir şekilde araştırıp kendi başınıza ve bir genel destek forumundaki topluluğun yardımıyla çözene kadar ürün birimiyle ilgili bir sorun açmayın. Ürün birimi, basit yanlış yapılandırma veya üçüncü taraf hizmetleri içeren kullanım örnekleri nedeniyle bozulan tek tek uygulamalarda sorun gideremez. Bir rapor doğası gereği hassas veya gizliyse ya da saldırganların yararlanabileceği üründe olası bir güvenlik açığını açıklıyorsa bkz . Güvenlik sorunlarını ve hatalarını raporlama (dotnet/aspnetcore GitHub deposu).

  • ME-ID için yetkisiz istemci

    bilgi: Microsoft.AspNetCore.Authorization.DefaultAuthorizationService[2] Yetkilendirme başarısız oldu. Bu gereksinimler karşılanmadı: DenyAnonymousAuthorizationRequirement: Kimliği doğrulanmış bir kullanıcı gerektirir.

    ME-ID'den oturum açma geri çağırma hatası:

    • Hata: unauthorized_client
    • Açıklama: AADB2C90058: The provided application is not configured to allow public clients.

    Hatayı düzeltmek için:

    1. Azure portalında uygulamanın bildirimine erişin.
    2. özniteliğini allowPublicClient veya trueolarak null ayarlayın.

Cookies ve site verileri

Cookies ve site verileri uygulama güncelleştirmeleri arasında kalıcı olabilir ve test ve sorun gidermeyi etkileyebilir. Uygulama kodu değişiklikleri, sağlayıcıyla kullanıcı hesabı değişiklikleri veya sağlayıcı uygulaması yapılandırma değişiklikleri yaparken aşağıdakileri temizleyin:

  • Kullanıcı oturum açmaları cookie
  • Uygulamalar cookie
  • Önbelleğe alınan ve depolanan site verileri

Kalan cookies ve site verilerinin test ve sorun gidermeye engel olmasını önlemeye yönelik bir yaklaşım:

  • Tarayıcı yapılandırma
    • Tarayıcı her kapatıldığında tüm cookie ve site verilerini silmek üzere yapılandırabileceğiniz test için bir tarayıcı kullanın.
    • Uygulama, test kullanıcısı veya sağlayıcı yapılandırmasında yapılan herhangi bir değişiklik için tarayıcının el ile veya IDE tarafından kapatıldığını doğrulayın.
  • Visual Studio'da InPrivate veya Gizli modda tarayıcı açmak için özel bir komut kullanın:
    • Visual Studio'nun Çalıştır düğmesinden Gözat iletişim kutusunu açın.
    • Ekle düğmesini seçin.
    • Program alanında tarayıcınızın yolunu belirtin. Aşağıdaki yürütülebilir yollar Windows 10 için tipik yükleme konumlarıdır. Tarayıcınız farklı bir konumda yüklüyse veya Windows 10 kullanmıyorsanız, tarayıcının yürütülebilir dosyasının yolunu sağlayın.
      • Microsoft Edge: C:\Program Files (x86)\Microsoft\Edge\Application\msedge.exe
      • Google Chrome: C:\Program Files (x86)\Google\Chrome\Application\chrome.exe
      • Mozilla Firefox: C:\Program Files\Mozilla Firefox\firefox.exe
    • Bağımsız Değişkenler alanında, tarayıcının InPrivate veya Gizli modda açmak için kullandığı komut satırı seçeneğini belirtin. Bazı tarayıcılar uygulamanın URL'sini gerektirir.
      • Microsoft Edge: kullanın -inprivate.
      • Google Chrome: Yer --incognito --new-window {URL}tutucunun {URL} açıldığı URL olduğu yerde kullanın (örneğin, https://localhost:5001).
      • Mozilla Firefox: -private -url {URL}Yer tutucunun {URL} açıldığı URL olduğu yerde kullanın (örneğin, https://localhost:5001).
    • Kolay ad alanına bir ad girin. Örneğin, Firefox Auth Testing.
    • Tamam düğmesini seçin.
    • Bir uygulamayla yapılan her test yinelemesi için tarayıcı profilini seçmek zorunda kalmamak için Varsayılan Olarak Ayarla düğmesiyle profili varsayılan olarak ayarlayın.
    • Uygulama, test kullanıcısı veya sağlayıcı yapılandırmasında yapılan herhangi bir değişiklik için tarayıcının IDE tarafından kapatıldığını doğrulayın.

Uygulama yükseltmeleri

Çalışan bir uygulama, geliştirme makinesindeki .NET Core SDK'sını yükselttikten veya uygulama içindeki paket sürümlerini değiştirdikten hemen sonra başarısız olabilir. Bazı durumlarda, tutarsız paketler ana yükseltmeler yaparken bir uygulamayı bozabilir. Bu sorunların çoğu şu yönergeleri izleyerek düzeltilebilir:

  1. Komut kabuğundan yürüterek dotnet nuget locals all --clear yerel sistemin NuGet paket önbelleklerini temizleyin.
  2. Proje bin ve obj klasörlerini silin.
  3. Projeyi geri yükleyin ve yeniden oluşturun.
  4. Uygulamayı yeniden dağıtmadan önce sunucudaki dağıtım klasöründeki tüm dosyaları silin.

Not

Uygulamanın hedef çerçevesiyle uyumlu olmayan paket sürümlerinin kullanımı desteklenmez. Paket hakkında bilgi için NuGet Galerisi'ni veya FuGet Paket Gezgini'ni kullanın.

Server Uygulamayı çalıştırma

Barındırılan Blazor WebAssemblybir çözümü test ederken ve sorun giderirken uygulamayı projeden çalıştırdığınızdan Server emin olun.

Kullanıcıyı inceleme

Aşağıdaki User bileşen doğrudan uygulamalarda kullanılabilir veya daha fazla özelleştirme için temel olarak kullanılabilir.

User.razor:

@page "/user"
@attribute [Authorize]
@using System.Text.Json
@using System.Security.Claims
@inject IAccessTokenProvider AuthorizationService

<h1>@AuthenticatedUser?.Identity?.Name</h1>

<h2>Claims</h2>

@foreach (var claim in AuthenticatedUser?.Claims ?? Array.Empty<Claim>())
{
    <p class="claim">@(claim.Type): @claim.Value</p>
}

<h2>Access token</h2>

<p id="access-token">@AccessToken?.Value</p>

<h2>Access token claims</h2>

@foreach (var claim in GetAccessTokenClaims())
{
    <p>@(claim.Key): @claim.Value.ToString()</p>
}

@if (AccessToken != null)
{
    <h2>Access token expires</h2>

    <p>Current time: <span id="current-time">@DateTimeOffset.Now</span></p>
    <p id="access-token-expires">@AccessToken.Expires</p>

    <h2>Access token granted scopes (as reported by the API)</h2>

    @foreach (var scope in AccessToken.GrantedScopes)
    {
        <p>Scope: @scope</p>
    }
}

@code {
    [CascadingParameter]
    private Task<AuthenticationState> AuthenticationState { get; set; }

    public ClaimsPrincipal AuthenticatedUser { get; set; }
    public AccessToken AccessToken { get; set; }

    protected override async Task OnInitializedAsync()
    {
        await base.OnInitializedAsync();
        var state = await AuthenticationState;
        var accessTokenResult = await AuthorizationService.RequestAccessToken();

        if (!accessTokenResult.TryGetToken(out var token))
        {
            throw new InvalidOperationException(
                "Failed to provision the access token.");
        }

        AccessToken = token;

        AuthenticatedUser = state.User;
    }

    protected IDictionary<string, object> GetAccessTokenClaims()
    {
        if (AccessToken == null)
        {
            return new Dictionary<string, object>();
        }

        // header.payload.signature
        var payload = AccessToken.Value.Split(".")[1];
        var base64Payload = payload.Replace('-', '+').Replace('_', '/')
            .PadRight(payload.Length + (4 - payload.Length % 4) % 4, '=');

        return JsonSerializer.Deserialize<IDictionary<string, object>>(
            Convert.FromBase64String(base64Payload));
    }
}

ON Web Belirtecinin JS(JWT) içeriğini inceleme

ON Web Belirtecinin (JWT) kodunu JSçözmek için Microsoft'un jwt.ms aracını kullanın. Kullanıcı arabirimindeki değerler hiçbir zaman tarayıcınızdan ayrılmaz.

Kodlanmış JWT örneği (görüntü için kısaltıldı):

eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImtpZCI6Ilg1ZVhrNHh5b2pORnVtMWtsMll0djhkbE5QNC1j ... bQdHBHGcQQRbW7Wmo6SWYG4V_bU55Ug_PW4pLPr20tTS8Ct7_uwy9DWrzCMzpD-EiwT5IjXwlGX3IXVjHIlX50IVIydBoPQtadvT7saKo1G5Jmutgq41o-dmz6-yBMKV2_nXA25Q

Azure AAD B2C'de kimlik doğrulaması yapılan bir uygulama için araç tarafından çözülen örnek JWT:

{
  "typ": "JWT",
  "alg": "RS256",
  "kid": "X5eXk4xyojNFum1kl2Ytv8dlNP4-c57dO6QGTVBwaNk"
}.{
  "exp": 1610059429,
  "nbf": 1610055829,
  "ver": "1.0",
  "iss": "https://mysiteb2c.b2clogin.com/5cc15ea8-a296-4aa3-97e4-226dcc9ad298/v2.0/",
  "sub": "5ee963fb-24d6-4d72-a1b6-889c6e2c7438",
  "aud": "70bde375-fce3-4b82-984a-b247d823a03f",
  "nonce": "b2641f54-8dc4-42ca-97ea-7f12ff4af871",
  "iat": 1610055829,
  "auth_time": 1610055822,
  "idp": "idp.com",
  "tfp": "B2C_1_signupsignin"
}.[Signature]

Ek kaynaklar