Hinweis
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, sich anzumelden oder das Verzeichnis zu wechseln.
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, das Verzeichnis zu wechseln.
Dieser Artikel hilft Ihnen beim Diagnostizieren und Beheben von Tokencacheproblemen in Microsoft. Identity.Web. Tokencacheprobleme können Authentifizierungsfehler, beeinträchtigte Leistung oder unerwartete Anmeldeaufforderungen verursachen. Eine Übersicht darüber, wie das Zwischenspeichern von Token in Microsoft funktioniert. Identity.Web finden Sie unter Token cache overview.
Voraussetzungen
Bestätigen Sie vor der Problembehandlung Folgendes:
- Sie verwenden eine unterstützte Version von Microsoft. Identity.Web.
- Ihre Anwendung hat das Zwischenspeichern von Token konfiguriert in
Program.csoderStartup.cs. - Sie haben Zugriff auf Anwendungsprotokolle und gegebenenfalls Ihre verteilte Cacheinfrastruktur.
Aktivieren der Token-Cache-Protokollierung und -diagnose
Aktivieren Sie die detaillierte Protokollierung als ersten Diagnoseschritt. Microsoft. Identity.Web verwendet die ASP.NET Core Protokollierungsinfrastruktur und gibt Ereignisse über die Microsoft Authentication Library (MSAL) (MSAL) aus.
Aktivieren der MSAL-Protokollierung
Legen Sie die Protokollebene für die Identitätsbibliotheken in Ihrem appsettings.json fest.
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.Identity.Web": "Debug",
"Microsoft.IdentityModel": "Debug"
}
}
}
MSAL-Cache-Ereignisse abonnieren
Abonnieren Sie MSAL-Tokencachebenachrichtigungsereignisse, um Cachetreffer, Fehler und Serialisierungsaktivitäten nachzuverfolgen:
services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme)
.AddMicrosoftIdentityWebApp(Configuration)
.EnableTokenAcquisitionToCallDownstreamApi()
.AddDistributedTokenCaches();
services.Configure<MsalDistributedTokenCacheAdapterOptions>(options =>
{
options.OnL2CacheFailure = (ex) =>
{
logger.LogWarning(ex, "L2 cache failure encountered.");
// Return true to allow the operation to continue despite the cache failure.
// Return false to propagate the exception.
return true;
};
});
Überwachen von Cachemetriken
Verfolgen Sie für die Produktionsüberwachung die folgenden wichtigen Metriken:
- Cachetrefferrate – eine niedrige Trefferrate gibt an, dass Token nicht aus dem Cache abgerufen werden.
- L2-Cachelatenz – hohe Latenz schlägt ein Problem mit verteilter Cachekonnektivität oder Leistung vor.
- Fehler bei der Cache serialisierung – Fehler beim Lesen oder Schreiben deuten auf Beschädigungen oder Versionskonflikt hin.
- Speicherverbrauch – ein anhaltendes Wachstum kann auf fehlende Vertreibungsrichtlinien hinweisen.
Verbindungsfehler für verteilten Cache (L2)
Symptom
Anwendungsprotokolle zeigen Verbindungstimeoutfehler oder zeitweilige Authentifizierungsfehler an. Benutzer haben Anmeldeverzögerungen, und Es werden Ausnahmen angezeigt, z. B.:
Microsoft.Extensions.Caching.StackExchangeRedis.RedisCache:
StackExchange.Redis.RedisConnectionException:
No connection is active/available to service this operation.
Oder für SQL Server verteilten Cache:
Microsoft.Data.SqlClient.SqlException:
A network-related or instance-specific error occurred while
establishing a connection to SQL Server.
Ursache
Der verteilte Cachesicherungsspeicher (Redis oder SQL Server) ist nicht erreichbar. Häufige Ursachen sind:
- Falsche Verbindungszeichenfolge oder abgelaufene Zugriffsanmeldeinformationen.
- Netzwerkfirewallregeln blockieren die Verbindung vom App-Host.
- Der Cachedienst ist ausgefallen oder wird gewartet.
- SSL/TLS-Konfigurationskonflikt zwischen Client und Cacheserver.
Schritte zum Diagnostizieren von Problemen
Führen Sie die folgenden Schritte aus, um den Verbindungsfehler zu identifizieren:
- Überprüfen Sie die Konnektivität. Testen Sie vom Anwendungshost die Verbindung mit Redis oder SQL Server mithilfe von
Test-NetConnection(PowerShell) oderredis-cli. - Überprüfen Sie die Verbindungszeichenfolge. Bestätigen Sie, dass die Verbindungszeichenfolge mit dem Hostnamen, Port und Anmeldeinformationen des Cacheservers übereinstimmt.
- Überprüfen Sie Firewallregeln. Stellen Sie in Azure sicher, dass der App-Dienst oder das virtuelle Netzwerk die Cacheressource erreichen kann.
- Prüfen des Dienststatus. Überprüfen Sie im Azure-Portal die Integrität und Metriken Ihrer Azure Cache for Redis- oder SQL-Datenbankinstanz.
Lösung
Step 1: Korrigieren Sie die Verbindungszeichenfolge
Überprüfen Sie die Verbindungszeichenfolge in Ihrer appsettings.json:
{
"ConnectionStrings": {
"Redis": "your-redis-instance.redis.cache.windows.net:6380,password=your-access-key,ssl=True,abortConnect=False"
}
}
Von Bedeutung
Legen Sie abortConnect=False in der Redis-Verbindungszeichenfolge fest. Diese Einstellung ermöglicht es der Anwendung, die Verbindung nach vorübergehenden Verbindungsfehlern automatisch wiederherzustellen, anstatt sofort auszuwerfen.
Schritt 2: Konfigurieren von Wiederholungsversuche und Resilienz
Konfigurieren Sie die OnL2CacheFailure Callback-Funktion so, dass Ihre Anwendung reibungslos weiterläuft, wenn der verteilte Cache vorübergehend ausfällt.
services.Configure<MsalDistributedTokenCacheAdapterOptions>(options =>
{
options.OnL2CacheFailure = (ex) =>
{
// Log the failure for monitoring and alerting.
logger.LogWarning(ex, "Distributed token cache is unavailable. " +
"Falling back to in-memory cache.");
return true; // Continue without the L2 cache.
};
// Set a timeout to avoid blocking the request pipeline.
options.AbsoluteExpirationRelativeToNow = TimeSpan.FromHours(12);
});
Schritt 3: Öffnen von Firewallregeln
Wenn die Anwendung in Azure App Service ausgeführt wird und sich der Cache in einem virtuellen Netzwerk befindet, fügen Sie der Zulassungsliste der Cachefirewall die ausgehenden IP-Adressen des App-Diensts hinzu.
Cache-Deserialisierungsfehler
Symptom
Nach dem Upgrade von Microsoft.Identity.Web oder MSAL.NET löst die Anwendung beim Lesen aus dem verteilten Cache Deserialisierungsausnahmen aus. Benutzer müssen sich erneut anmelden und Sie sehen Ausnahmen wie:
System.Text.Json.JsonException:
The JSON value could not be converted to the expected type.
Oder:
Microsoft.Identity.Client.MsalClientException:
Error code: json_parse_failed
Ursache
Das Serialisierungsformat des Tokencaches wurde zwischen Bibliotheksversionen geändert. Token, die von der vorherigen Version zwischengespeichert wurden, können von der neuen Version nicht deserialisiert werden. Dieses Problem tritt am häufigsten bei Hauptversionsupgrades von MSAL.NET oder Microsoft auf. Identity.Web.
Lösung
Option A: Löschen des Caches
Die einfachste Lösung besteht darin, alle Einträge im verteilten Cache zu löschen. Benutzer authentifizieren sich einmal erneut, und nachfolgende Token werden im neuen Format geschrieben.
Leeren sie den Redis-Cache:
redis-cli FLUSHDB
Oder löschen Sie die SQL Server verteilten Cachetabelle:
DELETE FROM [dbo].[TokenCache];
Hinweis
Durch das Löschen des Caches werden alle aktiven Benutzer erneut authentifiziert. Planen Sie diesen Vorgang während eines Wartungsfensters, wenn Ihre Anwendung eine große Benutzerbasis bietet.
Option B: Geschmeidige Handhabung von Deserialisierungsfehlern
Konfigurieren Sie den Cacheadapter so, dass Deserialisierungsfehler als Cache-Treffer behandelt werden, anstatt als schwerwiegende Fehler:
services.Configure<MsalDistributedTokenCacheAdapterOptions>(options =>
{
options.OnL2CacheFailure = (ex) =>
{
if (ex is JsonException or MsalClientException)
{
logger.LogWarning(ex, "Cache deserialization failed. " +
"Treating as cache miss.");
return true;
}
return false; // Propagate unexpected errors.
};
});
Bei diesem Ansatz werden betroffene Cacheeinträge automatisch ersetzt, wenn Benutzer erneut authentifiziert werden, und es ist kein manuelles Leeren des Caches erforderlich.
Nichtübereinstimmung zwischen Verschlüsselungsschlüsseln auf Servern
Symptom
Deserialisierungsfehler treten in Bereitstellungen mit mehreren Instanzen auf, obwohl der verteilte Cache funktioniert. Token, die von einer Serverinstanz zwischengespeichert werden, können nicht von einer anderen gelesen werden. Sie sehen json_parse_failed oder IDW10802 Fehler in den Protokollen.
Ursache
Wenn die Cacheverschlüsselung aktiviert ist (options.Encrypt = true), Microsoft. Identity.Web verwendet ASP.NET Core Datenschutz zum Verschlüsseln von Cacheeinträgen. Standardmäßig generiert jede Serverinstanz eigene Datenschutzschlüssel, sodass eine Instanz einträge, die von einer anderen geschrieben wurden, nicht entschlüsseln kann.
Lösung
Konfigurieren Sie ASP.NET Core Datenschutz, um Verschlüsselungsschlüssel für alle Serverinstanzen gemeinsam zu nutzen.
Option A: Azure Blob Storage + Azure Key Vault (empfohlen für Azure Bereitstellungen)
using Microsoft.AspNetCore.DataProtection;
using Azure.Identity;
builder.Services.AddDataProtection()
.PersistKeysToAzureBlobStorage(
new Uri("https://yourstorageaccount.blob.core.windows.net/dataprotection/keys.xml"),
new DefaultAzureCredential())
.ProtectKeysWithAzureKeyVault(
new Uri("https://yourkeyvault.vault.azure.net/keys/dataprotection-key"),
new DefaultAzureCredential());
builder.Services.Configure<MsalDistributedTokenCacheAdapterOptions>(options =>
{
options.Encrypt = true;
});
Diese Konfiguration speichert den Datenschutzschlüsselring in Azure Blob Storage und schützt die ruhenden Schlüssel mit Azure Key Vault. Alle Anwendungsinstanzen, die auf dasselbe Blob und denselben Schlüssel zugreifen, können die Cacheeinträge der anderen verschlüsseln und entschlüsseln.
Option B: Ein freigegebenes Dateisystem mit Zertifikatschutz
builder.Services.AddDataProtection()
.PersistKeysToFileSystem(new DirectoryInfo(@"\\server\share\keys"))
.ProtectKeysWithCertificate(certificate);
Tipp
Verwenden Sie UnprotectKeysWithAnyCertificate, um beim Erneuern des Datenschutzzertifikats sowohl die aktuellen als auch die vorherigen Zertifikate einzubeziehen. Dies ermöglicht die Entschlüsselung von Schlüsseln, die während des Rotationszeitraums mit dem alten Zertifikat geschützt wurden.
Arbeitsspeicherwachstum mit In-Memory-Cache
Symptom
Der Anwendungsspeicherverbrauch wächst im Laufe der Zeit stetig. Wenn die Anwendung in einem Container oder App Service-Plan mit einem festen Speicherlimit ausgeführt wird, wird sie schließlich neu gestartet oder wirft OutOfMemoryException. Die Überwachung zeigt, dass der verwaltete Heap ohne Rückgewinnung durch Garbage Collection wächst.
Ursache
Die Verwendung AddInMemoryTokenCaches() ohne Größenbeschränkungen führt zu einem ungebundenen Cachewachstum. Diese Situation ist besonders problematisch in Anwendungen, die viele Benutzer bedienen, da der Tokeneintrag jedes Benutzers unbegrenzt Speicher verbraucht.
Standardmäßig erzwingt MemoryCache keine maximale Größe und räumt keine Einträge aus, es sei denn, eine Ablaufrichtlinie ist festgelegt.
Lösung
Option A: Festlegen eines Größenlimits und einer gleitenden Ablaufsteuerung
Konfigurieren Sie den Speichercache mit Ablaufrichtlinien:
services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme)
.AddMicrosoftIdentityWebApp(Configuration)
.EnableTokenAcquisitionToCallDownstreamApi()
.AddInMemoryTokenCaches();
services.Configure<MsalMemoryTokenCacheOptions>(options =>
{
options.AbsoluteExpirationRelativeToNow = TimeSpan.FromHours(12);
options.SlidingExpiration = TimeSpan.FromHours(2);
});
Bei diesen Einstellungen laufen Einträge nach 12 Stunden ab, unabhängig vom Zugriff, und Einträge, die 2 Stunden im Leerlauf sind, werden früher gelöscht.
Option B: Wechseln zu einem verteilten Cache
Bei Anwendungen mit vielen gleichzeitigen Benutzern wird kein Speichercache skaliert. Wechseln zu einem verteilten Cache wie Redis:
services.AddStackExchangeRedisCache(options =>
{
options.Configuration = Configuration.GetConnectionString("Redis");
});
services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme)
.AddMicrosoftIdentityWebApp(Configuration)
.EnableTokenAcquisitionToCallDownstreamApi()
.AddDistributedTokenCaches();
Ein verteilter Cache setzt Speicher aus dem Anwendungsprozess aus, speichert Token über Neustarts hinweg und unterstützt Bereitstellungen mit mehreren Instanzen.
Option C: Verwenden der L1/L2-Hybridarchitektur
Microsoft. Identity.Web unterstützt einen Hybridansatz, der einen schnellen L1-Cache im Arbeitsspeicher mit einem persistenten verteilten L2-Cache kombiniert. Konfigurieren sie den L1/L2-Hybridcache:
services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme)
.AddMicrosoftIdentityWebApp(Configuration)
.EnableTokenAcquisitionToCallDownstreamApi()
.AddDistributedTokenCaches();
services.Configure<MsalDistributedTokenCacheAdapterOptions>(options =>
{
options.L1CacheOptions = new MsalMemoryTokenCacheOptions
{
AbsoluteExpirationRelativeToNow = TimeSpan.FromMinutes(5),
SlidingExpiration = TimeSpan.FromMinutes(2)
};
});
Bei der L1/L2-Zwischenspeicherung werden häufig verwendete Token aus dem Arbeitsspeicher (L1) mit Unter millisekundenlatenz bereitgestellt. Der L2-Cache bietet Persistenz und instanzübergreifende Konsistenz. Der L1-Cache verwendet kurze Ablaufzeiten, um das Speicherwachstum zu begrenzen.
Wiederholte Multi-Faktor-Authentifizierungs- oder Zustimmungsaufforderungen
Symptom
Benutzer werden wiederholt zur mehrstufigen Authentifizierung (MFA) oder zur Zustimmung aufgefordert, obwohl sie diese Schritte kürzlich abgeschlossen haben. Die Anwendung kann vorhandene Token im Cache nicht finden.
Ursache
Dieses Problem tritt auf, wenn die Tokencachesuche nicht mit einem zwischengespeicherten Eintrag mit dem aktuellen Benutzerkonto übereinstimmt. Häufige Ursachen sind:
- Der Cacheschlüssel unterscheidet sich von dem, der beim Speichern des Tokens verwendet wird. Diese Situation kann auftreten, wenn sich der
HomeAccountId- oder Mandantenkontext ändert. - Die Anwendung führt mehrere Instanzen hinter einem Load-Balancer mit Zwischenspeicherung im Arbeitsspeicher aus und leitet Anfragen an eine Instanz weiter, die nicht über das Benutzertoken verfügt.
- Die angeforderten Ansprüche oder Bereiche wurden geändert, sodass das zwischengespeicherte Token die neue Anforderung nicht erfüllt.
- Die Sitzungsaffinität ist nicht aktiviert, sodass Benutzer an verschiedene Instanzen weitergeleitet werden, die ihre zwischengespeicherten Token nicht haben.
Schritte zum Diagnostizieren von Problemen
Führen Sie die folgenden Schritte aus, um zu ermitteln, warum Token nicht im Cache gefunden werden:
- Überprüfen Sie den Cachetyp. Wenn Sie in einer Bereitstellung mit mehreren Instanzen verwenden
AddInMemoryTokenCaches(), stehen token, die in einer Instanz zwischengespeichert sind, nicht in einer anderen Instanz zur Verfügung. Wechseln sie zu einem verteilten Cache. - Überprüfen Sie den Kontobezeichner. Aktivieren Sie die Protokollierung auf Debugebene, und suchen Sie nach dem
HomeAccountId. Stellen Sie sicher, dass der Bezeichner über Anforderungen hinweg konsistent ist. - Überprüfen Sie die Geltungsbereiche. Vergewissern Sie sich, dass die von
GetAccessTokenForUserAsyncangeforderten Berechtigungen den ursprünglich zugestimmten Berechtigungen entsprechen. Eine Abweichung im Berechtigungsbereich bewirkt, dass MSAL ein neues Token anfordert. - Überprüfen Sie Richtlinien für bedingten Zugriff. Eine Microsoft Entra ID Richtlinie für bedingten Zugriff, die eine schrittweise Authentifizierung für bestimmte Ressourcen erfordert, führt zu zusätzlichen Eingabeaufforderungen, die nicht im Zusammenhang mit der Zwischenspeicherung stehen.
Lösung
Schritt 1: Wechseln zur verteilten Zwischenspeicherung
Wenn Ihre Anwendung mehrere Instanzen ausführt, verwenden Sie einen verteilten Cache, um Token über Instanzen hinweg zu teilen:
services.AddStackExchangeRedisCache(options =>
{
options.Configuration = Configuration.GetConnectionString("Redis");
});
services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme)
.AddMicrosoftIdentityWebApp(Configuration)
.EnableTokenAcquisitionToCallDownstreamApi()
.AddDistributedTokenCaches();
Schritt 2: Überprüfen konsistenter Bereiche
Stellen Sie sicher, dass die Bereiche, die Sie beim Abrufen von Token anfordern, den während der Authentifizierung konfigurierten Bereichen entsprechen:
// In authentication setup — initial scopes.
.EnableTokenAcquisitionToCallDownstreamApi(new[] { "User.Read", "Mail.Read" })
// When acquiring a token — use the same scopes.
var token = await tokenAcquisition.GetAccessTokenForUserAsync(
new[] { "User.Read", "Mail.Read" });
Schritt 3: Sitzungsaffinität aktivieren (vorübergehende Lösung)
Wenn Sie nicht sofort zu einem verteilten Cache wechseln können, aktivieren Sie die Sitzungsaffinität (Sticky Sessions) auf Ihrem Load Balancer. Die Sitzungsaffinität leitet die Anforderungen eines Benutzers an dieselbe Instanz weiter. Dieser Ansatz ist eine temporäre Problemumgehung mit Skalierbarkeitseinschränkungen.
Probleme mit der Cacheleistung
Symptom
Tokenabrufe sind langsam und nachgeschaltete API-Aufrufe haben eine höhere Latenz. Die Überwachung zeigt hohe durchschnittliche Reaktionszeiten für Tokenakquisitionsanforderungen. Die Latenz stammt nicht vom Identitätsanbieter– Token werden aus dem Cache bereitgestellt.
Ursache
Probleme mit der Cacheleistung ergeben sich in der Regel aus:
- Hohe L2-Cachelatenz. Der verteilte Cache befindet sich unter hoher Auslastung, geografisch entfernt von der Anwendung oder unter Verwendung einer untergeordneten Dienstebene.
- Große Tokencacheeinträge. Anwendungen, die Token für viele Ressourcen pro Benutzer zwischenspeichern, können große serialisierte Cacheeinträge erzeugen, die langsam zu lesen und zu schreiben sind.
- Kein L1-Cache. Jeder Tokenerwerb wechselt in den verteilten Cache über das Netzwerk, auch für Token, die häufig verwendet werden.
Lösung
Schritt 1: Aktivieren des L1-Speichercaches
Der L1-Cache speichert häufig verwendete Tokens im Prozessspeicher und vermeidet Netzwerkabfragen zu L2.
services.Configure<MsalDistributedTokenCacheAdapterOptions>(options =>
{
options.L1CacheOptions = new MsalMemoryTokenCacheOptions
{
AbsoluteExpirationRelativeToNow = TimeSpan.FromMinutes(5),
SlidingExpiration = TimeSpan.FromMinutes(2)
};
});
Bei dieser Konfiguration verfügen Token, die von L1 bereitgestellt werden, über eine Unter millisekundenlatenz. Token, die nicht in L1 liegen, fallen auf den verteilten L2-Cache zurück.
Schritt 2: Optimieren der verteilten Cacheebene
Wenn die L2-Cachelatenz hoch ist, berücksichtigen Sie die folgenden Aktionen:
- Skalieren Sie die Redis-Instanz. Wechseln Sie zu einer höheren Ebene (z. B. von Basic zu Standard oder Premium in Azure Cache for Redis), um mehr Durchsatz und geringere Latenz zu erhalten.
- Aktivieren Sie die Georeplikation. Wenn Ihre Anwendung Benutzern in mehreren Regionen dient, verwenden Sie Azure Cache for Redis Georeplikation, sodass der Cache nahe an den Berechnungen der einzelnen Regionen liegt.
- Überprüfen Sie die Netzwerkkonfiguration. Verwenden Sie Private Link- oder VNet-Integration, um Netzwerkhüpfungen zwischen der Anwendung und dem Cache zu reduzieren.
Schritt 3: Verringern der serialisierten Tokengröße
Wenn Tokencacheeinträge groß sind, überprüfen Sie, ob die Anwendung Token für mehr Ressourcen als erforderlich anfordert. Jede eindeutige Kombination von Ressourcen und Bereichen trägt zur Größe des Cacheeintrags bei. Konsolidieren Sie API-Aufrufe, soweit möglich, um die Anzahl unterschiedlicher Zugriffstoken zu reduzieren, die pro Benutzer zwischengespeichert wurden.
Redis Cache-Entfernung
Symptom
Benutzer werden zeitweise ohne erkennbares Muster, das auf dem Tokenablauf basiert, aufgefordert, sich erneut zu authentifizieren. Die Redis-Überwachung zeigt, dass evicted_keys steigt und used_memory sich dem maxmemory Grenzwert nähert.
Ursache
Wenn Redis seinen maxmemory Grenzwert erreicht, entfernt es Schlüssel basierend auf der konfigurierten maxmemory-policy. Die Standardrichtlinie (volatile-lru) entfernt die am wenigsten zuletzt verwendeten Schlüssel, die ein Ablaufdatum haben. Wenn die Redis-Instanz für andere Anwendungsdaten freigegeben wird, konkurrieren Tokencacheeinträge um Platz und können vorzeitig gelöscht werden.
Lösung
Schritt 1: Überprüfen der Eviction-Richtlinie
Überprüfen Sie die aktuelle Eviction-Richtlinie:
redis-cli CONFIG GET maxmemory-policy
Für Tokencaches ist (Standardeinstellung) geeignet, volatile-lru da Tokencacheeinträge Ablaufzeiten aufweisen. Wenn andere Daten ohne Ablauf jedoch Speicher verbrauchen, werden Tokeneinträge zuerst entfernt.
Schritt 2: Verwenden einer dedizierten Redis-Instanz
Isolieren Sie den Tokencache von anderen Anwendungsdaten mithilfe einer dedizierten Redis-Instanz:
{
"ConnectionStrings": {
"RedisTokenCache": "token-cache-redis.redis.cache.windows.net:6380,password=...,ssl=True,abortConnect=False",
"RedisAppData": "app-data-redis.redis.cache.windows.net:6380,password=...,ssl=True,abortConnect=False"
}
}
// Register the token cache Redis instance specifically for distributed caching.
services.AddStackExchangeRedisCache(options =>
{
options.Configuration = Configuration.GetConnectionString("RedisTokenCache");
});
Schritt 3: Erhöhen des Redis-Speicherlimits
Wenn eine dedizierte Instanz nicht machbar ist, erhöhen Sie die maxmemory Einstellung. Skalieren Sie in Azure Cache for Redis auf eine höhere Ebene, oder erhöhen Sie die Cachegröße.
Schritt 4: Geeignete Ablaufzeiten für Cacheeinträge festlegen
Legen Sie angemessene Ablaufzeiten fest, sodass veraltete Einträge entfernt werden, bevor der Arbeitsspeicher ausgeht.
services.Configure<MsalDistributedTokenCacheAdapterOptions>(options =>
{
options.AbsoluteExpirationRelativeToNow = TimeSpan.FromHours(12);
options.SlidingExpiration = TimeSpan.FromHours(2);
});
Wachstum der verteilten SQL-Cachetabelle
Symptom
Die SQL Verteilte Cachetabelle wächst kontinuierlich und verbraucht Speicherplatz. Datenbankabfragen für die Cachetabelle werden im Laufe der Zeit langsam ausgeführt, und Möglicherweise werden Warnungen zu Tabellengröße oder Speichergrenzwerten angezeigt.
Ursache
Der SQL Server verteilten Cache (Microsoft.Extensions.Caching.SqlServer) entfernt nicht automatisch abgelaufene Einträge. Abgelaufene Einträge bleiben, bis sie explizit bereinigt werden, was zu einem ungehinderten Tabellenwachstum, zu Leistungsverschlechterungen bei Abfragen und zu erhöhtem Speicherverbrauch führt.
Lösung
Schritt 1: Einrichten eines wiederkehrenden Bereinigungsauftrags
Erstellen Sie einen SQL Server-Agent Auftrag oder einen geplanten Vorgang, um abgelaufene Einträge regelmäßig zu entfernen:
-- Delete expired entries from the SQL distributed cache table.
-- Schedule this query to run every 30 minutes.
DELETE FROM [dbo].[TokenCache]
WHERE ExpiresAtTime < GETUTCDATE();
Tipp
Verwenden Sie in Azure SQL-Datenbank Azure Automation, Azure Functions mit einem Timer-Trigger oder Elastic Jobs, um die Bereinigung zu planen, da SQL Server-Agent nicht verfügbar ist.
Schritt 2: Hinzufügen eines Indexes für eine effiziente Bereinigung
Wenn die Cachetabelle noch keinen Index für die Ablaufspalte enthält, fügen Sie einen hinzu, um den Löschvorgang zu beschleunigen:
CREATE NONCLUSTERED INDEX IX_TokenCache_ExpiresAtTime
ON [dbo].[TokenCache] (ExpiresAtTime);
Schritt 3: Überwachen der Tabellengröße
Fügen Sie die Überwachung hinzu, um die Zeilenanzahl und die Tabellengröße im Laufe der Zeit nachzuverfolgen:
SELECT
COUNT(*) AS TotalEntries,
COUNT(CASE WHEN ExpiresAtTime < GETUTCDATE() THEN 1 END) AS ExpiredEntries,
COUNT(CASE WHEN ExpiresAtTime >= GETUTCDATE() THEN 1 END) AS ActiveEntries
FROM [dbo].[TokenCache];
Schritt 4: Erwägen Sie, zu Redis zu wechseln
Wenn die Verwaltung der SQL-Cachebereinigung belastend ist, wechseln Sie zu Redis, die den Ablauf automatisch über den integrierten TTL-Mechanismus verarbeitet:
// Replace SQL distributed cache with Redis.
services.AddStackExchangeRedisCache(options =>
{
options.Configuration = Configuration.GetConnectionString("Redis");
});
Allgemeine Tipps für die Problembehandlung
Verwenden Sie diese Tipps, wenn Ihr Problem nicht mit einem bestimmten Szenario in diesem Artikel übereinstimmt.
Überprüfen, ob der Cache verwendet wird
Fügen Sie temporäre Protokollierung hinzu, um zu bestätigen, dass Token aus dem Cache gelesen und in den Cache geschrieben werden:
services.Configure<MsalDistributedTokenCacheAdapterOptions>(options =>
{
options.Encrypt = false; // Disable encryption temporarily for debugging only.
options.OnL2CacheFailure = (ex) =>
{
logger.LogError(ex, "L2 cache operation failed.");
return true;
};
});
Mehrfache Cache-Registrierungen überprüfen
Wenn in Ihrem Startcode mehrere Aufrufe von AddInMemoryTokenCaches() oder AddDistributedTokenCaches() existieren, gewinnt die letzte Registrierung. Stellen Sie sicher, dass nur ein Cachetyp registriert ist.
Überprüfen der Tokenlebensdauer
Zugriffstoken haben eine endliche Lebensdauer (in der Regel 60 bis 90 Minuten). Wenn Benutzer nach diesem Zeitraum eine erneute Authentifizierung melden, wird das Verhalten anstelle eines Cacheproblems erwartet. Aktualisierungstoken rufen neue Zugriffstoken im Hintergrund ab und werden im Cache gespeichert. Wenn das Aktualisierungstoken fehlt oder abgelaufen ist, muss der Benutzer erneut authentifizieren.
Testen mit einem sauberen Cache
Löschen Sie beim Diagnostizieren von Problemen den Cache, um beschädigte oder veraltete Einträge auszuschließen:
- Cache im Arbeitsspeicher: Starten Sie die Anwendung neu.
-
Redis: Führen Sie die Ausführung
FLUSHDBin der Cachedatenbank aus. - SQL Server: Alle Zeilen aus der Cachetabelle löschen.
Der Token-Cache ist nach dem Neustart der Anwendung leer.
Symptom
Benutzer müssen nach jedem Neustart der Anwendung oder erneuten Bereitstellung erneut authentifizieren. Der verteilte Cache wird leer angezeigt, oder Token werden nicht beibehalten.
Ursache
Dieses Problem tritt in der Regel auf, wenn Sie einen Speichercache (AddInMemoryTokenCaches()) oder den nicht persistenten verteilten Speichercache (AddDistributedMemoryCache()) in der Produktion verwenden. Keine der beiden Optionen speichert Tokens über Anwendungsneustarts hinweg.
AddDistributedMemoryCache() registriert eine IDistributedCache Implementierung, die Daten im Arbeitsspeicher speichert. Trotz des "verteilten" Namens werden daten nicht extern gespeichert und nur für Entwicklung und Tests vorgesehen.
Lösung
Wechseln sie zu einem beständigen verteilten Cache:
// Register a persistent cache (Redis example).
builder.Services.AddStackExchangeRedisCache(options =>
{
options.Configuration = builder.Configuration.GetConnectionString("Redis");
options.InstanceName = "MyApp_";
});
// Use distributed token caches instead of in-memory.
builder.Services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme)
.AddMicrosoftIdentityWebApp(builder.Configuration)
.EnableTokenAcquisitionToCallDownstreamApi()
.AddDistributedTokenCaches();
Warnung
Verwechseln AddDistributedMemoryCache() Sie nicht mit einem persistenten verteilten Cache. Verwenden Sie AddStackExchangeRedisCache() (Redis), AddDistributedSqlServerCache() (SQL Server) oder eine andere persistente IDistributedCache-Implementierung für Produktionsworkloads.