Tokencache in Microsoft. Identity.Web

Tokencaching verbetert de prestaties, betrouwbaarheid en gebruikerservaring van toepassingen. Microsoft. Identity.Web biedt flexibele cachestrategieën die de prestaties, persistentie en operationele betrouwbaarheid in balans brengt.

Overzicht

Deze sectie beschrijft welke tokens Microsoft.Identity.Web cachet en waarom caching belangrijk is voor uw applicatie.

Welke tokens worden in de cache opgeslagen?

Microsoft. Identity.Web slaat verschillende typen tokens in de cache op:

Token type Grootte Scope Uitzetting
Toegangstokens ~2 kB Per (gebruiker/app, tenant, resource) Automatisch (op basis van levensduur)
Tokens vernieuwen Variable Per gebruikersaccount Handmatig of op beleid gebaseerd
Id-tokens ~2-7 KB Per gebruiker Automatisch

Waar tokencaching van toepassing is:

Waarom cachetokens?

Prestatievoordelen:

  • Vermindert retouren naar Microsoft Entra ID
  • Snellere API-aanroepen (L1: <10ms vs L2: ~30ms vs network: >100ms)
  • Lagere latentie voor eindgebruikers

Voordelen van betrouwbaarheid:

  • Blijft werken tijdens tijdelijke Microsoft Entra storingen
  • Tolerant voor netwerktransients
  • Probleemloze degradatie wanneer gedistribueerde cache mislukt

Kostenvoordelen:

  • Vermindert authenticatieverzoeken (vermijding van beperking)
  • Lagere Azure kosten voor verificatiebewerkingen

Quickstart

Ga snel aan de slag met een van de volgende cacheconfiguraties, afhankelijk van uw omgeving.

Ontwikkeling - cache in het geheugen

In het volgende voorbeeld wordt een tokencache in het geheugen toegevoegd, geschikt voor ontwikkeling en voorbeelden:

using Microsoft.Identity.Web;

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

Voordelen:

  • Eenvoudige instellingen
  • Snelle prestaties
  • Geen externe afhankelijkheden

Nadelen:

  • Cache is verloren bij het opnieuw opstarten van de app. In een web-app blijven gebruikers aangemeld via de cookie, maar moeten ze zich opnieuw aanmelden om een toegangstoken op te halen en de cache opnieuw te vullen
  • Niet geschikt voor productieimplementaties met meerdere servers
  • Niet gedeeld tussen applicatie-instanties

Productie - gedistribueerde cache

Gebruik voor productietoepassingen, met name implementaties met meerdere servers, een gedistribueerde cache die wordt ondersteund door Redis of een andere provider:

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

Voordelen:

  • Overleeft het opnieuw opstarten van de app
  • Gedeeld door alle applicatie-instanties
  • Automatische L1+L2-caching

Nadelen:

  • Externe cache-infrastructuur vereist
  • Aanvullende configuratiecomplexiteit
  • Netwerklatentie voor cachebewerkingen

Een cachestrategie kiezen

Gebruik het volgende beslissingsstroomdiagram en de volgende matrix om de cachestrategie te selecteren die het beste bij uw implementatie past.

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

Beslissingsmatrix

De volgende tabel bevat een overzicht van aanbevolen cachetypen voor veelvoorkomende implementatiescenario's.

Scenario Aanbevolen cache Onderbouwing
Lokale ontwikkeling In-Memory Eenvoud, geen infrastructuur nodig
Voorbeelden/demo's In-Memory Eenvoudige installatie voor demonstraties
Productie met één server (herstarten OK) In-Memory Acceptabel als sessies opnieuw kunnen worden ingesteld
Productie met meerdere servers Redis Gedeelde cache, hoge prestaties, betrouwbaar
Azure gehoste toepassingen Azure Cache voor Redis Systeemeigen Azure-integratie, beheerde service
Lokale onderneming SQL Server Maakt gebruik van bestaande infrastructuur
PostgreSQL-omgevingen PostgreSQL Maakt gebruik van bestaande PostgreSQL-database, vertrouwde SQL-semantiek
Omgevingen met hoge beveiliging SQL Server + versleuteling Gegevensresidentie, versleuteling van gegevens in rusttoestand
Gedistribueerde scenario's testen Gedistribueerd geheugen Test L2-cachegedrag zonder infrastructuur

Cache-implementaties

Microsoft. Identity.Web ondersteunt verschillende cache-implementaties. Kies de optie die overeenkomt met uw infrastructuur- en beschikbaarheidsvereisten.

Cache in het geheugen

Wanneer te gebruiken:

  • Ontwikkeling en testen
  • Implementaties met één server met acceptabel gedrag voor opnieuw opstarten
  • Voorbeelden en prototypen

Configuration:

Met de volgende code wordt de cache van het token in het geheugen geregistreerd met standaardinstellingen:

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

Met aangepaste opties:

U kunt de verloop- en groottelimieten aanpassen door opties door te geven:

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

→ Meer informatie over cacheconfiguratie in het geheugen


Gedistribueerde cache (L2) met automatische L1-ondersteuning

Wanneer te gebruiken:

  • Productieimplementaties met meerdere servers
  • Toepassingen waarvoor cachepersistentie nodig is tijdens het opnieuw opstarten
  • Scenario's voor hoge beschikbaarheid

Sleutelfunctie: Sinds Microsoft. Identity.Web v1.8.0, de gedistribueerde cache bevat automatisch een L1-cache in het geheugen voor prestaties en betrouwbaarheid.

Voeg de Redis-verbindingsreeks toe aan appsettings.json:

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

Registreer vervolgens de gedistribueerde tokencache en Redis-provider in 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 voor Redis

Als u Azure Cache voor Redis wilt gebruiken, registreert u de cache bij uw Azure verbindingsreeks:

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

Indeling van verbindingsreeks:

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

SQL Server cache

In het volgende voorbeeld wordt SQL Server geconfigureerd als de back-end van de gedistribueerde cache:

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 cache

In het volgende voorbeeld wordt Azure Cosmos DB geconfigureerd als de back-end van de gedistribueerde cache:

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-cache

Vereist het NuGet-pakket Microsoft.Extensions.Caching.Postgres.

appsettings.json:

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

Registreer vervolgens de PostgreSQL-cache in 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);
});

→ Meer informatie over configuratie van gedistribueerde cache


Waarschuwing

Caching op basis van sessies heeft aanzienlijke beperkingen. Gebruik in plaats daarvan een gedistribueerde cache.

In het volgende voorbeeld ziet u cacheopslag van tokens op basis van sessies ter referentie:

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:

  • Problemen met cookiegrootte - Grote ID-tokens met veel claims veroorzaken problemen
  • Scope-conflicten - Kan niet worden gebruikt met singleton TokenAcquisition (bijvoorbeeld Microsoft Graph SDK)
  • Sessieaffiniteit vereist : werkt niet goed in scenario's met gelijke taakverdeling
  • Niet aanbevolen - In plaats daarvan gedistribueerde cache gebruiken

Geavanceerde configuratie

Met deze opties kunt u het cachegedrag verfijnen voor prestatie-, beveiligings- en verwijderingsbeleid.

L1-cachebeheer

De L1-cache (in-memory) verbetert de prestaties wanneer u gedistribueerde caches gebruikt. Met de volgende code wordt de grootte en het gedrag van de L1-cache geconfigureerd:

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

Wanneer moet u L1 uitschakelen:

  • Geen sessieaffiniteit in de load balancer
  • Gebruikers worden vaak om MFA gevraagd vanwege inconsistentie in de cache
  • Afweging: L2-toegang is langzamer (~30 ms versus ~10 ms)

Verwijderingsbeleid voor cache

Het verwijderingsbeleid bepaalt wanneer tokens in de cache worden verwijderd. Met de volgende code worden absolute en verschuivende vervaldatum ingesteld:

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

U kunt verwijdering ook configureren via appsettings.json:

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

Aanbevelingen:

  • Verlooptijd langer instellen dan de levensduur van tokens (tokens verlopen doorgaans in 1 uur)
  • Standaard: 90 minuten verschuivende verlooptijd
  • Balans tussen geheugengebruik en gebruikerservaring
  • Overweeg: 72 uur absoluut + 2 uur schuiven voor goede UX

→ Meer informatie over verwijderingsstrategieën voor cache


Versleuteling van opgeslagen data

Als u gevoelige tokengegevens in gedistribueerde caches wilt beveiligen, schakelt u versleuteling in via ASP.NET Core Gegevensbeveiliging.

Enkele machine

Schakel op één computer versleuteling in met de ingebouwde provider voor gegevensbeveiliging:

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

Gedistribueerde systemen (meerdere servers)

Belangrijk

Gedistribueerde systemen delen standaard geen versleutelingssleutels. U moet sleuteldeling configureren:

Azure Key Vault (aanbevolen):

Met de volgende code blijven sleutels behouden voor Azure Blob Storage en worden deze beveiligd met 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());

Op basis van certificaten:

De volgende code bewaart sleutels voor een bestandsshare en beveiligt deze met een X.509-certificaat:

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

→ Meer informatie over versleuteling en gegevensbeveiliging


Overwegingen voor cacheprestaties

Gebruik de volgende schattingen om de cachecapaciteit voor uw toepassing te plannen.

Schattingen van tokengrootte

Token type Typische grootte Per Aantekeningen
App-tokens ~2 kB Tenant ×-resource Automatisch verwijderd
Gebruikerstokens ~7 kB Gebruiker × Tenant × Resource Handmatige uitdrijving nodig
Vernieuwen van tokens Variable Gebruiker Langlevend

Geheugenplanning

Voor 500 gelijktijdige gebruikers die 3 API's aanroepen:

  • Gebruikerstokens: 500 × 3 × 7 KB = 10,5 MB
  • Met overhead: ~15-20 MB

Voor 10.000 gelijktijdige gebruikers:

  • Gebruikerstokens: 10.000 × 3 × 7 KB = 210 MB
  • Met overhead: ~300-350 MB

Aanbeveling: Stel de limiet voor L1-cachegrootte in op basis van verwachte gelijktijdige gebruikers.

Beste praktijken

Volg deze richtlijnen om betrouwbare en efficiënte tokencaching te garanderen.

Gedistribueerde cache gebruiken in productie - Essentieel voor implementaties met meerdere servers

De juiste cachegroottelimieten instellen - Niet-gebonden geheugengroei voorkomen

Verwijderingsbeleid configureren - UX- en geheugengebruik verdelen

Versleuteling inschakelen voor gevoelige gegevens - tokens in rust beveiligen

Cachestatus bewaken : trefferpercentages, fouten en prestaties bijhouden

L2-cachefouten correct afhandelen - L1-cache zorgt voor tolerantie

Cachegedrag testen - Scenario's voor opnieuw opstarten en failover controleren

Gebruik geen gedistribueerde geheugencache in productie : niet permanent of gedistribueerd

Gebruik geen sessiecache - heeft aanzienlijke beperkingen

Stel de verlooptijd niet korter in dan de levensduur van het token - Dwingt onnodige herverificatie af

Vergeet het delen van versleutelingssleutels niet : gedistribueerde systemen hebben gedeelde sleutels nodig