培训
认证
Microsoft Certified: Identity and Access Administrator Associate - Certifications
演示 Microsoft Entra ID 的功能,以将标识解决方案现代化、实现混合解决方案和实现标识治理。
After Microsoft Authentication Library (MSAL) acquires a token, it caches that token. Public client applications (desktop and mobile apps) should try to get a token from the cache before acquiring a token by another method. Acquisition methods on confidential client applications manage the cache themselves. This article discusses default and custom serialization of the token cache in MSAL.NET.
The recommendation is:
The Microsoft.Identity.Web.TokenCache NuGet package provides token cache serialization within the Microsoft.Identity.Web library. The library provides integration with both ASP.NET Core and ASP.NET Classic, and its abstractions can be used to drive other web app or API frameworks.
备注
The examples below are for ASP.NET Core. For ASP.NET the code is similar, see the ms-identity-aspnet-wepapp-openidconnect
web app sample for a reference implementation.
Extension method | Description |
---|---|
AddInMemoryTokenCaches | Creates a temporary cache in memory for token storage and retrieval. In-memory token caches are faster than other cache types, but their tokens aren't persisted between application restarts, and you can't control the cache size. In-memory caches are good for applications that don't require tokens to persist between app restarts. Use an in-memory token cache in apps that participate in machine-to-machine auth scenarios like services, daemons, and others that use AcquireTokenForClient (the client credentials grant). In-memory token caches are also good for sample applications and during local app development. Microsoft.Identity.Web versions 1.19.0+ share an in-memory token cache across all application instances. |
AddSessionTokenCaches | The token cache is bound to the user session. This option isn't ideal if the ID token contains many claims, because the cookie becomes too large. |
AddDistributedTokenCaches |
The token cache is an adapter against the ASP.NET Core IDistributedCache implementation. It enables you to choose between a distributed memory cache, a Redis cache, a distributed NCache, or a SQL Server cache. For details about the IDistributedCache implementations, see Distributed memory cache. |
Here's an example of code that uses the in-memory cache in the ConfigureServices method of the Startup class in an ASP.NET Core application:
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
is suitable in production if you request app-only tokens. If you use user tokens, consider using a distributed token cache.
Token cache configuration code is similar between ASP.NET Core web apps and web APIs.
Here are examples of possible distributed caches:
// 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;
});
For more information, see:
The usage of distributed cache is featured in the ASP.NET Core web app tutorial in the phase 2-2 token cache.
MSAL exposes important metrics as part of AuthenticationResult.AuthenticationResultMetadata object. You can log these metrics to assess the health of your application.
Metric | Meaning | When to trigger an alarm? |
---|---|---|
DurationTotalInMs |
Total time spent in MSAL, including network calls and cache. | Alarm on overall high latency (> 1 second). Value depends on token source. From the cache: one cache access. From Microsoft Entra ID: two cache accesses plus one HTTP call. First ever call (per-process) takes longer because of one extra HTTP call. |
DurationInCacheInMs |
Time spent loading or saving the token cache, which is customized by the app developer (for example, save to Redis). | Alarm on spikes. |
DurationInHttpInMs |
Time spent making HTTP calls to Microsoft Entra ID. | Alarm on spikes. |
TokenSource |
Source of the token. Tokens are retrieved from the cache much faster (for example, ~100 ms versus ~700 ms). Can be used to monitor and alarm the cache hit ratio. | Use with DurationTotalInMs . |
CacheRefreshReason |
Reason for fetching the access token from the identity provider. | Use with TokenSource . |
When using a token cache, it's important to consider the potential size of the cache, especially for highly-available and distributed applications. When users log in, there will be a cache entry for each user, around 7KB in size. The size will be larger if you are calling several downstream APIs. For service-to-service authentication, there will be a cache entry for each tenant and downstream API, around 2KB in size.
Detailed estimates are listed below.
备注
We strongly recommend using the higher level APIs from Microsoft.Identity.Web
for this and not MSAL directly. The caching considerations are the same.
Same as for web site scenario, but there will be 1 node for each session, not for each user. By default, MSAL identifies a session by hashing the upstream assertion, but this can be changed. See Long Running OBO Processes.
备注
We strongly recommend using the higher level APIs from Microsoft.Identity.Web
for this and not MSAL directly. The caching considerations are the same.
MSAL.NET operates with two types of token caches - user and application.
The application token cache which holds access tokens for this application. It's maintained and updated silently when calling AcquireTokenForClient.
The user token cache holds ID tokens, access tokens, and refresh tokens for accounts MSAL.NET interacts with. It's used and updated silently if needed when calling AcquireTokenSilent. It is updated by each token acquisition method, with the exception of AcquireTokenForClient which only uses the application cache.
The following samples illustrate token cache serialization.
Sample | Platform | Description |
---|---|---|
active-directory-dotnet-desktop-msgraph-v2 | Desktop (WPF) | Windows Desktop .NET (WPF) application that calls the Microsoft Graph API. |
active-directory-dotnet-v1-to-v2 | Desktop (console) | Set of Visual Studio solutions that illustrate the migration of Azure AD v1.0 applications (using ADAL.NET) to Microsoft identity platform applications (using MSAL.NET). |
ms-identity-aspnet-webapp-openidconnect | ASP.NET (net472) | Example of token cache serialization in an ASP.NET MVC application (using MSAL.NET). |
培训
认证
Microsoft Certified: Identity and Access Administrator Associate - Certifications
演示 Microsoft Entra ID 的功能,以将标识解决方案现代化、实现混合解决方案和实现标识治理。
文档
When users login to Web applications (web sites) using OpenID Connect, the web application receives an authorization code which it can redeem to acquire a token to call Web APIs.
Acquire a token from the cache (MSAL.NET) - Microsoft Authentication Library for .NET
Learn how to acquire an access token silently (from the token cache) using the Microsoft Authentication Library for .NET (MSAL.NET).
High availability considerations in MSAL.NET - Microsoft Authentication Library for .NET
Explore high availability considerations in MSAL.NET, including token cache, monitoring MSAL operations, logging, retry policy, and certificate rotation. Learn more now.