Nota
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare ad accedere o modificare le directory.
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare a modificare le directory.
Questo articolo illustra come diagnosticare e risolvere i problemi della cache dei token in Microsoft. Identity.Web. I problemi di cache dei token possono causare errori di autenticazione, prestazioni ridotte o richieste di accesso impreviste. Per una panoramica del funzionamento della memorizzazione nella cache dei token in Microsoft. Identity.Web, vedere panoramica della cache Token.
Prerequisiti
Prima di risolvere i problemi, verificare quanto segue:
- Si sta usando una versione supportata di Microsoft. Identity.Web.
- L'applicazione ha la memorizzazione nella cache dei token configurata in
Program.csoStartup.cs. - È possibile accedere ai log dell'applicazione e, se applicabile, all'infrastruttura della cache distribuita.
Abilitare la registrazione e la diagnostica della cache dei token
Abilitare la registrazione dettagliata come primo passaggio di diagnostica. Microsoft. Identity.Web usa l'infrastruttura di registrazione ASP.NET Core e genera eventi tramite il Libreria di Autenticazione Microsoft (MSAL).
Abilitare la registrazione MSAL
Impostare il livello di log su Debug per le librerie di identità in appsettings.json:
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.Identity.Web": "Debug",
"Microsoft.IdentityModel": "Debug"
}
}
}
Sottoscrivere eventi della cache MSAL
Sottoscrivere gli eventi di notifica della cache dei token MSAL per tenere traccia di riscontri nella cache, mancati riscontri e attività di serializzazione:
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;
};
});
Monitorare le metriche della cache
Per il monitoraggio della produzione, tenere traccia delle metriche chiave seguenti:
- Frequenza di riscontri nella cache : una frequenza di riscontri bassa indica che i token non vengono recuperati dalla cache.
- Latenza cache L2 : la latenza elevata suggerisce un problema di connettività o prestazioni della cache distribuita.
- Errori di serializzazione della cache : errori durante la lettura o la scrittura indicano errori di danneggiamento o mancata corrispondenza della versione.
- Consumo di memoria — una crescita sostenuta può indicare politiche di espulsione mancanti.
Errori di connessione della cache distribuita (L2)
Sintomo
I log dell'applicazione mostrano errori di timeout della connessione o errori di autenticazione intermittenti. Gli utenti riscontrano ritardi di accesso e vengono visualizzate eccezioni come:
Microsoft.Extensions.Caching.StackExchangeRedis.RedisCache:
StackExchange.Redis.RedisConnectionException:
No connection is active/available to service this operation.
Oppure per la cache distribuita di SQL Server:
Microsoft.Data.SqlClient.SqlException:
A network-related or instance-specific error occurred while
establishing a connection to SQL Server.
Motivo
L'archivio di backup della cache distribuita (Redis o SQL Server) non è raggiungibile. Cause comuni includono:
- Stringa di connessione errata o credenziali di accesso scadute.
- Regole del firewall di rete che bloccano la connessione dall'host dell'app.
- Il servizio cache è inattivo o in fase di manutenzione.
- Mancata corrispondenza della configurazione SSL/TLS tra il client e il server della cache.
Procedura di diagnostica
Per identificare l'errore di connessione, seguire questa procedura:
- Verificare la connettività. Dall'host dell'applicazione testare la connessione a Redis o SQL Server usando
Test-NetConnection(PowerShell) oredis-cli. - Controllare la stringa di connessione. Verificare che il stringa di connessione corrisponda al nome host, alla porta e alle credenziali del server della cache.
- Esaminare le regole del firewall. In Azure verificare che il servizio app o la rete virtuale possa raggiungere la risorsa della cache.
- Verificare lo stato del servizio. Nel portale di Azure esaminare l'integrità e le metriche del cache di Azure per Redis o dell'istanza del database SQL.
Soluzione
P 1: Correggere il stringa di connessione
Verificare la stringa di connessione nel appsettings.json:
{
"ConnectionStrings": {
"Redis": "your-redis-instance.redis.cache.windows.net:6380,password=your-access-key,ssl=True,abortConnect=False"
}
}
Importante
Impostare abortConnect=False nella stringa di connessione di Redis. Questa impostazione consente all'applicazione di riconnettersi automaticamente dopo gli errori di connessione temporanei anziché riportare immediatamente un errore.
Passaggio 2: Configurare i tentativi e la resilienza
Configurare il callback in modo che l'applicazione OnL2CacheFailure si degradi gradualmente quando la cache distribuita è temporaneamente non disponibile.
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);
});
Passaggio 3: Aprire le regole del firewall
Se l'applicazione viene eseguita in Servizio app di Azure e la cache si trova in una rete virtuale, aggiungere gli indirizzi IP in uscita del servizio app all'elenco di indirizzi consentiti del firewall della cache.
Errori di deserializzazione della cache
Sintomo
Dopo l'aggiornamento Microsoft. Identity.Web o MSAL.NET, l'applicazione genera eccezioni di deserializzazione durante la lettura dalla cache distribuita. Gli utenti devono eseguire di nuovo l'accesso e vengono visualizzate eccezioni come:
System.Text.Json.JsonException:
The JSON value could not be converted to the expected type.
O:
Microsoft.Identity.Client.MsalClientException:
Error code: json_parse_failed
Motivo
Il formato di serializzazione della cache dei token è cambiato tra le versioni della libreria. I token memorizzati nella cache dalla versione precedente non possono essere deserializzati dalla nuova versione. Questo problema si verifica più spesso durante gli aggiornamenti delle versioni principali di MSAL.NET o Microsoft. Identity.Web.
Soluzione
Opzione A: Cancellare la cache
La correzione più semplice consiste nell'eliminare tutte le voci nella cache distribuita. Gli utenti riautentano una sola volta e i token successivi vengono scritti nel nuovo formato.
Scaricare la cache Redis:
redis-cli FLUSHDB
Cancellare la tabella della cache distribuita di SQL Server:
DELETE FROM [dbo].[TokenCache];
Annotazioni
La cancellazione della cache comporta la riautenticazione di tutti gli utenti attivi. Pianificare questa operazione durante una finestra di manutenzione se l'applicazione serve una base utente di grandi dimensioni.
Opzione B: Gestire gli errori di deserializzazione normalmente
Configurare l'adattatore cache per gestire gli errori di deserializzazione come mancati riscontri nella cache anziché errori irreversibili:
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.
};
});
Con questo approccio, le voci della cache interessate vengono sostituite automaticamente quando gli utenti riautenticano e non è necessario scaricare manualmente la cache.
Incongruenza della chiave di crittografia tra server
Sintomo
Gli errori di deserializzazione si verificano nelle distribuzioni a istanze multipla anche se la cache distribuita funziona. I token memorizzati nella cache da un'istanza del server non possono essere letti da un'altra. Nei registri vengono visualizzati errori json_parse_failed o IDW10802.
Motivo
Quando la crittografia della cache è abilitata (options.Encrypt = true), Microsoft. Identity.Web usa ASP.NET Core Protezione dati per crittografare le voci della cache. Per impostazione predefinita, ogni istanza del server genera le proprie chiavi di protezione dei dati, in modo che un'istanza non possa decrittografare le voci scritte da un'altra.
Soluzione
Configurare ASP.NET Core Protezione dati per condividere le chiavi di crittografia in tutte le istanze del server.
Opzione A: Archiviazione BLOB di Azure + Azure Key Vault (scelta consigliata per le distribuzioni 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;
});
Questa configurazione archivia l'anello di chiave di protezione dati in Archiviazione BLOB di Azure e protegge le chiavi inattive con Azure Key Vault. Tutte le istanze dell'applicazione che accedono allo stesso blob e alla stessa chiave possono crittografare e decrittografare le voci della cache.
Opzione B: File system condiviso con protezione del certificato
builder.Services.AddDataProtection()
.PersistKeysToFileSystem(new DirectoryInfo(@"\\server\share\keys"))
.ProtectKeysWithCertificate(certificate);
Suggerimento
Quando si ruota il certificato di protezione dati, usare UnprotectKeysWithAnyCertificate per includere sia i certificati correnti che quelli precedenti. Ciò consente la decrittografia delle chiavi protette con il certificato precedente durante la finestra di rotazione.
Aumento della memoria con cache in memoria
Sintomo
L'utilizzo della memoria dell'applicazione aumenta costantemente nel tempo. Se l'applicazione viene eseguita in un contenitore o in un piano di servizio app con un limite di memoria fisso, alla fine si riavvia o genera un errore OutOfMemoryException. Il monitoraggio mostra la crescita dell'heap gestito senza il recupero da parte della raccolta dei rifiuti.
Motivo
L'uso di AddInMemoryTokenCaches() senza limiti di dimensioni causa una crescita della cache senza limiti. Questa situazione è particolarmente problematica nelle applicazioni che servono molti utenti, perché la registrazione del token di ogni utente consuma memoria indefinitamente.
Per impostazione predefinita, MemoryCache non applica una dimensione massima e non rimuove le voci a meno che non sia impostato un criterio di scadenza.
Soluzione
Opzione A: Impostare un limite di dimensioni e una scadenza scorrevole
Configurare la cache in memoria con i criteri di scadenza:
services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme)
.AddMicrosoftIdentityWebApp(Configuration)
.EnableTokenAcquisitionToCallDownstreamApi()
.AddInMemoryTokenCaches();
services.Configure<MsalMemoryTokenCacheOptions>(options =>
{
options.AbsoluteExpirationRelativeToNow = TimeSpan.FromHours(12);
options.SlidingExpiration = TimeSpan.FromHours(2);
});
Con queste impostazioni, le voci scadono dopo 12 ore indipendentemente dall'accesso e le voci inattive per 2 ore vengono rimosse in precedenza.
Opzione B: Passare a una cache distribuita
Per le applicazioni con molti utenti simultanei, una cache in memoria non viene ridimensionata. Passare a una cache distribuita, ad esempio Redis:
services.AddStackExchangeRedisCache(options =>
{
options.Configuration = Configuration.GetConnectionString("Redis");
});
services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme)
.AddMicrosoftIdentityWebApp(Configuration)
.EnableTokenAcquisitionToCallDownstreamApi()
.AddDistributedTokenCaches();
Una cache distribuita esegue l'offload della memoria dal processo dell'applicazione, salva in modo permanente i token tra i riavvii e supporta le distribuzioni a più istanze.
Opzione C: Usare l'architettura ibrida L1/L2
Microsoft. Identity.Web supporta un approccio ibrido che combina una cache L1 veloce in memoria con una cache L2 distribuita persistente. Configurare la cache ibrida 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)
};
});
Con la memorizzazione nella cache L1/L2, i token a cui si accede di frequente vengono serviti dalla memoria (L1) con una latenza inferiore al millisecondo. La cache L2 fornisce la persistenza e la coerenza tra istanze. La cache L1 usa scadenze brevi per limitare la crescita della memoria.
Richieste di autenticazione a più fattori o di consenso ripetute
Sintomo
Agli utenti viene richiesta ripetutamente l'autenticazione a più fattori (MFA) o il consenso anche se hanno completato di recente questi passaggi. L'applicazione non riesce a trovare i token esistenti nella cache.
Motivo
Questo problema si verifica quando il tentativo di ricerca nella cache dei token non riesce a trovare una voce memorizzata corrispondente all'account utente corrente. Cause comuni includono:
- La chiave della cache è diversa da quella usata quando il token è stato archiviato. Questa situazione può verificarsi se il contesto del tenant
HomeAccountIdo cambia. - L'applicazione esegue più istanze dietro un bilanciatore di carico con caching in memoria, e le richieste vengono instradate verso un'istanza che non possiede il token dell'utente.
- Le attestazioni o gli ambiti richiesti sono stati modificati, quindi il token memorizzato nella cache non soddisfa il nuovo requisito.
- L'affinità di sessione non è abilitata, quindi gli utenti vengono instradati verso le diverse istanze che non dispongono dei token memorizzati nella cache.
Procedura di diagnostica
Seguire questa procedura per identificare i motivi per cui i token non vengono trovati nella cache:
- Controllare il tipo di cache. Se si usa
AddInMemoryTokenCaches()in una distribuzione a più istanze, i token memorizzati nella cache in un'istanza non sono disponibili in un'altra. Passare a una cache distribuita. - Verificare l'identificatore dell'account. Abilitare la registrazione a livello di debug e cercare il
HomeAccountId. Verificare che l'identificatore sia coerente tra le richieste. - Esaminare gli ambiti. Verificare che gli ambiti richiesti da
GetAccessTokenForUserAsynccorrispondano agli ambiti a cui è stato originariamente concesso il consenso. Una mancata corrispondenza dell'ambito fa sì che MSAL richieda un nuovo token. - Esaminare i criteri di accesso condizionale. Un Microsoft Entra ID criterio di accesso condizionale che richiede l'autenticazione dettagliata per risorse specifiche causa richieste aggiuntive non correlate alla memorizzazione nella cache.
Soluzione
Passaggio 1: Passare alla memorizzazione nella cache distribuita
Se l'applicazione esegue più istanze, usare una cache distribuita per condividere i token tra istanze:
services.AddStackExchangeRedisCache(options =>
{
options.Configuration = Configuration.GetConnectionString("Redis");
});
services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme)
.AddMicrosoftIdentityWebApp(Configuration)
.EnableTokenAcquisitionToCallDownstreamApi()
.AddDistributedTokenCaches();
Passaggio 2: Verificare ambiti coerenti
Assicurarsi che gli ambiti richiesti durante l'acquisizione dei token corrispondano agli ambiti configurati durante l'autenticazione:
// 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" });
Passaggio 3: Abilitare l'affinità di sessione (soluzione temporanea)
Se non è possibile passare immediatamente a una cache distribuita, abilitare l'affinità di sessione (sessioni permanenti) nel servizio di bilanciamento del carico. L'affinità di sessione indirizza le richieste di un utente alla stessa istanza. Questo approccio è una soluzione alternativa temporanea con limitazioni di scalabilità.
Problemi di prestazioni della cache
Sintomo
Il recupero dei token è lento e le chiamate API downstream aumentano la latenza. Il monitoraggio mostra tempi di risposta medi elevati per le richieste di acquisizione dei token. La latenza non proviene dal provider di identità. I token vengono serviti dalla cache.
Motivo
I problemi di prestazioni della cache in genere derivano da:
- Latenza cache L2 elevata. La cache distribuita è sottoposta a carico elevato, geograficamente distante dall'applicazione o tramite un livello di servizio sottodimensionato.
- Voci della cache dei token di grandi dimensioni. Le applicazioni che memorizzano nella cache i token per molte risorse per utente possono produrre voci di cache serializzate di grandi dimensioni lente da leggere e scrivere.
- Nessuna cache L1. Ogni acquisizione di token passa alla cache distribuita in rete, anche per i token usati di frequente.
Soluzione
Passaggio 1: Abilitare la cache in memoria L1
La cache L1 archivia i token a cui si accede di frequente nella memoria del processo, evitando round trip di rete a L2:
services.Configure<MsalDistributedTokenCacheAdapterOptions>(options =>
{
options.L1CacheOptions = new MsalMemoryTokenCacheOptions
{
AbsoluteExpirationRelativeToNow = TimeSpan.FromMinutes(5),
SlidingExpiration = TimeSpan.FromMinutes(2)
};
});
Con questa configurazione, i token serviti da L1 hanno una latenza di sub millisecondi. I token che non sono in L1 ricadono nella cache distribuita L2.
Passaggio 2: Ottimizzare il livello cache distribuita
Se la latenza della cache L2 è elevata, prendere in considerazione le azioni seguenti:
- Aumentare la capacità dell'istanza di Redis. Passare a un livello superiore (ad esempio, da Basic a Standard o Premium in cache di Azure per Redis) per ottenere una maggiore velocità effettiva e una latenza inferiore.
- Abilita replica geografica. Se l'applicazione serve gli utenti in più aree, usare cache di Azure per Redis replica geografica in modo che la cache sia vicina al calcolo di ogni area.
- Esaminare la configurazione di rete. Usare collegamento privato o integrazione rete virtuale per ridurre gli hop di rete tra l'applicazione e la cache.
Passaggio 3: Ridurre le dimensioni dei token serializzati
Se le voci della cache dei token sono di grandi dimensioni, verificare se l'applicazione richiede token per risorse in eccesso. Ogni combinazione univoca di risorsa e ambito contribuisce alla dimensione dell'entrata della cache. Consolidare le chiamate API, laddove possibile, per ridurre il numero di token di accesso distinti memorizzati nella cache per utente.
Rimozione della cache Redis
Sintomo
Agli utenti viene chiesto di ripetere l'autenticazione senza alcun modello in base alla scadenza del token. Il monitoraggio di Redis mostra evicted_keys sta aumentando e used_memory si sta avvicinando al limite maxmemory.
Motivo
Quando Redis raggiunge il maxmemory limite, rimuove le chiavi in base alla configurazione maxmemory-policy. Il criterio predefinito (volatile-lru) rimuove le chiavi usate meno di recente che hanno una scadenza. Se l'istanza di Redis viene condivisa con altri dati dell'applicazione, gli elementi della cache dei token competono per lo spazio e possono essere espulse prematuramente.
Soluzione
Passaggio 1: Controllare il criterio di rimozione
Controllare i criteri di rimozione correnti:
redis-cli CONFIG GET maxmemory-policy
Per le cache dei token, volatile-lru (impostazione predefinita) è appropriato perché le voci della cache dei token hanno scadenze. Tuttavia, se altri dati senza data di scadenza consumano memoria, le voci del token vengono rimosse per prime.
Passaggio 2: Usare un'istanza di Redis dedicata
Isolare la cache dei token da altri dati dell'applicazione usando un'istanza redis dedicata:
{
"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");
});
Passaggio 3: Aumentare il limite di memoria Redis
Se un'istanza dedicata non è fattibile, aumentare l'impostazione maxmemory . In cache di Azure per Redis aumentare le prestazioni fino a un livello superiore o aumentare le dimensioni della cache.
Passaggio 4: Impostare le scadenze appropriate per le voci della cache
Impostare scadenze ragionevoli in modo che le voci non aggiornate vengano rimosse prima che venga esaurita la memoria:
services.Configure<MsalDistributedTokenCacheAdapterOptions>(options =>
{
options.AbsoluteExpirationRelativeToNow = TimeSpan.FromHours(12);
options.SlidingExpiration = TimeSpan.FromHours(2);
});
Crescita della tabella della cache distribuita SQL
Sintomo
La tabella della cache distribuita di SQL aumenta in modo continuo, consumando spazio su disco. Le query di database sulla tabella della cache sono lente nel tempo e potrebbero essere visualizzati avvisi relativi alle dimensioni delle tabelle o ai limiti di archiviazione.
Motivo
La cache distribuita SQL Server (Microsoft.Extensions.Caching.SqlServer) non rimuove automaticamente le voci scadute. Le voci scadute rimangono fino a quando non vengono eliminate esplicitamente, provocando una crescita illimitata della tabella, ridotte prestazioni delle query e consumo di spazio di archiviazione.
Soluzione
Passaggio 1: Configurare un processo di pulizia ricorrente
Creare un processo SQL Server Agent o un'attività pianificata per rimuovere periodicamente le voci scadute:
-- Delete expired entries from the SQL distributed cache table.
-- Schedule this query to run every 30 minutes.
DELETE FROM [dbo].[TokenCache]
WHERE ExpiresAtTime < GETUTCDATE();
Suggerimento
In database SQL di Azure, in cui SQL Server Agent non è disponibile, utilizzare Automazione di Azure, Funzioni di Azure con un trigger timer o Elastic Jobs per pianificare la pulizia.
Passaggio 2: Aggiungere un indice per una pulizia efficiente
Se la tabella della cache non dispone già di un indice nella colonna di scadenza, aggiungerne una per velocizzare l'operazione di eliminazione:
CREATE NONCLUSTERED INDEX IX_TokenCache_ExpiresAtTime
ON [dbo].[TokenCache] (ExpiresAtTime);
Passaggio 3: Monitorare le dimensioni della tabella
Aggiungere il monitoraggio per tenere traccia del numero di righe e delle dimensioni della tabella nel tempo:
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];
Passaggio 4: Prendere in considerazione il passaggio a Redis
Se la gestione della pulizia della cache SQL è complessa, passare a Redis, che gestisce automaticamente la scadenza tramite il meccanismo TTL predefinito:
// Replace SQL distributed cache with Redis.
services.AddStackExchangeRedisCache(options =>
{
options.Configuration = Configuration.GetConnectionString("Redis");
});
Suggerimenti generali sulla risoluzione dei problemi
Usare questi suggerimenti quando il problema non corrisponde a uno scenario specifico in questo articolo.
Verificare che la cache sia in uso
Aggiungere la registrazione temporanea per confermare che i token vengono letti e scritti nella cache:
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;
};
});
Verificare la presenza di più registrazioni della cache
Se nel codice di avvio sono presenti più chiamate a AddInMemoryTokenCaches() o AddDistributedTokenCaches(), l'ultima registrazione vince. Verificare che sia registrato un solo tipo di cache.
Esaminare la durata del token
I token di accesso hanno una durata limitata (in genere da 60 a 90 minuti). Se gli utenti segnalano la riautenticazione dopo questo periodo, il comportamento è previsto anziché un problema di cache. I token di aggiornamento ottengono automaticamente nuovi token di accesso e vengono archiviati nella cache. Se il token di aggiornamento è mancante o scaduto, l'utente deve ripetere l'autenticazione.
Eseguire il test con una cache pulita
Durante la diagnosi dei problemi, cancellare la cache per escludere voci danneggiate o non aggiornate:
- Cache in memoria: Riavviare l'applicazione.
-
Redis: Eseguire
FLUSHDBnel database della cache. - SQL Server: Elimina tutte le righe dalla tabella della cache.
Cache dei token vuota dopo il riavvio dell'applicazione
Sintomo
Gli utenti devono ripetere l'autenticazione dopo il riavvio o la ridistribuzione dell'applicazione. La cache distribuita appare vuota o i token non sono persistenti.
Motivo
Questo problema si verifica in genere quando si usa una cache in memoria (AddInMemoryTokenCaches()) o la cache di memoria distribuita non persistente (AddDistributedMemoryCache()) nell'ambiente di produzione. Nessuna delle due opzioni rende persistenti i token tra i riavvii dell'applicazione.
AddDistributedMemoryCache() registra un'implementazione IDistributedCache che archivia i dati in memoria. Nonostante il nome "distribuito", non rende persistenti i dati esternamente ed è destinato solo allo sviluppo e ai test.
Soluzione
Passare a una cache distribuita permanente:
// 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();
Avvertimento
Non confondere AddDistributedMemoryCache() con una cache distribuita persistente. Usare AddStackExchangeRedisCache() (Redis), AddDistributedSqlServerCache() (SQL Server) o un'altra implementazione persistente IDistributedCache per i carichi di lavoro di produzione.