Mezipaměť tokenů v Microsoft Identity.Web

Ukládání tokenů do mezipaměti zlepšuje výkon, spolehlivost a uživatelské prostředí aplikací. Microsoft. Identity.Web poskytuje flexibilní strategie ukládání do mezipaměti, které vyrovnává výkon, trvalost a provozní spolehlivost.

Přehled

Tato část popisuje, které tokeny Microsoft. Identity.Web ukládá do mezipaměti a proč je ukládání do mezipaměti pro vaši aplikaci důležité.

Jaké tokeny se ukládají do mezipaměti?

Microsoft. Identity.Web ukládá do mezipaměti několik typů tokenů:

Typ tokenu Velikost Scope Vyřazování
Přístupové tokeny ~2 kB Na (uživatele/aplikaci, nájemce, prostředek) Automatická (založená na životnosti)
Obnovovací tokeny Proměnná Na uživatelský účet Ruční nebo na základě zásad
ID tokeny ~2–7 kB Na uživatele Automatické

Kde se používá ukládání tokenů do mezipaměti:

Proč tokeny mezipaměti?

Výhody výkonu:

  • Zkracuje dobu odezvy na Microsoft Entra ID
  • Rychlejší volání rozhraní API (L1: <10ms vs. L2: ~30ms vs. síť: >100 ms)
  • Nižší latence pro koncové uživatele

Výhody spolehlivosti:

  • Pokračuje v práci během dočasných výpadků Microsoft Entra
  • Odolné vůči přechodným síťovým objektům
  • Řádné snížení výkonu v případě selhání distribuované mezipaměti

Nákladové výhody:

  • Snižuje požadavky na ověřování (zabránění omezování)
  • Nižší Azure náklady na operace ověřování

Rychlý start

Začněte rychle s jednou z následujících konfigurací mezipaměti v závislosti na vašem prostředí.

Vývoj – mezipaměť v operační paměti

Následující příklad přidá mezipaměť tokenů v paměti, která je vhodná pro vývoj a ukázky:

using Microsoft.Identity.Web;

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

Výhody:

  • Jednoduché nastavení
  • Rychlý výkon
  • Žádné externí závislosti

Nevýhody:

  • Při restartování aplikace dojde ke ztrátě mezipaměti. Ve webové aplikaci zůstanou uživatelé přihlášení přes soubor cookie, ale musí se znovu přihlásit, aby získali přístupový token a znovu zaplní mezipaměť.
  • Není vhodné pro nasazení s více servery v produkčním prostředí.
  • Nesdílený mezi instancemi aplikace

Produkční – distribuovaná mezipaměť

Pro produkční aplikace, zejména nasazení s více servery, použijte distribuovanou mezipaměť zálohovanou Redisem nebo jiným poskytovatelem:

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

Výhody:

  • Přežije restartování aplikace.
  • Sdílené napříč všemi instancemi aplikace
  • Automatické ukládání do mezipaměti L1+L2

Nevýhody:

  • Vyžaduje infrastrukturu externí mezipaměti.
  • Další složitost konfigurace
  • Latence sítě pro operace mezipaměti

Volba strategie mezipaměti

Pomocí následujícího rozhodovacího vývojového diagramu a matice vyberte strategii mezipaměti, která nejlépe vyhovuje vašemu nasazení.

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

Rozhodovací matice

Následující tabulka shrnuje doporučené typy mezipaměti pro běžné scénáře nasazení.

Scénář Doporučená mezipaměť Odůvodnění
Místní vývoj In-Memory Jednoduchost, nevyžaduje se žádná infrastruktura
Ukázky/demoverze In-Memory Snadné nastavení pro ukázky
Provoz na jednom serveru (restarty jsou v pořádku) In-Memory Přijatelné, pokud je možné znovu navázat relace
Víceserverové produkční prostředí Redis Sdílená mezipaměť, vysoký výkon, spolehlivá
Azure hostované aplikace Azure Cache for Redis Nativní integrace Azure, spravovaná služba
Místní podnik SQL Server Využívá stávající infrastrukturu.
Prostředí PostgreSQL PostgreSQL Používá existující databázi PostgreSQL, známou sémantiku SQL.
Prostředí s vysokým zabezpečením SQL Server + šifrování Rezidence dat, šifrování neaktivních uložených dat
Testování distribuovaných scénářů Distribuovaná paměť Testuje chování mezipaměti L2 bez infrastruktury.

Implementace mezipaměti

Microsoft. Identity.Web podporuje několik implementací mezipaměti. Vyberte ten, který odpovídá vašim požadavkům na infrastrukturu a dostupnost.

Mezipaměť v operační paměti

Kdy použít:

  • Vývoj a testování
  • Jednoserverové nasazení s přijatelným chováním při restartu.
  • Ukázky a prototypy

Configuration:

Následující kód registruje mezipaměť tokenů v paměti s výchozím nastavením:

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

S vlastními možnostmi:

Limity vypršení platnosti a velikosti můžete přizpůsobit předáním možností:

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

→ Další informace o konfiguraci mezipaměti v paměti


Distribuovaná mezipaměť (L2) s automatickou podporou L1

Kdy použít:

  • Produkční nasazení s více servery
  • Aplikace vyžadující trvalost mezipaměti napříč restartováními
  • Scénáře s vysokou dostupností

Klíčová funkce: Od Microsoft. Identity.Web v1.8.0, distribuovaná mezipaměť automaticky obsahuje mezipaměť L1 v paměti pro výkon a spolehlivost.

Přidejte připojovací řetězec Redis do appsettings.json:

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

Pak zaregistrujte mezipaměť distribuovaných tokenů a poskytovatele Redis v Program.cs:

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

Azure Cache for Redis

Abyste mohli používat Azure Cache for Redis, zaregistrujte mezipaměť pomocí připojovací řetězec služby Azure.

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

Formát připojovacího řetězce:

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

mezipaměť SQL Server

Následující příklad nakonfiguruje SQL Server jako back-end distribuované mezipaměti:

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

mezipaměť Azure Cosmos DB

Následující příklad nakonfiguruje Azure Cosmos DB jako back-end distribuované mezipaměti:

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

Mezipaměť PostgreSQL

Vyžaduje balíček NuGet Microsoft.Extensions.Caching.Postgres.

appsettings.json:

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

Pak zaregistrujte mezipaměť PostgreSQL v Program.cs:

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

→ Další informace o konfiguraci distribuované mezipaměti


Upozornění

Ukládání do mezipaměti založené na relacích má významná omezení. Místo toho použijte distribuovanou mezipaměť.

Následující příklad ukazuje ukládání tokenů do mezipaměti založeného na relacích pro referenci:

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

Omezení:

  • Problémy s velikostí souborů cookie – Velké tokeny ID s mnoha deklaracemi identity způsobují problémy
  • Konflikty v rámci Scope – Nelze použít se TokenAcquisition singletonem (např. Microsoft Graph SDK)
  • Vyžaduje se spřažení relací – nefunguje dobře ve scénářích s vyrovnáváním zatížení
  • Nedoporučuje se – místo toho používejte distribuovanou mezipaměť.

Rozšířená konfigurace

Tyto možnosti umožňují doladit chování mezipaměti pro zásady výkonu, zabezpečení a vyřazení.

Řízení mezipaměti L1

Mezipaměť L1 (v paměti) zlepšuje výkon při použití distribuovaných mezipamětí. Následující kód konfiguruje velikost a chování mezipaměti L1:

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

Kdy zakázat L1:

  • V nástroji pro vyrovnávání zatížení není žádná vazba na relaci.
  • Uživatelé jsou často vyzýváni k vícefaktorovému ověřování kvůli nekonzistenci mezipaměti.
  • Kompromis: Přístup K L2 je pomalejší (~30ms vs. ~10ms)

Zásady vyřazení mezipaměti

Zásady vyřazení řídí, když jsou odebírány tokeny v mezipaměti. Následující kód nastaví absolutní a posuvné vypršení platnosti:

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

Vyřazení můžete nakonfigurovat také prostřednictvím appsettings.json:

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

Doporučení:

  • Nastavení vypršení platnosti delšího než životnost tokenu (platnost tokenů obvykle vyprší za 1 hodinu)
  • Výchozí hodnota: 90 minut posuvného vypršení platnosti
  • Vyvážení mezi využitím paměti a uživatelským prostředím
  • Zvažte: 72 hodin absolutní + 2 hodiny posuvné pro dobré uživatelské prostředí

→ Další informace o strategiích vyřazení mezipaměti


Šifrování v klidu

Pokud chcete chránit citlivá data tokenů v distribuovaných mezipamětí, povolte šifrování prostřednictvím služby ASP.NET Core Data Protection.

Jeden počítač

Na jednom počítači povolte šifrování pomocí integrovaného poskytovatele ochrany dat:

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

Distribuované systémy (více serverů)

Důležité

Distribuované systémy ve výchozím nastavení nesdílejí šifrovací klíče. Musíte nakonfigurovat sdílení klíčů:

Azure Key Vault (doporučeno):

Následující kód zachovává klíče Azure Blob Storage a chrání je pomocí Azure Key Vault:

using Microsoft.AspNetCore.DataProtection;

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

Založené na certifikátech:

Následující kód zachovává klíče do sdílené složky a chrání je certifikátem X.509:

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

→ Další informace o šifrování a ochraně dat


Aspekty výkonu mezipaměti

Pomocí následujících odhadů naplánujte kapacitu mezipaměti pro vaši aplikaci.

Odhady velikosti tokenů

Typ tokenu Typická velikost Na Poznámky
Tokeny aplikací ~2 kB Nájemce × Prostředek Automaticky vyřazeno
Uživatelské tokeny ~7 kB Uživatel × Tenanta × Prostředek Potřeba ručního vyřazení
Aktualizace tokenů Proměnná User Dlouho žijící

Plánování paměti

Pro 500 souběžných uživatelů , kteří volají 3 API:

  • Uživatelské tokeny: 500 × 3 × 7 kB = 10,5 MB
  • Režijní náklady: ~15–20 MB

Pro 10 000 souběžných uživatelů:

  • Uživatelské tokeny: 10 000 × 3 × 7 kB = 210 MB
  • Včetně režie: ~300–350 MB

Doporučení: Nastavte limit velikosti mezipaměti L1 na základě očekávaných souběžných uživatelů.

Osvědčené postupy

Pokud chcete zajistit spolehlivé a efektivní ukládání tokenů do mezipaměti, postupujte podle těchto pokynů.

Použití distribuované mezipaměti v produkčním prostředí – Základní pro nasazení s více servery

Nastavení vhodných limitů velikosti mezipaměti – Zabránění růstu nevázané paměti

Konfigurace zásad vyřazení – Vyrovnávání využití uživatelského rozhraní a paměti

Povolení šifrování citlivých dat – Ochrana neaktivních uložených tokenů

Monitorování stavu mezipaměti – Sledování zásahovosti, selhání a výkonu

Řešení selhání mezipaměti L2 elegantně – mezipaměť L1 zajišťuje rezilienci

Chování mezipaměti při testu – Ověřte scénáře restartu a failoveru

Nepoužívejte mezipaměť distribuované paměti v produkčním prostředí – není trvalá ani distribuovaná

Nepoužívat mezipaměť relací – má významná omezení

Nenastavujte vypršení platnosti kratší než životnost tokenu – Vynutí zbytečné opakované ověřování.

Nezapomeňte na sdílení šifrovacích klíčů – Distribuované systémy potřebují sdílené klíče.