Microsoft.Identity.Web'te belirteç önbelleği

Belirteç önbelleğe alma uygulama performansını, güvenilirliğini ve kullanıcı deneyimini geliştirir. Microsoft. Identity.Web, performansı, kalıcılığı ve operasyonel güvenilirliği dengeleyen esnek önbelleğe alma stratejileri sağlar.

Genel bakış

Microsoft.Identity.Web tarafından hangi belirteçlerin önbelleğe alındığı ve bu önbelleğe almanın uygulamanız için neden önemli olduğu belirtilmektedir.

Hangi belirteçler önbelleğe alınır?

Microsoft. Identity.Web çeşitli belirteç türlerini önbelleğe alır:

Belirteç Türü Boyut Scope Tahliye
Erişim Belirteçleri Yaklaşık 2 KB Başına (kullanıcı/uygulama, kiracı, kaynak) Otomatik (yaşam süresi tabanlı)
Belirteçleri Yenile Variable Kullanıcı hesabı başına Manuel veya politika tabanlı
Kimlik Belirteçleri ~2-7 KB Kullanıcı başına Automatic

Belirteç önbelleğe alma işleminin geçerli olduğu yer:

Belirteçler neden önbelleğe alınır?

Performans Avantajları:

  • Microsoft Entra ID gidiş dönüşlerini azaltır
  • Daha hızlı API çağrıları (L1: <10ms vs L2: ~30ms vs ağ: >100ms)
  • Son kullanıcılar için daha düşük gecikme süresi

Güvenilirlik Avantajları:

  • Geçici Microsoft Entra kesintileri sırasında çalışmaya devam eder
  • Ağ dalgalanmalarına dayanıklı
  • Dağıtılmış önbellek başarısız olduğunda düzgün performans düşüşü

Maliyet Avantajları:

  • Kimlik doğrulama isteklerini azaltır (darboğazdan kaçınma)
  • Kimlik doğrulama işlemleri için daha düşük Azure maliyetleri

Hızlı Başlangıç

Ortamınıza bağlı olarak aşağıdaki önbellek yapılandırmalarından biriyle hızlı bir şekilde çalışmaya başlayın.

Geliştirme - bellek içi önbellek

Aşağıdaki örnek, geliştirme ve örnekler için uygun bir bellek içi belirteç önbelleği ekler:

using Microsoft.Identity.Web;

builder.Services.AddMicrosoftIdentityWebAppAuthentication(builder.Configuration, "AzureAd")
    .EnableTokenAcquisitionToCallDownstreamApi()
    .AddInMemoryTokenCaches();

Avantajlar:

  • Basit kurulum
  • Hızlı performans
  • Dış bağımlılık yok

Dezavantaj -ları:

  • Uygulama yeniden başlatıldığında önbellek kayboldu. Bir web uygulamasında, kullanıcılar tanımlama bilgisi aracılığıyla oturum açmış durumda kalır, ancak erişim belirteci almak ve önbelleği yeniden doldurmaları için yeniden oturum açmaları gerekir
  • Çok sunuculu üretim dağıtımları için uygun değildir
  • Uygulama örnekleri arasında paylaşılmaz

Üretim - dağıtılmış önbellek

Üretim uygulamaları, özellikle de çok sunuculu dağıtımlar için Redis veya başka bir sağlayıcı tarafından desteklenen dağıtılmış bir önbellek kullanın:

using Microsoft.Identity.Web;

builder.Services.AddMicrosoftIdentityWebAppAuthentication(builder.Configuration, "AzureAd")
    .EnableTokenAcquisitionToCallDownstreamApi()
    .AddDistributedTokenCaches();

// Choose your cache implementation
builder.Services.AddStackExchangeRedisCache(options =>
{
    options.Configuration = builder.Configuration.GetConnectionString("Redis");
    options.InstanceName = "MyApp_";
});

Avantajlar:

  • Uygulama yeniden başlatmalarında hayatta kalır
  • Tüm uygulama örnekleri arasında paylaşıldı
  • Otomatik L1+L2 önbelleğe alma

Dezavantaj -ları:

  • Dış önbellek altyapısı gerektirir
  • Ek yapılandırma karmaşıklığı
  • Önbellek işlemleri için ağ gecikme süresi

Önbellek stratejisi seçme

Dağıtımınıza en uygun önbellek stratejisini seçmek için aşağıdaki karar akış çizelgesini ve matrisi kullanın.

flowchart TD
    Start([Token Caching<br/>Decision]) --> Q1{Production<br/>Environment?}

    Q1 -->|No - Dev/Test| DevChoice[In-Memory Cache<br/>AddInMemoryTokenCaches]
    Q1 -->|Yes| Q2{Multiple Server<br/>Instances?}

    Q2 -->|No - Single Server| Q3{App Restarts<br/>Acceptable?}
    Q3 -->|Yes| DevChoice
    Q3 -->|No| DistChoice

    Q2 -->|Yes| DistChoice[Distributed Cache<br/>AddDistributedTokenCaches]

    DistChoice --> Q4{Cache<br/>Implementation?}

    Q4 -->|High Performance| Redis[Redis Cache<br/>StackExchange.Redis<br/>⭐ Recommended]
    Q4 -->|Azure Native| Azure[Azure Cache for Redis,<br/>Azure Cosmos DB,<br/>or Azure Database for PostgreSQL]
    Q4 -->|On-Premises| SQL[SQL Server Cache<br/>AddDistributedSqlServerCache]
    Q4 -->|Testing| DistMem[Distributed Memory<br/>Not for production]

    Redis --> L1L2[Automatic L1+L2<br/>Caching]
    Azure --> L1L2
    SQL --> L1L2
    DistMem --> L1L2

    L1L2 --> Config[Configure Options<br/>MsalDistributedTokenCacheAdapterOptions]
    DevChoice --> MemConfig[Configure Memory Options<br/>MsalMemoryTokenCacheOptions]

    style Start fill:#e1f5ff
    style DevChoice fill:#d4edda
    style DistChoice fill:#fff3cd
    style Redis fill:#d1ecf1
    style L1L2 fill:#f8d7da

Karar matrisi

Aşağıdaki tabloda, yaygın dağıtım senaryoları için önerilen önbellek türleri özetlenmiştir.

Scenario Önerilen Önbellek Gerekçe
Yerel geliştirme In-Memory Basitlik, altyapı gerekmez
Örnekler/tanıtımlar In-Memory Tanıtımlar için kolay kurulum
Tek sunuculu üretim (Yeniden başlatmalar uygun) In-Memory Oturumlar yeniden kurulabiliyorsa kabul edilebilir
Çok sunuculu üretim Redis Paylaşılan önbellek, yüksek performanslı, güvenilir
Azure barındırılan uygulamalar Redis için Azure Önbellek (Redis için Azure Önbelleği) Yerel Azure tümleştirmesi, yönetilen hizmet
Şirket içi kuruluş SQL Server Mevcut altyapıdan yararlanıyor
PostgreSQL ortamları PostgreSQL Mevcut PostgreSQL veritabanını, tanıdık SQL semantiğini kullanır
Yüksek güvenlikli ortamlar SQL Server + Şifreleme Veri yerleşimi, dinamik olmayan veri şifrelemesi
Dağıtılmış senaryoları test etme Dağıtılmış Bellek Altyapı olmadan L2 önbellek davranışını test etme

Önbellek uygulamaları

Microsoft. Identity.Web çeşitli önbellek uygulamalarını destekler. Altyapı ve kullanılabilirlik gereksinimlerinizle eşleşen bir tane seçin.

Bellek içi önbellek

Ne zaman kullanılır:

  • Geliştirme ve test
  • Kabul edilebilir yeniden başlatma davranışına sahip tek sunuculu dağıtımlar
  • Örnekler ve prototipler

Configuration:

Aşağıdaki kod, bellek içi belirteç önbelleğini varsayılan ayarlarla kaydeder:

builder.Services.AddMicrosoftIdentityWebAppAuthentication(builder.Configuration, "AzureAd")
    .EnableTokenAcquisitionToCallDownstreamApi()
    .AddInMemoryTokenCaches();

Özel seçeneklerle:

Süre sonu ve boyut sınırlarını seçenekleri geçirerek özelleştirebilirsiniz:

builder.Services.AddMicrosoftIdentityWebAppAuthentication(builder.Configuration, "AzureAd")
    .EnableTokenAcquisitionToCallDownstreamApi()
    .AddInMemoryTokenCaches(options =>
    {
        // Token cache entry will expire after this duration
        options.AbsoluteExpirationRelativeToNow = TimeSpan.FromHours(1);

        // Limit cache size (default is unlimited)
        options.SizeLimit = 500 * 1024 * 1024; // 500 MB
    });

→ Bellek içi önbellek yapılandırması hakkında daha fazla bilgi edinin


Otomatik L1 desteğine sahip dağıtılmış önbellek (L2)

Ne zaman kullanılır:

  • Çok sunuculu üretim dağıtımları
  • Yeniden başlatmalar arasında önbellek kalıcılığı gerektiren uygulamalar
  • Yüksek kullanılabilirlik senaryoları

Ana özellik: Microsoft.Identity.Web v1.8.0'dan itibaren, dağıtılmış önbellek, performans ve güvenilirliği artırmak amacıyla otomatik olarak bir bellek içi L1 önbelleği içerir.

Redis bağlantı dizesini appsettings.json'a ekleyin.

{
  "ConnectionStrings": {
    "Redis": "localhost:6379"
  }
}

Ardından dağıtılmış belirteç önbelleğini ve Redis sağlayıcısını Program.cs kaydedin:

using Microsoft.Identity.Web;
using Microsoft.Identity.Web.TokenCacheProviders.Distributed;

builder.Services.AddMicrosoftIdentityWebAppAuthentication(builder.Configuration, "AzureAd")
    .EnableTokenAcquisitionToCallDownstreamApi()
    .AddDistributedTokenCaches();

// Redis cache implementation
builder.Services.AddStackExchangeRedisCache(options =>
{
    options.Configuration = builder.Configuration.GetConnectionString("Redis");
    options.InstanceName = "MyApp_"; // Unique prefix per application
});

// Optional: Configure distributed cache behavior
builder.Services.Configure<MsalDistributedTokenCacheAdapterOptions>(options =>
{
    // Control L1 cache size
    options.L1CacheOptions.SizeLimit = 500 * 1024 * 1024; // 500 MB

    // Handle L2 cache failures gracefully
    options.OnL2CacheFailure = (exception) =>
    {
        if (exception is StackExchange.Redis.RedisConnectionException)
        {
            // Log the failure
            // Optionally attempt reconnection
            return true; // Retry the operation
        }
        return false; // Don't retry
    };
});

Redis için Azure Önbellek (Redis için Azure Önbelleği)

Redis için Azure Önbellek kullanmak için, önbelleği Azure bağlantı dizesi ile kaydedin.

builder.Services.AddStackExchangeRedisCache(options =>
{
    options.Configuration = builder.Configuration.GetConnectionString("AzureRedis");
    options.InstanceName = "MyApp_";
});

Bağlantı dizesinin biçimi:

<cache-name>.redis.cache.windows.net:6380,password=<access-key>,ssl=True,abortConnect=False

SQL Server önbelleği

Aşağıdaki örnek, SQL Server dağıtılmış önbellek arka ucu olarak yapılandırır:

builder.Services.AddDistributedSqlServerCache(options =>
{
    options.ConnectionString = builder.Configuration.GetConnectionString("TokenCacheDb");
    options.SchemaName = "dbo";
    options.TableName = "TokenCache";

    // Set expiration longer than access token lifetime (default 1 hour)
    // This prevents cache entries from expiring before tokens
    options.DefaultSlidingExpiration = TimeSpan.FromMinutes(90);
});

Azure Cosmos DB önbelleği

Aşağıdaki örnek, Azure Cosmos DB dağıtılmış önbellek arka ucu olarak yapılandırır:

builder.Services.AddCosmosCache((CosmosCacheOptions options) =>
{
    options.ContainerName = builder.Configuration["CosmosCache:ContainerName"];
    options.DatabaseName = builder.Configuration["CosmosCache:DatabaseName"];
    options.ClientBuilder = new CosmosClientBuilder(
        builder.Configuration["CosmosCache:ConnectionString"]);
    options.CreateIfNotExists = true;
});

PostgreSQL önbelleği

Microsoft.Extensions.Caching.Postgres NuGet paketini gerektirir.

appsettings.json:

{
  "ConnectionStrings": {
    "PostgresCache": "Host=localhost;Database=mydb;Username=myuser;Password=mypassword"
  },
  "PostgresCache": {
    "SchemaName": "public",
    "TableName": "token_cache",
    "CreateIfNotExists": true
  }
}

Ardından PostgreSQL önbelleğini Program.cs kaydedin:

builder.Services.AddDistributedPostgresCache(options =>
{
    options.ConnectionString = builder.Configuration.GetConnectionString("PostgresCache");
    options.SchemaName = builder.Configuration["PostgresCache:SchemaName"];
    options.TableName = builder.Configuration["PostgresCache:TableName"];
    options.CreateIfNotExists = builder.Configuration.GetValue<bool>("PostgresCache:CreateIfNotExists");
    options.DefaultSlidingExpiration = TimeSpan.FromMinutes(90);
});

→ Dağıtılmış önbellek yapılandırması hakkında daha fazla bilgi edinin


Dikkat

Oturum tabanlı önbelleğe almanın önemli sınırlamaları vardır. Bunun yerine dağıtılmış önbellek kullanın.

Aşağıdaki örnek, referans olarak oturum tabanlı token önbelleğe almayı göstermektedir.

using Microsoft.Identity.Web.TokenCacheProviders.Session;

// In Program.cs
builder.Services.AddSession();

builder.Services.AddMicrosoftIdentityWebAppAuthentication(builder.Configuration, "AzureAd")
    .EnableTokenAcquisitionToCallDownstreamApi()
    .AddSessionTokenCaches();

// In middleware pipeline
app.UseSession(); // Must be before UseAuthentication()
app.UseAuthentication();
app.UseAuthorization();

Limitations:

  • Çerez boyutu sorunları - Birçok iddiaya sahip büyük kimlik belirteçleri sorunlara neden oluyor
  • Scope çakışmaları - singleton TokenAcquisition (örneğin, Microsoft Graph SDK) ile kullanılamaz
  • Oturum bağımlılığı gerekli - Yük dengeleme senaryolarında iyi çalışmaz
  • Önerilmez - Bunun yerine dağıtılmış önbellek kullanın

Gelişmiş yapılandırma

Bu seçenekler performans, güvenlik ve çıkarma ilkeleri için önbellek davranışında ince ayar yapmanızı olanaklı kılar.

L1 önbellek denetimi

L1 (bellek içi) önbelleği, dağıtılmış önbellekleri kullandığınızda performansı artırır. Aşağıdaki kod L1 önbellek boyutunu ve davranışını yapılandırır:

builder.Services.Configure<MsalDistributedTokenCacheAdapterOptions>(options =>
{
    // Control L1 cache size (default: 500 MB)
    options.L1CacheOptions.SizeLimit = 100 * 1024 * 1024; // 100 MB

    // Disable L1 cache if session affinity is not available
    // (forces all requests to use L2 cache for consistency)
    options.DisableL1Cache = false;
});

L1 ne zaman devre dışı bırakılır:

  • Yük dengeleyicide oturum bağımlılığı yok
  • Önbellek tutarsızlığı nedeniyle kullanıcılardan sık sık MFA istenir
  • Takas: L2 erişimi daha yavaş (~30 ms karşısında ~10 ms)

Önbellek çıkarma ilkeleri

Çıkarma ilkeleri, önbelleğe alınan belirteçlerin ne zaman kaldırıldığını denetler. Aşağıdaki kod mutlak ve kayan süre sonunu ayarlar:

builder.Services.Configure<MsalDistributedTokenCacheAdapterOptions>(options =>
{
    // Absolute expiration (removed after this time, regardless of use)
    options.AbsoluteExpirationRelativeToNow = TimeSpan.FromHours(72);

    // Sliding expiration (renewed on each access)
    options.SlidingExpiration = TimeSpan.FromHours(2);
});

Çıkarmayı appsettings.jsonaracılığıyla da yapılandırabilirsiniz:

{
  "TokenCacheOptions": {
    "AbsoluteExpirationRelativeToNow": "72:00:00",
    "SlidingExpiration": "02:00:00"
  }
}
builder.Services.Configure<MsalDistributedTokenCacheAdapterOptions>(
    builder.Configuration.GetSection("TokenCacheOptions"));

Öneriler:

  • Süre sonunu belirteç ömründen daha uzun olarak ayarlayın (belirteçlerin süresi genellikle 1 saat içinde dolar)
  • Varsayılan: 90 dakika kayan zaman aşımı süresi
  • Bellek kullanımı ile kullanıcı deneyimi arasında denge
  • Göz önünde bulundurun: İyi bir UX için 72 saat kesin + 2 saat esnek

→ Önbellek çıkarma stratejileri hakkında daha fazla bilgi edinin


Atıl durumdaki şifreleme

Dağıtılmış önbelleklerdeki hassas belirteç verilerini korumak için ASP.NET Core Veri Koruması aracılığıyla şifrelemeyi etkinleştirin.

Tek bir makine

Tek bir makinede yerleşik Veri Koruma sağlayıcısıyla şifrelemeyi etkinleştirin:

builder.Services.Configure<MsalDistributedTokenCacheAdapterOptions>(options =>
{
    options.Encrypt = true; // Uses ASP.NET Core Data Protection
});

Dağıtılmış sistemler (birden çok sunucu)

Önemli

Dağıtılmış sistemler varsayılan olarak şifreleme anahtarlarını paylaşmaz . Anahtar paylaşımını yapılandırmanız gerekir:

Azure Key Vault (önerilir):

Aşağıdaki kod, anahtarları Azure Blob Depolama'a kalıcı olarak depolar ve Azure Key Vault ile koruma altına alır.

using Microsoft.AspNetCore.DataProtection;

builder.Services.AddDataProtection()
    .PersistKeysToAzureBlobStorage(new Uri(builder.Configuration["DataProtection:BlobUri"]))
    .ProtectKeysWithAzureKeyVault(
        new Uri(builder.Configuration["DataProtection:KeyIdentifier"]),
        new DefaultAzureCredential());

Sertifika tabanlı:

Aşağıdaki kod, anahtarları bir dosya paylaşımında kalıcı hale getirerek X.509 sertifikasıyla korur:

builder.Services.AddDataProtection()
    .PersistKeysToFileSystem(new DirectoryInfo(@"\\server\share\keys"))
    .ProtectKeysWithCertificate(
        new X509Certificate2("current.pfx", builder.Configuration["CertPassword"]))
    .UnprotectKeysWithAnyCertificate(
        new X509Certificate2("current.pfx", builder.Configuration["CertPassword"]),
        new X509Certificate2("previous.pfx", builder.Configuration["PrevCertPassword"]));

→ Şifreleme ve veri koruması hakkında daha fazla bilgi edinin


Önbellek performansıyla ilgili dikkat edilmesi gerekenler

Uygulamanız için önbellek kapasitesini planlamak için aşağıdaki tahminleri kullanın.

Belirteç boyutu tahminleri

Belirteç Türü Tipik Boyut Başına Notlar
Uygulama belirteçleri Yaklaşık 2 KB Kiracı × Kaynak Otomatik çıkarılmış
Kullanıcı belirteçleri ~7 KB Kullanıcı × Kiracı × Kaynağı Elle tahliye gerekiyor
Belirteçleri yenileme Variable User Uzun ömürlü

Bellek planlaması

3 API'yiçağıran 500 eşzamanlı kullanıcı için:

  • Kullanıcı belirteçleri: 500 × 3 × 7 KB = 10,5 MB
  • Ek yük ile: ~15-20 MB

10.000 eşzamanlı kullanıcı için:

  • Kullanıcı belirteçleri: 10.000 × 3 × 7 KB = 210 MB
  • Ek yük ile: ~300-350 MB

Öneri: L1 önbellek boyutu sınırını beklenen eşzamanlı kullanıcılara göre ayarlayın.

En iyi uygulamalar

Güvenilir ve verimli belirteç önbelleğe alma sağlamak için bu yönergeleri izleyin.

Üretimde dağıtılmış önbellek kullanma - Çok sunuculu dağıtımlar için temel

Uygun önbellek boyutu sınırlarını ayarlama - İlişkisiz bellek büyümesini önleme

Çıkarma ilkelerini yapılandırma - UX ve bellek kullanımını dengeleme

Hassas veriler için şifrelemeyi etkinleştirme - Durumda olan belirteçleri koruma

Önbellek durumunu izleme - İsabet oranlarını, hataları ve performansı izleme

L2 önbellek hatalarını düzgün bir şekilde işleme - L1 önbelleği dayanıklılığı sağlar

Önbellek davranışını test et - Yeniden başlatma senaryolarını ve yük devretmeyi doğrulama

Üretimde dağıtılmış bellek önbelleği kullanma - Kalıcı veya dağıtılmış değil

Oturum önbelleğini kullanma - Önemli sınırlamaları vardır

Jeton ömründen daha kısa bir süre sonu ayarlamayın - Gereksiz yeniden kimlik doğrulamayı zorlar

Şifreleme anahtarı paylaşımını unutmayın - Dağıtılmış sistemlerin paylaşılan anahtarlara ihtiyacı var