Poznámka:
Přístup k této stránce vyžaduje autorizaci. Můžete se zkusit přihlásit nebo změnit adresáře.
Přístup k této stránce vyžaduje autorizaci. Můžete zkusit změnit adresáře.
Tento článek vám pomůže diagnostikovat a vyřešit problémy s mezipamětí tokenů v Microsoft. Identity.Web. Problémy s mezipamětí tokenů můžou způsobit selhání ověřování, snížený výkon nebo neočekávané výzvy k přihlášení. Přehled toho, jak funguje ukládání tokenů do mezipaměti v Microsoft Identity.Web, viz Přehled mezipamětiToken.
Předpoklady
Než začnete řešit potíže, potvrďte následující:
- Používáte podporovanou verzi Microsoft. Identity.Web
- Vaše aplikace má nakonfigurované ukládání tokenů do mezipaměti v
Program.csneboStartup.cs. - Máte přístup k protokolům aplikace a v případě potřeby máte infrastrukturu distribuované mezipaměti.
Povolení protokolování a diagnostiky mezipaměti tokenů
Povolte podrobné protokolování jako první diagnostický krok. Microsoft. Identity.Web používá infrastrukturu protokolování ASP.NET Core a generuje události prostřednictvím Identity a ověřování Microsoftu (MSAL).
Povolte protokolování MSAL
Nastavte úroveň protokolu pro Debug knihovny identit ve vaší appsettings.json:
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.Identity.Web": "Debug",
"Microsoft.IdentityModel": "Debug"
}
}
}
Přihlášení k odběru událostí mezipaměti MSAL
Přihlaste se k odběru událostí oznámení mezipaměti tokenů MSAL, abyste mohli sledovat přístupy do mezipaměti, neúspěšné přístupy a činnost serializace:
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;
};
});
Monitorování metrik mezipaměti
V případě provozního monitorování sledujte tyto klíčové metriky:
- Míra úspěchu při načítání z mezipaměti – nízká míra úspěchu indikuje, že tokeny nejsou načítány z mezipaměti.
- Latence mezipaměti L2 – vysoká latence naznačuje problém s připojením nebo výkonem distribuované mezipaměti.
- Chyby serializace mezipaměti – chyby při čtení nebo zápisu signalizují poškození nebo nesoulad verzí.
- Spotřeba paměti – trvalý růst může indikovat chybějící zásady vyřazení.
Selhání připojení distribuované mezipaměti (L2)
Symptom
Protokoly aplikací zobrazují chyby vypršení časového limitu připojení nebo přerušované chyby ověřování. Uživatelé mají zpoždění při přihlašování a zobrazují se výjimky, jako jsou:
Microsoft.Extensions.Caching.StackExchangeRedis.RedisCache:
StackExchange.Redis.RedisConnectionException:
No connection is active/available to service this operation.
Nebo pro SQL Server distribuovanou mezipaměť:
Microsoft.Data.SqlClient.SqlException:
A network-related or instance-specific error occurred while
establishing a connection to SQL Server.
Příčina
Záložní úložiště distribuované mezipaměti (Redis nebo SQL Server) je nedostupné. Mezi obvyklé příčiny patří:
- Nesprávný připojovací řetězec nebo vypršely přístupové údaje.
- Pravidla firewallu sítě blokují připojení z hostitele aplikace.
- Služba mezipaměti je nefunkční nebo prochází údržbou.
- Neshoda konfigurace PROTOKOLU SSL/TLS mezi klientem a serverem mezipaměti
Diagnostické kroky
K identifikaci selhání připojení postupujte takto:
- Ověřte připojení. Z hostitele aplikace otestujte připojení k Redis nebo SQL Server pomocí
Test-NetConnection(PowerShell) neboredis-cli. - Zkontrolujte připojovací řetězec. Ověřte, že připojovací řetězec odpovídá názvu hostitele, portu a přihlašovacím údajům serveru mezipaměti.
- Zkontrolujte pravidla brány firewall. V Azure ověřte, že služba App Service nebo virtuální síť má přístup k prostředku mezipaměti.
- Kontrola stavu funkčnosti. Na portálu Azure zkontrolujte stav a metriky vaší instance Azure Cache for Redis nebo služby SQL Database.
Řešení
Krok 1: Oprava připojovacího řetězce
Ověřte připojovací řetězec v appsettings.json:
{
"ConnectionStrings": {
"Redis": "your-redis-instance.redis.cache.windows.net:6380,password=your-access-key,ssl=True,abortConnect=False"
}
}
Důležité
Nastavte abortConnect=False v řetězci připojení Redis. Toto nastavení umožňuje aplikaci, aby se po přechodných selháních připojení automaticky znovu připojila a nevyvolá se okamžitě.
Krok 2: Konfigurace opakování a odolnosti
Nakonfigurujte OnL2CacheFailure zpětné volání tak, aby vaše aplikace degraduje elegantně, když je distribuovaná mezipaměť dočasně nedostupná.
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);
});
Krok 3: Otevření pravidel brány firewall
Pokud aplikace běží v Azure App Service a mezipaměť je ve virtuální síti, přidejte odchozí IP adresy služby App Service do seznamu povolených bránou firewall mezipaměti.
Chyby deserializace mezipaměti
Symptom
Po upgradu Microsoft.Identity.Web nebo MSAL.NET dojde k vyvolání výjimek při deserializaci při čtení z distribuované mezipaměti. Uživatelé se musí znovu přihlásit a zobrazí se výjimky, například:
System.Text.Json.JsonException:
The JSON value could not be converted to the expected type.
Nebo:
Microsoft.Identity.Client.MsalClientException:
Error code: json_parse_failed
Příčina
Formát serializace mezipaměti tokenů se změnil mezi verzemi knihovny. Tokeny uložené v mezipaměti předchozí verze nelze deserializovat novou verzí. K tomuto problému dochází nejčastěji při upgradu hlavní verze MSAL.NET nebo Microsoft.Identity.Web.
Řešení
Možnost A: Vymazání mezipaměti
Nejjednodušším řešením je vymazat všechny položky v distribuované mezipaměti. Uživatelé se znovu prověří jednou a další tokeny se zapíšou v novém formátu.
Vyprázdnění mezipaměti Redis:
redis-cli FLUSHDB
Nebo vymažte tabulku SQL Server distribuované mezipaměti:
DELETE FROM [dbo].[TokenCache];
Poznámka:
Vymazání mezipaměti způsobí opětovné ověření všech aktivních uživatelů. Naplánujte tuto operaci během časového období údržby, pokud vaše aplikace obsluhuje velkou uživatelskou základnu.
Možnost B: Elegantní zpracování chyb deserializace
Nakonfigurujte adaptér mezipaměti tak, aby selhání deserializace byla považována za neúspěchy mezipaměti místo fatálních chyb.
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.
};
});
Při tomto přístupu se ovlivněné položky mezipaměti automaticky nahradí při opětovném ověření uživatelů a nevyžaduje se žádné ruční vyprázdnění mezipaměti.
Neshoda šifrovacích klíčů mezi servery
Symptom
V nasazeních s více instancemi dochází k chybám deserializace, i když distribuovaná mezipaměť funguje. Tokeny uložené v mezipaměti jedné instance serveru nemůžou číst jiné. V protokolech se zobrazí chyby jako json_parse_failed nebo IDW10802.
Příčina
Pokud je povolené šifrování mezipaměti (options.Encrypt = true), Microsoft. Identity.Web používá k šifrování položek mezipaměti ASP.NET Core Data Protection. Ve výchozím nastavení každá instance serveru generuje vlastní klíče ochrany dat, takže jedna instance nemůže dešifrovat záznamy zapsané jiným serverem.
Řešení
Nakonfigurujte ASP.NET Core Ochrana dat tak, aby sdílela šifrovací klíče napříč všemi instancemi serveru.
Option A: Azure Blob Storage + Azure Key Vault (doporučeno pro nasazení Azure)
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;
});
Tato konfigurace ukládá okruh klíčů ochrany dat do Azure Blob Storage a chrání neaktivní uložené klíče pomocí Azure Key Vault. Všechny instance aplikace, které přistupují ke stejnému blobu a klíči, mohou šifrovat a dešifrovat položky mezipaměti navzájem.
Možnost B: Sdílený systém souborů s ochranou certifikátů
builder.Services.AddDataProtection()
.PersistKeysToFileSystem(new DirectoryInfo(@"\\server\share\keys"))
.ProtectKeysWithCertificate(certificate);
Návod
Při obměně certifikátu Ochrany dat použijte UnprotectKeysWithAnyCertificate k zahrnutí aktuálních i předchozích certifikátů. To umožňuje dešifrování klíčů chráněných starým certifikátem během okna rotace.
Růst paměti při použití cache v paměti RAM
Symptom
Spotřeba paměti aplikace se v průběhu času stále zvyšuje. Pokud aplikace běží v kontejneru nebo plánu služby App Service s pevným limitem paměti, nakonec se restartuje nebo vyvolá OutOfMemoryException. Monitorování ukazuje růst spravované haldy bez zásahu garbage collectoru.
Příčina
Použití AddInMemoryTokenCaches() bez omezení velikosti způsobí nevázaných nárůst mezipaměti. Tato situace je obzvláště problematická v aplikacích, které obsluhují mnoho uživatelů, protože položka tokenu každého uživatele spotřebovává paměť neomezeně dlouho.
Ve výchozím nastavení MemoryCache nevynucuje maximální velikost a neodstraňuje položky, pokud není nastavená zásada vypršení platnosti.
Řešení
Možnost A: Nastavení limitu velikosti a posuvného vypršení platnosti
Nakonfigurujte mezipaměť v paměti pomocí zásad vypršení platnosti:
services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme)
.AddMicrosoftIdentityWebApp(Configuration)
.EnableTokenAcquisitionToCallDownstreamApi()
.AddInMemoryTokenCaches();
services.Configure<MsalMemoryTokenCacheOptions>(options =>
{
options.AbsoluteExpirationRelativeToNow = TimeSpan.FromHours(12);
options.SlidingExpiration = TimeSpan.FromHours(2);
});
U těchto nastavení vyprší platnost položek po 12 hodinách bez ohledu na přístup a položky nečinné po dobu 2 hodin se vyřadí dříve.
Možnost B: Přepnutí do distribuované mezipaměti
U aplikací s mnoha souběžnými uživateli se mezipaměť v paměti nes škáluje. Přepněte do distribuované mezipaměti, jako je Redis:
services.AddStackExchangeRedisCache(options =>
{
options.Configuration = Configuration.GetConnectionString("Redis");
});
services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme)
.AddMicrosoftIdentityWebApp(Configuration)
.EnableTokenAcquisitionToCallDownstreamApi()
.AddDistributedTokenCaches();
Distribuovaná mezipaměť snižuje zatížení paměti z procesu aplikace, zachovává tokeny napříč restartováními a podporuje nasazení s více instancemi.
Možnost C: Použití hybridní architektury L1/L2
Microsoft. Identity.Web podporuje hybridní přístup, který kombinuje rychlou mezipaměť L1 v paměti s trvalou distribuovanou mezipamětí L2. Konfigurace hybridní mezipaměti L1/L2:
services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme)
.AddMicrosoftIdentityWebApp(Configuration)
.EnableTokenAcquisitionToCallDownstreamApi()
.AddDistributedTokenCaches();
services.Configure<MsalDistributedTokenCacheAdapterOptions>(options =>
{
options.L1CacheOptions = new MsalMemoryTokenCacheOptions
{
AbsoluteExpirationRelativeToNow = TimeSpan.FromMinutes(5),
SlidingExpiration = TimeSpan.FromMinutes(2)
};
});
Při použití mezipaměti L1/L2 se často přistupované tokeny obsluhují přímo z paměti L1 s latencí pod jednu milisekundu. Mezipaměť L2 poskytuje trvalost a konzistenci mezi instancemi. Mezipaměť L1 využívá krátké vypršení platnosti k omezení růstu paměti.
Opakované výzvy k vícefaktorové ověřování nebo vyjádření souhlasu
Symptom
Uživatelům se opakovaně zobrazuje výzva k vícefaktorovým ověřováním (MFA) nebo k vyjádření souhlasu, i když tyto kroky provedli nedávno. Aplikace nemůže najít existující tokeny v mezipaměti.
Příčina
K tomuto problému dochází, když vyhledávání v mezipaměti tokenů neodpovídá uložené položce pro aktuální uživatelský účet. Mezi obvyklé příčiny patří:
- Klíč mezipaměti se liší od klíče použitého při uložení tokenu. K této situaci může dojít v případě, že se kontext tenanta
HomeAccountIdzmění. - Aplikace spouští několik instancí za vyrovnávačem zatížení s ukládáním do mezipaměti v paměti a požadavky jsou směrovány do instance, která nemá uživatelský token.
- Požadované nároky nebo obory se změnily, takže token v mezipaměti nesplňuje nový požadavek.
- Spřažení relací není povolené, takže uživatelé jsou směrováni do různých instancí, které nemají tokeny uložené v mezipaměti.
Diagnostické kroky
Pokud chcete zjistit, proč se tokeny v mezipaměti nenašly, postupujte takto:
- Zkontrolujte typ mezipaměti. Pokud používáte
AddInMemoryTokenCaches()při nasazení s více instancemi, tokeny uložené v mezipaměti v jedné instanci nejsou v jiné instanci k dispozici. Přepněte do distribuované mezipaměti. - Ověřte identifikátor účtu. Povolte protokolování na úrovni ladění a vyhledejte
HomeAccountId. Ověřte, že je identifikátor konzistentní napříč požadavky. - Zkontrolujte rozsahy. Ověřte, že rozsahy požadované pomocí
GetAccessTokenForUserAsyncodpovídají rozsahům původně odsouhlaseným. Nesoulad oborů způsobí, že MSAL požádá o nový token. - Zkontrolujte zásady podmíněného přístupu. Zásady podmíněného přístupu Microsoft Entra ID, které vyžadují zesílené ověření specifických zdrojů, způsobují nečekané výzvy, které nesouvisejí s ukládáním do mezipaměti.
Řešení
Krok 1: Přepnutí do distribuované mezipaměti
Pokud vaše aplikace spouští více instancí, použijte distribuovanou mezipaměť ke sdílení tokenů napříč instancemi:
services.AddStackExchangeRedisCache(options =>
{
options.Configuration = Configuration.GetConnectionString("Redis");
});
services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme)
.AddMicrosoftIdentityWebApp(Configuration)
.EnableTokenAcquisitionToCallDownstreamApi()
.AddDistributedTokenCaches();
Krok 2: Ověření konzistentních oborů
Ujistěte se, že obory, které požadujete při získávání tokenů, odpovídají oborům nakonfigurovaným během ověřování:
// 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" });
Krok 3: Povolení spřažení relací (dočasné alternativní řešení)
Pokud nemůžete hned přepnout na distribuovanou mezipaměť, povolte v nástroji pro vyrovnávání zatížení spřažení relací (rychlé relace). Přesměrování podle relace směruje požadavky uživatele do stejné instance. Tento přístup představuje dočasné alternativní řešení s omezeními škálovatelnosti.
Problémy s výkonem mezipaměti
Symptom
Načítání tokenů je pomalé a podřízená volání rozhraní API mají zvýšenou latenci. Monitorování ukazuje vysokou průměrnou dobu odezvy pro žádosti o získání tokenu. Latence není způsobena zprostředkovatelem identity – tokeny jsou poskytovány z mezipaměti.
Příčina
Problémy s výkonem mezipaměti obvykle vyplývají z:
- Vysoká latence mezipaměti L2 Distribuovaná mezipaměť je pod velkým zatížením, geograficky vzdálená od aplikace nebo používá podsazenou úroveň služby.
- Velké položky mezipaměti tokenů. Aplikace, které ukládají tokeny do mezipaměti pro mnoho prostředků na uživatele, mohou vytvářet velké serializované položky do mezipaměti, které jsou pomalé při čtení a zápisu.
- Žádná L1 cache. Každé pořízení tokenu přejde do distribuované mezipaměti přes síť, a to i pro tokeny, které se používají často.
Řešení
Krok 1: Povolení mezipaměti L1 v paměti
Mezipaměť L1 ukládá často používané tokeny v paměti procesu, čímž se vyhne síťovým přenosům do mezipaměti L2.
services.Configure<MsalDistributedTokenCacheAdapterOptions>(options =>
{
options.L1CacheOptions = new MsalMemoryTokenCacheOptions
{
AbsoluteExpirationRelativeToNow = TimeSpan.FromMinutes(5),
SlidingExpiration = TimeSpan.FromMinutes(2)
};
});
V této konfiguraci mají tokeny obsluhované z L1 podmilisekundovou latenci. Tokeny, které nejsou v L1, se vrátí do distribuované mezipaměti L2.
Krok 2: Optimalizace úrovně distribuované mezipaměti
Pokud je latence mezipaměti L2 vysoká, zvažte následující akce:
- Navyšte kapacitu instance Redisu. Přejděte na vyšší úroveň (například z úrovně Basic na Standard nebo Premium v Azure Cache for Redis), abyste získali větší propustnost a nižší latenci.
- Povolte geografickou replikaci. Pokud vaše aplikace obsluhuje uživatele ve více oblastech, použijte geografickou replikaci Azure Cache for Redis, aby byla mezipaměť blíže výpočetním zdrojům jednotlivých oblastí.
- Zkontrolujte konfiguraci sítě. Pomocí Private Link nebo integrace s virtuální sítí VNet snižte počet skoků v síti mezi aplikací a mezipamětí.
Krok 3: Zmenšení serializované velikosti tokenu
Pokud jsou položky mezipaměti tokenů velké, zkontrolujte, jestli aplikace požaduje tokeny pro více prostředků, než je potřeba. Každá jedinečná kombinace prostředků a rozsahů přispívá k velikosti položky v mezipaměti. Konsolidujte volání rozhraní API, pokud je to možné, aby se snížil počet jedinečných přístupových tokenů uložených v mezipaměti pro jednotlivé uživatele.
Vyřazení mezipaměti Redis
Symptom
Uživatelům se přerušovaně zobrazí výzva k opětovnému ověření bez vzoru na základě vypršení platnosti tokenu. Monitorování Redis ukazuje evicted_keys zvýšení a used_memory přiblížení k limitu maxmemory.
Příčina
Když Redis dosáhne svého maxmemory limitu, vyřazuje klíče podle nastaveného maxmemory-policy. Výchozí zásada (volatile-lru) vyřadí nejméně naposledy použité klíče, které mají vypršení platnosti. Pokud je instance Redis sdílena s jinými daty aplikace, položky mezipaměti tokenů soupeří o prostor a je možné je předčasně vyřadit.
Řešení
Krok 1: Kontrola zásad vyřazení
Zkontrolujte aktuální zásady vyřazení:
redis-cli CONFIG GET maxmemory-policy
U mezipamětí tokenů (výchozí nastavení) je vhodné, volatile-lru protože položky mezipaměti tokenů mají vypršení platnosti. Pokud však jiná data bez vypršení platnosti spotřebovávají paměť, položky tokenů se nejprve vyřadí.
Krok 2: Použití vyhrazené instance Redis
Izolujte mezipaměť tokenů od jiných dat aplikace pomocí vyhrazené instance Redis:
{
"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");
});
Krok 3: Zvýšení limitu paměti Redis
Pokud není možné zřídit vyhrazenou instanci, zvyšte maxmemory nastavení. V Azure Cache for Redis vertikálně navyšte kapacitu na vyšší úroveň nebo zvětšete velikost mezipaměti.
Krok 4: Nastavení vypršení platnosti příslušných položek mezipaměti
Nastavte přiměřené vypršení platnosti, aby se před vyčerpáním paměti odebraly zastaralé položky:
services.Configure<MsalDistributedTokenCacheAdapterOptions>(options =>
{
options.AbsoluteExpirationRelativeToNow = TimeSpan.FromHours(12);
options.SlidingExpiration = TimeSpan.FromHours(2);
});
Růst tabulek distribuované mezipaměti SQL
Symptom
Tabulka distribuované mezipaměti SQL neustále roste a spotřebovává místo na disku. Databázové dotazy na tabulku mezipaměti jsou pomalé v průběhu času a můžou se zobrazit upozornění týkající se velikosti tabulky nebo omezení úložiště.
Příčina
Distribuovaná mezipaměť SQL Server (Microsoft.Extensions.Caching.SqlServer) automaticky neodebere položky, jejichž platnost vypršela. Položky s vypršenou platností zůstanou, dokud se explicitně nevyprázdní, což způsobí nárůst nevázaných tabulek, snížení výkonu dotazů a spotřebu úložiště.
Řešení
Krok 1: Nastavení opakované úlohy čištění
Vytvořte SQL Server Agent úlohu nebo naplánovanou úlohu, která bude pravidelně odebírat položky, jejichž platnost vypršela:
-- Delete expired entries from the SQL distributed cache table.
-- Schedule this query to run every 30 minutes.
DELETE FROM [dbo].[TokenCache]
WHERE ExpiresAtTime < GETUTCDATE();
Návod
V Azure SQL Database, kde SQL Server Agent není k dispozici, použijte Azure Automation, Azure Functions s časovým spouštěčem nebo Elastic Jobs k naplánování vyčištění.
Krok 2: Přidání indexu pro efektivní vyčištění
Pokud tabulka mezipaměti ještě nemá ve sloupci vypršení platnosti index, přidejte jednu pro urychlení operace odstranění:
CREATE NONCLUSTERED INDEX IX_TokenCache_ExpiresAtTime
ON [dbo].[TokenCache] (ExpiresAtTime);
Krok 3: Monitorování velikosti tabulky
Přidejte monitorování pro sledování počtu řádků a velikosti tabulky v průběhu času:
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];
Krok 4: Zvažte přepnutí na Redis
Pokud je správa čištění mezipaměti SQL náročná, přepněte na Redis, který automaticky zpracovává vypršení platnosti prostřednictvím integrovaného mechanismu TTL:
// Replace SQL distributed cache with Redis.
services.AddStackExchangeRedisCache(options =>
{
options.Configuration = Configuration.GetConnectionString("Redis");
});
Obecné tipy pro řešení potíží
Tyto tipy použijte v případě, že váš problém neodpovídá konkrétnímu scénáři v tomto článku.
Ověřte, že se mezipaměť používá.
Přidejte dočasné protokolování pro potvrzení, že tokeny se čtou a zapisují do mezipaměti:
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;
};
});
Kontrola více registrací mezipaměti
Pokud ve spouštěcím kódu existuje více volání AddInMemoryTokenCaches() nebo AddDistributedTokenCaches(), převáží poslední registrace. Ověřte, že je zaregistrovaný pouze jeden typ mezipaměti.
Kontrola doby života tokenu
Přístupové tokeny mají omezenou životnost (obvykle 60–90 minut). Pokud uživatelé po tomto období hlásí, že se znovu autentizovali, je to očekávané chování, nikoliv problém s mezipamětí. Obnovovací tokeny získávají nové přístupové tokeny bezobslužně a ukládají se do mezipaměti. Pokud token aktualizace chybí nebo vypršela jeho platnost, musí se uživatel znovu autorizovat.
Testování s čistou mezipamětí
Při diagnostice problémů vymažte mezipaměť, aby se vyloučily poškozené nebo zastaralé položky:
- Mezipaměť v paměti: Restartujte aplikaci.
-
Redis: Spusťte
FLUSHDBna databázi mezipaměti. - SQL Server: Odstraňte všechny řádky z tabulky mezipaměti.
Mezipaměť tokenů je po restartování aplikace prázdná.
Symptom
Uživatelé musí po každém restartování nebo opětovném nasazení aplikace znovu provést ověření. Distribuovaná mezipaměť se zobrazuje jako prázdná nebo tokeny se neuchovávají.
Příčina
K tomuto problému obvykle dochází v případě, že v produkčním prostředí používáte mezipaměť v paměti (AddInMemoryTokenCaches()) nebo neuskutečnou distribuovanou paměťovou mezipaměť (AddDistributedMemoryCache()). Žádná možnost neuchová tokeny napříč restartováními aplikace.
AddDistributedMemoryCache() zaregistruje IDistributedCache implementaci, která ukládá data do paměti. I přes "distribuovaný" název neuchovává data externě a je určen pouze pro vývoj a testování.
Řešení
Přepnutí na trvalou distribuovanou mezipaměť:
// 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();
Výstraha
Nezaměňujte AddDistributedMemoryCache() s trvalou distribuovanou mezipamětí. Pro produkční úlohy použijte AddStackExchangeRedisCache() (Redis), AddDistributedSqlServerCache() (SQL Server) nebo jinou trvalou implementaci IDistributedCache.