Remarque
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de vous connecter ou de modifier des répertoires.
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de modifier des répertoires.
Cet article vous aide à diagnostiquer et résoudre les problèmes de cache de jetons dans Microsoft. Identity.Web. Les problèmes de cache de jeton peuvent entraîner des échecs d’authentification, des performances détériorées ou des invites de connexion inattendues. Pour obtenir une vue d’ensemble du fonctionnement de la mise en cache des jetons dans Microsoft. Identity.Web, consultez Vue d’ensemble du cachetoken.
Prerequisites
Avant de résoudre les problèmes, vérifiez les points suivants :
- Vous utilisez une version prise en charge de Microsoft. Identity.Web.
- Votre application dispose d’une mise en cache de jetons configurée dans
Program.csouStartup.cs. - Vous avez accès aux journaux d’application et, le cas échéant, à votre infrastructure de cache distribué.
Activer la journalisation et les diagnostics du cache de jetons
Activez la journalisation détaillée en tant que première étape de diagnostic. Microsoft. Identity.Web utilise l’infrastructure de journalisation ASP.NET Core et émet des événements via le Microsoft Authentication Library (MSAL).
Activer la journalisation MSAL
Définissez à Debug le niveau de journal pour les bibliothèques d’identités dans votre appsettings.json:
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.Identity.Web": "Debug",
"Microsoft.IdentityModel": "Debug"
}
}
}
S’abonner aux événements de cache MSAL
S’abonner aux notifications d'événements du cache de jetons MSAL pour suivre les accès au cache, les ratés et l’activité de sérialisation :
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;
};
});
Surveiller les métriques de cache
Pour la surveillance de la production, effectuez le suivi de ces métriques clés :
- Taux d’accès au cache : un faible taux d’accès indique que les jetons ne sont pas récupérés à partir du cache.
- Latence du cache L2 : une latence élevée suggère un problème de connectivité ou de performances de cache distribué.
- Erreurs de sérialisation du cache : les erreurs de lecture ou d’écriture indiquent une incompatibilité de version ou de corruption.
- Consommation de mémoire : une croissance soutenue peut indiquer des stratégies d’éviction manquantes.
Échecs de connexion du cache distribué (L2)
Symptôme
Les journaux d’application affichent des erreurs de délai d’expiration de connexion ou des échecs d’authentification intermittents. Les utilisateurs rencontrent des retards de connexion et vous voyez des exceptions telles que :
Microsoft.Extensions.Caching.StackExchangeRedis.RedisCache:
StackExchange.Redis.RedisConnectionException:
No connection is active/available to service this operation.
Ou pour SQL Server cache distribué :
Microsoft.Data.SqlClient.SqlException:
A network-related or instance-specific error occurred while
establishing a connection to SQL Server.
La cause
Le magasin de stockage de cache distribué (Redis ou SQL Server) est inaccessible. Les causes courantes sont les suivantes :
- Chaîne de connexion incorrecte ou informations d'identification expirées.
- Règles de pare-feu réseau bloquant la connexion à partir de l’hôte de l’application.
- Le service de cache est en panne ou en cours de maintenance.
- Incompatibilité de configuration SSL/TLS entre le client et le serveur de cache.
Étapes de diagnostic
Procédez comme suit pour identifier l’échec de connexion :
- Vérifiez la connectivité. À partir de l’hôte de l’application, testez la connexion à Redis ou SQL Server en utilisant
Test-NetConnection(PowerShell) ouredis-cli. - Vérifiez le chaîne de connexion. Vérifiez que le chaîne de connexion correspond au nom d'hôte, au port et aux informations d'identification du serveur de cache.
- Passez en revue les règles de pare-feu. Dans Azure, vérifiez que le service d’application ou le réseau virtuel peut atteindre la ressource de cache.
- Vérification de l’intégrité du service. Dans le portail Azure, passez en revue l’intégrité et les métriques de votre instance Azure Cache pour Redis ou SQL Database.
Solution
Step 1 : Corrigez la chaîne de connexion
Vérifiez la chaîne de connexion dans votre appsettings.json :
{
"ConnectionStrings": {
"Redis": "your-redis-instance.redis.cache.windows.net:6380,password=your-access-key,ssl=True,abortConnect=False"
}
}
Important
Définissez abortConnect=False dans le chaîne de connexion Redis. Ce paramètre permet à l’application de se reconnecter automatiquement après les échecs de connexion temporaires plutôt que de lever immédiatement.
Étape 2 : Configurer la nouvelle tentative et la résilience
Configurez le OnL2CacheFailure rappel afin que votre application se dégrade correctement lorsque le cache distribué n’est pas disponible temporairement :
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);
});
Étape 3 : Ouvrir des règles de pare-feu
Si l’application s’exécute dans Azure App Service et que le cache se trouve dans un réseau virtuel, ajoutez les adresses IP sortantes App Service à la liste d'autorisation du pare-feu du cache.
Erreurs de désérialisation du cache
Symptôme
Après avoir mis à niveau Microsoft.Identity.Web ou MSAL.NET, l’application génère des exceptions de désérialisation lors de la lecture à partir du cache distribué. Les utilisateurs doivent se reconnecter, et vous voyez des exceptions telles que :
System.Text.Json.JsonException:
The JSON value could not be converted to the expected type.
Ou:
Microsoft.Identity.Client.MsalClientException:
Error code: json_parse_failed
La cause
Le format de sérialisation du cache de jetons a changé entre les versions de la bibliothèque. Les jetons mis en cache par la version précédente ne peuvent pas être désérialisés par la nouvelle version. Ce problème se produit le plus souvent pendant les mises à niveau principales de MSAL.NET ou de Microsoft. Identity.Web.
Solution
Option A : Effacer le cache
Le correctif le plus simple consiste à effacer toutes les entrées dans le cache distribué. Les utilisateurs se réauthentifient une fois et les jetons suivants sont écrits dans le nouveau format.
Videz le cache Redis :
redis-cli FLUSHDB
Ou effacez la table de cache distribuée SQL Server :
DELETE FROM [dbo].[TokenCache];
Note
L’effacement du cache entraîne la réauthentification de tous les utilisateurs actifs. Planifiez cette opération pendant une fenêtre de maintenance si votre application sert une grande base d’utilisateurs.
Option B : Gérer les erreurs de désérialisation correctement
Configurez l’adaptateur de cache pour traiter les échecs de désérialisation comme des erreurs de cache plutôt que des erreurs irrécupérables :
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.
};
});
Avec cette approche, les entrées de cache affectées sont automatiquement remplacées lorsque les utilisateurs se réauthentiquent et qu’aucune vidage manuel du cache n’est nécessaire.
Incompatibilité de clé de chiffrement entre les serveurs
Symptôme
Des erreurs de désérialisation se produisent dans les déploiements multi-instances même si le cache distribué fonctionne. Les jetons mis en cache par une instance de serveur ne peuvent pas être lus par un autre. Vous voyez des erreurs json_parse_failed ou IDW10802 dans les journaux.
La cause
Lorsque le chiffrement du cache est activé (options.Encrypt = true), Microsoft. Identity.Web utilise ASP.NET Core Protection des données pour chiffrer les entrées du cache. Par défaut, chaque instance de serveur génère ses propres clés de protection des données, afin qu’une instance ne puisse pas déchiffrer les entrées écrites par une autre.
Solution
Configurez ASP.NET Core Protection des données pour partager des clés de chiffrement sur toutes les instances de serveur.
Option A : Stockage Blob Azure + Azure Key Vault (recommandé pour les déploiements 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;
});
Cette configuration stocke l’anneau de clés de protection des données dans Stockage Blob Azure et protège les clés au repos avec Azure Key Vault. Toutes les instances d’application qui accèdent au même objet blob et à la même clé peuvent chiffrer et déchiffrer les entrées de cache des autres.
Option B : Système de fichiers partagé avec protection des certificats
builder.Services.AddDataProtection()
.PersistKeysToFileSystem(new DirectoryInfo(@"\\server\share\keys"))
.ProtectKeysWithCertificate(certificate);
Conseil / Astuce
Lors de la rotation du certificat de protection des données, utilisez cette option UnprotectKeysWithAnyCertificate pour inclure les certificats actuels et précédents. Cela permet le déchiffrement des clés qui ont été protégées avec l’ancien certificat pendant la fenêtre de rotation.
Croissance de la mémoire avec le cache en mémoire
Symptôme
La consommation de mémoire d’application augmente régulièrement au fil du temps. Si l’application s’exécute dans un conteneur ou un plan App Service avec une limite de mémoire fixe, elle finit par redémarrer ou lever OutOfMemoryException. La surveillance montre la croissance du tas managé sans récupération par la collecte des ordures.
La cause
L’utilisation AddInMemoryTokenCaches() sans limites de taille entraîne une croissance du cache non limitée. Cette situation est particulièrement problématique dans les applications qui servent de nombreux utilisateurs, car l’entrée de jeton de chaque utilisateur consomme indéfiniment de la mémoire.
Par défaut, MemoryCache n'impose pas de taille maximale et ne supprime pas les entrées à moins qu'une stratégie d’expiration ne soit définie.
Solution
Option A : Définir une limite de taille et une expiration glissante
Configurez le cache en mémoire avec des stratégies d’expiration :
services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme)
.AddMicrosoftIdentityWebApp(Configuration)
.EnableTokenAcquisitionToCallDownstreamApi()
.AddInMemoryTokenCaches();
services.Configure<MsalMemoryTokenCacheOptions>(options =>
{
options.AbsoluteExpirationRelativeToNow = TimeSpan.FromHours(12);
options.SlidingExpiration = TimeSpan.FromHours(2);
});
Avec ces paramètres, les entrées expirent après 12 heures, quel que soit l’accès, et les entrées inactives pendant 2 heures sont supprimées précédemment.
Option B : Basculer vers un cache distribué
Pour les applications avec de nombreux utilisateurs simultanés, un cache en mémoire n’est pas mis à l’échelle. Basculez vers un cache distribué tel que Redis :
services.AddStackExchangeRedisCache(options =>
{
options.Configuration = Configuration.GetConnectionString("Redis");
});
services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme)
.AddMicrosoftIdentityWebApp(Configuration)
.EnableTokenAcquisitionToCallDownstreamApi()
.AddDistributedTokenCaches();
Un cache distribué décharge la mémoire à partir du processus d’application, conserve les jetons entre les redémarrages et prend en charge les déploiements à plusieurs instances.
Option C : Utiliser l’architecture hybride L1/L2
Microsoft. Identity.Web prend en charge une approche hybride qui combine un cache L1 en mémoire rapide avec un cache L2 distribué persistant. Configurez le cache hybride 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)
};
});
Avec la mise en cache L1/L2, les jetons fréquemment consultés sont servis à partir de la mémoire (L1) avec une latence inférieure à milliseconde. Le cache L2 fournit une cohérence entre instances et persistance. Le cache L1 utilise des expirations courtes pour limiter la croissance de la mémoire.
Invites de consentement ou d’authentification multifacteur répétées
Symptôme
Les utilisateurs sont invités à plusieurs reprises à demander l’authentification multifacteur (MFA) ou le consentement même s’ils ont effectué ces étapes récemment. L’application ne trouve pas de jetons existants dans le cache.
La cause
Ce problème se produit lorsque la recherche dans le cache de jetons n’arrive pas à associer une entrée mise en cache au compte utilisateur actuel. Les causes courantes sont les suivantes :
- La clé de cache diffère de celle utilisée lorsque le jeton a été stocké. Cette situation peut se produire si le contexte
HomeAccountIdou de locataire change. - L'application exécute plusieurs instances derrière un équilibreur de charge avec mise en cache en mémoire, et les requêtes sont dirigées vers une instance qui n'a pas le jeton de l'utilisateur.
- Les revendications ou étendues demandées ont changé, de sorte que le jeton mis en cache ne répond pas à la nouvelle exigence.
- L’affinité de session n’est pas activée. Les utilisateurs sont donc acheminés vers différentes instances qui n’ont pas leurs jetons mis en cache.
Étapes de diagnostic
Suivez ces étapes pour identifier la raison pour laquelle les jetons ne sont pas trouvés dans le cache :
- Vérifiez le type de cache. Si vous utilisez
AddInMemoryTokenCaches()dans un déploiement à plusieurs instances, les jetons mis en cache sur une instance ne sont pas disponibles sur une autre. Basculez vers un cache distribué. - Vérifiez l’identificateur du compte. Activez la journalisation de niveau débogage et recherchez le
HomeAccountId. Vérifiez que l’identificateur est cohérent entre les requêtes. - Inspectez les périmètres. Vérifiez que les étendues demandées par
GetAccessTokenForUserAsynccorrespondent aux étendues à l’origine consentées. Une différence de portée pousse MSAL à demander un nouveau jeton. - Passez en revue les stratégies d’accès conditionnel. Une stratégie d’accès conditionnel Microsoft Entra ID qui nécessite une authentification pas à pas pour des ressources spécifiques entraîne des invites supplémentaires non liées à la mise en cache.
Solution
Étape 1 : Basculer vers la mise en cache distribuée
Si votre application exécute plusieurs instances, utilisez un cache distribué pour partager des jetons entre les instances :
services.AddStackExchangeRedisCache(options =>
{
options.Configuration = Configuration.GetConnectionString("Redis");
});
services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme)
.AddMicrosoftIdentityWebApp(Configuration)
.EnableTokenAcquisitionToCallDownstreamApi()
.AddDistributedTokenCaches();
Étape 2 : Vérifier les étendues cohérentes
Vérifiez que les étendues que vous demandez lors de l’acquisition de jetons correspondent aux étendues configurées lors de l’authentification :
// 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" });
Étape 3 : Activer l’affinité de session (solution de contournement temporaire)
Si vous ne pouvez pas basculer immédiatement vers un cache distribué, activez l’affinité de session (sessions sticky) sur votre équilibreur de charge. L’affinité de session achemine les requêtes d’un utilisateur vers la même instance. Cette approche est une solution de contournement temporaire avec des limitations d’extensibilité.
Problèmes de performances du cache
Symptôme
La récupération de jetons est lente et les appels d’API en aval ont augmenté la latence. La surveillance montre des temps de réponse moyens élevés pour les demandes d’acquisition de jetons. La latence ne provient pas du fournisseur d’identité : les jetons sont servis à partir du cache.
La cause
Les problèmes de performances du cache résultent généralement des suivants :
- Latence élevée du cache L2. Le cache distribué est sous une charge importante, géographiquement éloigné de l’application ou utilise un niveau de service sous-dimensionné.
- Entrées de cache de jeton volumineuses. Les applications qui génèrent des jetons de cache pour de nombreuses ressources par utilisateur peuvent produire des entrées de cache sérialisées volumineuses lentes à lire et écrire.
- Aucun cache L1. Chaque acquisition de jetons passe au cache distribué sur le réseau, même pour les jetons utilisés fréquemment.
Solution
Étape 1 : Activer le cache en mémoire L1
Le cache L1 stocke les jetons fréquemment consultés dans la mémoire du processus, évitant ainsi les allers-retours réseau vers L2 :
services.Configure<MsalDistributedTokenCacheAdapterOptions>(options =>
{
options.L1CacheOptions = new MsalMemoryTokenCacheOptions
{
AbsoluteExpirationRelativeToNow = TimeSpan.FromMinutes(5),
SlidingExpiration = TimeSpan.FromMinutes(2)
};
});
Avec cette configuration, les jetons servis à partir de L1 ont une latence inférieure à milliseconde. Les jetons qui ne sont pas dans L1 se replient sur le cache distribué L2.
Étape 2 : Optimiser le niveau de cache distribué
Si la latence du cache L2 est élevée, tenez compte des actions suivantes :
- Effectuez un scale-up de l’instance Redis. Passez à un niveau supérieur (par exemple, de Base à Standard ou Premium dans Azure Cache pour Redis) pour obtenir plus de débit et une latence inférieure.
- Activez la géo-réplication. Si votre application sert des utilisateurs dans plusieurs régions, utilisez Azure Cache pour Redis géoréplication afin que le cache soit proche du calcul de chaque région.
- Passez en revue la configuration du réseau. Utilisez Private Link ou l’intégration au réseau virtuel pour réduire les tronçons réseau entre l’application et le cache.
Étape 3 : Réduire la taille du jeton sérialisé
Si les entrées du cache de jeton sont volumineuses, vérifiez si l’application demande des jetons pour plus de ressources que nécessaire. Chaque combinaison unique de ressources et de périmètres ajoute à la taille d’entrée du cache. Consolidez les appels d’API dans la mesure du possible pour réduire le nombre de jetons d’accès distincts mis en cache par utilisateur.
Éviction du cache Redis
Symptôme
Les utilisateurs sont de manière intermittente invités à s'authentifier à nouveau sans motif prévisible, qui n'est pas liée à l'expiration du jeton. La surveillance de Redis montre que evicted_keys augmente et que used_memory s'approche de la limite maxmemory.
La cause
Lorsque Redis atteint sa maxmemory limite, il supprime les clés en fonction de la configuration maxmemory-policy. La stratégie par défaut (volatile-lru) supprime les clés les moins récemment utilisées qui ont une expiration. Si l’instance Redis est partagée avec d’autres données d’application, les entrées du cache de jetons entrent en concurrence pour l’espace et peuvent être supprimées prématurément.
Solution
Étape 1 : Vérifier la stratégie d’éviction
Vérifiez la stratégie d’éviction actuelle :
redis-cli CONFIG GET maxmemory-policy
Pour les caches de jetons, volatile-lru (valeur par défaut) est approprié, car les entrées du cache de jetons ont des expirations. Toutefois, si d’autres données sans expiration consomment de la mémoire, les entrées de jeton sont supprimées en premier.
Étape 2 : Utiliser une instance Redis dédiée
Isolez le cache de jetons d’autres données d’application à l’aide d’une instance Redis dédiée :
{
"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");
});
Étape 3 : Augmenter la limite de mémoire Redis
Si une instance dédiée n’est pas réalisable, augmentez le maxmemory paramètre. Dans Azure Cache pour Redis, effectuez un scale-up jusqu’à un niveau supérieur ou augmentez la taille du cache.
Étape 4 : Définir les expirations d’entrée de cache appropriées
Définissez des expirations raisonnables afin que les entrées obsolètes soient supprimées avant l’expiration de la mémoire :
services.Configure<MsalDistributedTokenCacheAdapterOptions>(options =>
{
options.AbsoluteExpirationRelativeToNow = TimeSpan.FromHours(12);
options.SlidingExpiration = TimeSpan.FromHours(2);
});
Croissance de la table de cache distribuée SQL
Symptôme
La table de cache distribué SQL augmente en continu, consommant de l’espace disque. Les requêtes de base de données sur la table de cache sont lentes au fil du temps et vous pouvez voir des avertissements sur la taille de la table ou les limites de stockage.
La cause
Le cache distribué SQL Server (Microsoft.Extensions.Caching.SqlServer) ne supprime pas automatiquement les entrées expirées. Les entrées expirées restent jusqu'à ce qu'elles soient explicitement purgées, ce qui provoque une croissance illimitée de la table, une dégradation des performances des requêtes et une consommation de stockage.
Solution
Étape 1 : Configurer un travail de nettoyage périodique
Créez un travail SQL Server Agent ou une tâche planifiée pour supprimer périodiquement les entrées expirées :
-- Delete expired entries from the SQL distributed cache table.
-- Schedule this query to run every 30 minutes.
DELETE FROM [dbo].[TokenCache]
WHERE ExpiresAtTime < GETUTCDATE();
Conseil / Astuce
Dans Azure SQL Database, où SQL Server Agent n'est pas disponible, utilisez Azure Automation, Azure Functions avec un déclencheur basé sur une minuterie, ou les Elastic Jobs pour planifier le nettoyage.
Étape 2 : Ajouter un index pour un nettoyage efficace
Si la table de cache n’a pas encore d’index sur la colonne d’expiration, ajoutez-en un pour accélérer l’opération de suppression :
CREATE NONCLUSTERED INDEX IX_TokenCache_ExpiresAtTime
ON [dbo].[TokenCache] (ExpiresAtTime);
Étape 3 : Surveiller la taille de la table
Ajoutez une surveillance pour suivre le nombre de lignes et la taille de la table au fil du temps :
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];
Étape 4 : Envisagez de passer à Redis
Si la gestion du nettoyage du cache SQL est fastidieuse, basculez vers Redis, qui gère automatiquement l’expiration par le biais de son mécanisme TTL intégré :
// Replace SQL distributed cache with Redis.
services.AddStackExchangeRedisCache(options =>
{
options.Configuration = Configuration.GetConnectionString("Redis");
});
Conseils généraux de dépannage
Utilisez ces conseils lorsque votre problème ne correspond pas à un scénario spécifique dans cet article.
Vérifier que le cache est utilisé
Ajoutez la journalisation temporaire pour confirmer que les jetons sont lus et écrits dans le 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;
};
});
Vérifier plusieurs enregistrements de cache
Si plusieurs appels vers AddInMemoryTokenCaches() ou AddDistributedTokenCaches() existent dans votre code de démarrage, la dernière inscription gagne. Vérifiez qu’un seul type de cache est inscrit.
Passer en revue la durée de vie du jeton
Les jetons d’accès ont une durée de vie finie (généralement 60 à 90 minutes). Si les utilisateurs signalent une réauthentification après cette période, le comportement est attendu plutôt qu’un problème de cache. Les jetons d’actualisation obtiennent de nouveaux jetons d’accès en mode silencieux et sont stockés dans le cache. Si le jeton d’actualisation est manquant ou expiré, l’utilisateur doit se réauthentifier.
Tester avec un cache propre
Lors du diagnostic des problèmes, effacez le cache pour exclure les entrées endommagées ou obsolètes :
- Cache en mémoire : Redémarrez l’application.
-
Redis : Exécutez
FLUSHDBsur la base de données du cache. - SQL Server : Supprimer toutes les lignes de la table de cache.
Cache de jeton vide après le redémarrage de l’application
Symptôme
Les utilisateurs doivent se réauthentifier après chaque redémarrage ou redéploiement de chaque application. Le cache distribué apparaît vide ou les jetons ne sont pas conservés.
La cause
Ce problème se produit généralement lorsque vous utilisez un cache en mémoire (AddInMemoryTokenCaches()) ou le cache de mémoire distribuée non persistant (AddDistributedMemoryCache()) en production. Aucune des options ne conserve les jetons entre les redémarrages de l’application.
AddDistributedMemoryCache() inscrit une IDistributedCache implémentation qui stocke les données en mémoire. Malgré le nom « distribué », il ne conserve pas les données en externe et est destiné uniquement au développement et au test.
Solution
Basculez vers un cache distribué persistant :
// 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();
Avertissement
Ne confondez AddDistributedMemoryCache() pas avec un cache distribué persistant. Utilisez AddStackExchangeRedisCache() (Redis), AddDistributedSqlServerCache() (SQL Server) ou une autre implémentation IDistributedCache persistante pour les charges de travail de production.