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.
Après Microsoft Authentication Library (MSAL) acquiert un jeton, il met en cache ce jeton. Les applications clientes publiques (applications de bureau et mobiles) doivent essayer d’obtenir un jeton à partir du cache avant d’acquérir un jeton par une autre méthode. Les méthodes d’acquisition sur les applications clientes confidentielles gèrent elles-mêmes le cache. Cet article traite de la sérialisation par défaut et personnalisée du cache de jetons dans MSAL.NET.
Résumé
La recommandation est la suivante :
- Lors de l’écriture d’applications mobiles, la mise en cache est déjà préconfigurée par MSAL.
- Lors de l’écriture d’une application de bureau, utilisez le cache de jetons multiplateforme, comme expliqué dans les applications de bureau.
- Lors de l’écriture de nouvelles applications clientes confidentielles (applications web, API web ou applications de service à service ou démon, utilisez Microsoft. Identity.Web en tant qu’API de niveau supérieur. Il offre une intégration avec ASP.NET Core, ASP.NET Classic et fonctionne également autonome.
- Les applications clientes confidentielles existantes qui tirent parti de MSAL.NET directement peuvent continuer à le faire.
- Les applications web et les API web doivent utiliser un cache de jetons distribué (par exemple, Redis, SQL Server, Azure Cosmos DB) conjointement avec un cache de mémoire limité.
- Le chiffrement au repos peut être configuré facultativement à l’aide de ASP.NET Core Data Protection.
- Les applications web peuvent également s’appuyer sur des cookies de session ; Toutefois, cette option n’est pas recommandée en raison de la taille des cookies.
- Les applications de service à service et les applications démon peuvent s’appuyer uniquement sur un cache en mémoire. Si votre application sert de nombreux locataires, configurez une stratégie d’éviction.
- Les jetons d’identité managée sont mis en cache uniquement en mémoire.
- Clients confidentiels utilisant Microsoft. Identity.Web
- Clients confidentiels utilisant MSAL.NET
- Applications de bureau
- Applications mobiles
- Écrire votre propre cache
Le package NuGet Microsoft.Identity.Web.TokenCache fournit la sérialisation du cache de jetons au sein de la bibliothèque Microsoft.Identity.Web. La bibliothèque fournit une intégration à la fois ASP.NET Core et ASP.NET Classic, et ses abstractions peuvent être utilisées pour piloter d’autres infrastructures d’application web ou d’API.
Note
Les exemples ci-dessous concernent ASP.NET Core. Pour ASP.NET le code est similaire, consultez l’exemple ms-identity-aspnet-wepapp-openidconnect d’application web pour une implémentation de référence.
| Méthode d’extension | Description |
|---|---|
| AddInMemoryTokenCaches | Crée un cache temporaire en mémoire pour le stockage et la récupération de jetons. Les caches de jetons en mémoire sont plus rapides que les autres types de cache, mais leurs jetons ne sont pas conservés entre les redémarrages de l’application et vous ne pouvez pas contrôler la taille du cache. Les caches en mémoire conviennent aux applications qui n’exigent pas que les jetons soient conservés entre les redémarrages de l’application. Utilisez un cache de jetons en mémoire dans les applications qui participent à des scénarios d’authentification machine à machine tels que des services, des démons et d’autres qui utilisent AcquireTokenForClient (l’octroi d’informations d’identification du client). Les caches de jetons en mémoire sont également appropriés pour les exemples d’applications et pendant le développement d’applications locales. Les versions 1.19.0+ de Microsoft.Identity.Web partagent un cache de jetons en mémoire entre toutes les instances de l’application. |
| AddSessionTokenCaches | Le cache de jetons est lié à la session utilisateur. Cette option n’est pas idéale si le jeton d’ID contient de nombreuses revendications, car le cookie devient trop volumineux. |
AddDistributedTokenCaches |
Le cache de jeton est un adaptateur par rapport à l’implémentation de IDistributedCache ASP.NET Core. Il vous permet de choisir entre un cache de mémoire distribuée, un cache Redis, un NCache distribué ou un cache SQL Server. Pour plus d’informations sur les IDistributedCache implémentations, consultez Cache de mémoire distribuée. |
Cache de jetons en mémoire
Voici un exemple de code qui utilise le cache en mémoire dans la méthode ConfigureServices de la classe Startup dans une application ASP.NET Core :
using Microsoft.Identity.Web;
public class Startup
{
const string scopesToRequest = "user.read";
public void ConfigureServices(IServiceCollection services)
{
// code before
services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme)
.AddMicrosoftIdentityWebApp(Configuration)
.EnableTokenAcquisitionToCallDownstreamApi(new string[] { scopesToRequest })
.AddInMemoryTokenCaches();
// code after
}
// code after
}
AddInMemoryTokenCaches peut être utilisé en production si vous demandez uniquement des jetons d’application. Si vous utilisez des jetons utilisateur, envisagez d’utiliser un cache de jetons distribué.
Le code de configuration du cache de jetons est similaire entre les applications web ASP.NET Core et les API web.
Caches de jetons distribués
Voici des exemples de caches distribués possibles :
// or use a distributed Token Cache by adding
services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme)
.AddMicrosoftIdentityWebApp(Configuration)
.EnableTokenAcquisitionToCallDownstreamApi(new string[] { scopesToRequest }
.AddDistributedTokenCaches();
// Distributed token caches have a L1/L2 mechanism.
// L1 is in memory, and L2 is the distributed cache
// implementation that you will choose below.
// You can configure them to limit the memory of the
// L1 cache, encrypt, and set eviction policies.
services.Configure<MsalDistributedTokenCacheAdapterOptions>(options =>
{
// Optional: Disable the L1 cache in apps that don't use session affinity
// by setting DisableL1Cache to 'true'.
options.DisableL1Cache = false;
// Or limit the memory (by default, this is 500 MB)
options.L1CacheOptions.SizeLimit = 1024 * 1024 * 1024; // 1 GB
// You can choose if you encrypt or not encrypt the cache
options.Encrypt = false;
// And you can set eviction policies for the distributed
// cache.
options.SlidingExpiration = TimeSpan.FromHours(1);
});
// Then, choose your implementation of distributed cache
// -----------------------------------------------------
// good for prototyping and testing, but this is NOT persisted and it is NOT distributed - do not use in production
services.AddDistributedMemoryCache();
// Or a Redis cache
// Requires the Microsoft.Extensions.Caching.StackExchangeRedis NuGet package
services.AddStackExchangeRedisCache(options =>
{
options.Configuration = "localhost";
options.InstanceName = "SampleInstance";
});
// You can even decide if you want to repair the connection
// with Redis and retry on Redis failures.
services.Configure<MsalDistributedTokenCacheAdapterOptions>(options =>
{
options.OnL2CacheFailure = (ex) =>
{
if (ex is StackExchange.Redis.RedisConnectionException)
{
// action: try to reconnect or something
return true; //try to do the cache operation again
}
return false;
};
});
// Or even a SQL Server token cache
// Requires the Microsoft.Extensions.Caching.SqlServer NuGet package
services.AddDistributedSqlServerCache(options =>
{
options.ConnectionString = _config["DistCache_ConnectionString"];
options.SchemaName = "dbo";
options.TableName = "TestCache";
});
// Or an Azure Cosmos DB cache
// Requires the Microsoft.Extensions.Caching.Cosmos NuGet package
services.AddCosmosCache((CosmosCacheOptions cacheOptions) =>
{
cacheOptions.ContainerName = Configuration["CosmosCacheContainer"];
cacheOptions.DatabaseName = Configuration["CosmosCacheDatabase"];
cacheOptions.ClientBuilder = new CosmosClientBuilder(Configuration["CosmosConnectionString"]);
cacheOptions.CreateIfNotExists = true;
});
Pour en savoir plus, consultez :
- Chiffrement du cache distribué et autres options avancées
- Gérer l’éviction du cache L2
- Configurer un cache Redis dans Docker
- Troubleshooting
L’utilisation du cache distribué est présentée dans le tutoriel de l’application web ASP.NET Core, à la section cache de jetons de la phase 2-2.
Surveiller les ratios d’accès au cache et les performances du cache
MSAL expose des métriques importantes dans le cadre de l’objet AuthenticationResult.AuthenticationResultMetadata . Vous pouvez enregistrer ces métriques pour évaluer l’intégrité de votre application.
| Metric | Sens | Quand déclencher une alarme ? |
|---|---|---|
DurationTotalInMs |
Temps total passé dans MSAL, y compris les appels réseau et le cache. | Alarme sur une latence élevée globale (> 1 seconde). La valeur dépend de la source du jeton. Depuis le cache : un accès au cache. À partir de Microsoft Entra ID : deux accès au cache plus un appel HTTP. Le premier appel (par processus) prend plus de temps en raison d’un appel HTTP supplémentaire. |
DurationInCacheInMs |
Temps passé au chargement ou à l’enregistrement du cache de jetons, personnalisé par le développeur de l’application (par exemple, enregistrer dans Redis). | Alarme lors de pics. |
DurationInHttpInMs |
Temps passé à effectuer des appels HTTP à Microsoft Entra ID. | Alarme lors de pics. |
TokenSource |
Source du jeton. Les jetons sont récupérés à partir du cache beaucoup plus rapidement (par exemple, ~100 ms par rapport à ~700 ms). Peut être utilisé pour surveiller et alarmer le taux d’accès au cache. | Utiliser avec DurationTotalInMs. |
CacheRefreshReason |
Raison de la récupération du jeton d’accès auprès du fournisseur d’identité. | Utiliser avec TokenSource. |
Approximations de taille
Lorsque vous utilisez un cache de jetons, il est important de prendre en compte la taille potentielle du cache, en particulier pour les applications hautement disponibles et distribuées. Lorsque les utilisateurs se connectent, il y aura une entrée de cache pour chaque utilisateur, d’environ 7 Ko de taille. La taille sera plus grande si vous appelez plusieurs API en aval. Pour l’authentification de service à service, il y aura une entrée de cache pour chaque locataire et pour chaque API en aval, d’une taille d’environ 2 Ko.
Les estimations détaillées sont répertoriées ci-dessous.
Flux d’application (AcquireTokenForClient, AcquireTokenForManagedIdentity)
- Seuls les jetons d’accès sont mis en cache. Un jeton d’environ 2 à 3 Ko lorsqu’il est conservé. Il y aura 1 jeton par ID client d’application * locataires * ressources en aval. Par exemple, une application multilocataire servant 1000 locataires et nécessitant des jetons pour Graph et SharePoint utilisera : 3 Ko * 1000 * 2, c’est-à-dire environ 6 Mo.
Site web appelant une API web en aval (AcquireTokenByAuthCode)
- Jetons d’accès : 4 Ko ; 1 jeton par ID client d’application * utilisateur * locataire * ressource en aval.
- Jeton d’actualisation : 2 Ko ; 1 jeton par ID d’application client * utilisateur.
- Jeton d’ID – 2 Ko ; 1 jeton par ID d’application client * utilisateur * nombre de locataires dans lesquels cet utilisateur se connecte.
Note
Nous vous recommandons vivement d’utiliser pour cela les API de plus haut niveau via Microsoft.Identity.Web, et non MSAL directement. Les considérations relatives à la mise en cache sont les mêmes.
API web appelant d’autres API web (AcquireTokenOnBehalfOf)
Identique au scénario de site web, mais il y aura 1 nœud pour chaque session, et non pour chaque utilisateur. Par défaut, MSAL identifie une session en hachage de l’assertion en amont, mais cela peut être modifié. Consultez les processus OBO de longue durée.
Note
Nous vous recommandons vivement d’utiliser pour cela les API de plus haut niveau de Microsoft.Identity.Web, et non MSAL directement. Les considérations relatives à la mise en cache sont les mêmes.
Types de cache de jetons
MSAL.NET fonctionne avec deux types de caches de jetons : utilisateur et application.
Cache des jetons d’application qui contient des jetons d’accès pour cette application. Elle est conservée et mise à jour en mode silencieux lors de l’appel d’AcquireTokenForClient.
Le cache de jetons utilisateur contient des jetons d’identité, des jetons d’accès et des jetons d’actualisation pour les comptes avec lesquels MSAL.NET interagit. Elle est utilisée et mise à jour silencieusement si nécessaire lors de l’appel à AcquireTokenSilent. Elle est mise à jour par chaque méthode d’acquisition de jetons, à l’exception d’AcquireTokenForClient qui utilise uniquement le cache d’application.
Étapes suivantes
Les exemples suivants illustrent la sérialisation du cache de jetons.
| Sample | Platform | Description |
|---|---|---|
| active-directory-dotnet-desktop-msgraph-v2 | Application de bureau (WPF) | application de bureau Windows .NET (WPF) qui appelle l’API Microsoft Graph.
|
| active-directory-dotnet-v1-to-v2 | Ordinateur de bureau (console) | Ensemble de solutions Visual Studio qui illustrent la migration d’applications Azure AD v1.0 (à l’aide de la bibliothèque ADAL.NET) vers des applications Plateforme d'identités Microsoft (à l’aide de MSAL.NET). |
| ms-identity-aspnet-webapp-openidconnect | ASP.NET (net472) | Exemple de sérialisation du cache de jetons dans une application ASP.NET MVC (à l’aide de MSAL.NET). |