-
Notifications
You must be signed in to change notification settings - Fork 378
High availability
MSAL is used by many applications, both Microsoft internal and external. We treat scalability issues as high priority bugs. Using the latest version of the library ensures it has the latest scalability improvements.
Default behaviour: MSAL builds an internal in-memory cache of tokens when it fetches tokens from AAD.
Recommendation: Make sure you call AcquireTokenSilent method which first checks the cache for a valid token before making a call to AAD. For service-to-service calls, AcquireTokenForClient uses the token cache by default.
Default behaviour: Each PublicClientApplication (PCA) or ConfidentialClientApplication (CCA) maintains a token cache in memory.
Recommendation: Do not re-create a new application object for each token request, unless cache serialization is enabled (see next point), because once the application instance is garbage collected, the internal cache will be disposed of too.
Default behaviour: Using a singleton ConfidentialClientApplication tends to lead to slower performance, as each request has to search through many cache items. Based on the performed testing AcquireTokenForClient takes ~5ms with 10k cache items and ~95ms with 100k cache items. Performance testing wiki.
Recommendation: General strategy is to partition the cached data into smaller equal buckets, so that search is performed across the fewer number of cache items. The partition key could be anything that can equally divide the tokens, for example, tenant ID, client ID. Examples:
- Instead of one CCA, create a collection of CCA instances partitioned by your chosen data point.
- Add a serialization cache to the CCA instance, and use your chosen partition key as a key into the cache. This will make sure the internal CCA cache is reloaded with only the partitioned data (and not the whole set).
Default behaviour: MSAL maintains a secondary ADAL token cache for migration scenarios between ADAL and MSAL. ADAL cache operations are very slow. Recommendation: Disable ADAL cache if you are not interested in migrating from ADAL. This will make a BIG perf improvement - see perf measurements here.
Add WithLegacyCacheCompatibility(false) when constructing your app to disable ADAL caching.
Default behaviour: MSAL caches the tokens in memory. Each ConfidentialClientApplication instance has its own internal token cache. In-memory cache can be lost, for example, if the object instance is disposed or the whole application is stopped.
Recommendation: Use the cache read and write callbacks, exposed by MSAL, to persist the internal cache. Customers have reported good results when using Redis and other distributed cache stores. Details here.
Default behaviour: MSAL will retry failed 5xx requests once, then block similar requests for 1 minute.
Recommendation:
- Add your own retry logic around
AcquireToken*methods, using a library like Poly. - ESTS may reply with a 429 Too Many Requests that contains a Retry-After header. Make sure to obey this value, otherwise you will get throttled. More details about Retry-After
In web app and web API scenarios, it is recommended to use a new ConfidentialClientApplication on each session and to serialize in the same way - one token cache per session. This scales well and also increases security. The official samples show how to do this.
Default behaviour: An HttpClient is created for each PublicClientApplication / ConfidentialClientApplication. This does not scale well for web sites / web API where we recommend to have a ClientApplication object for each user session.
Recommendation: Provide your own scalable HttpClientFactory. On .NET Core we recommend that you inject the System.Net.Http.IHttpClientFactory. This is described in more detail here.
MSAL.NET supports auto refreshing longer lived tokens for several of the Microsoft services which supports Continuous Access Evaluation (CAE). Thus before writing your own background refresh please ensure you validate if your scenario is already covered with built-in MSAL capabilities.
By default, access tokens expire after 1h, and if AAD is busy when the tokens expire, your application will become unavailable because you cannot acquire a new access token and the old one is expired. You can improve the availability of your application by regularly forcing a refresh. We recommend to force a refresh every 30 min, or half the lifetime of the AT when this is a custom lifetime.
It is important NOT to force refresh every time. Doing so will cause your application to add significant load to AAD, and AAD will throttle you. Instead, do this on a background thread at regular intervals.
This is especially recommended in service to service calls (i.e. the Client Credential grant):
// ***On a background thread, invoke this every 30 min***
// (or half the lifetime of the AT)
IConfidentialClientApplication cca = ... // get or create the app, making sure it is bound to the token cache
try
{
await cca.AcquireTokenForClient(scopes)
.WithForceRefresh(true) // Do NOT force refresh every time!!
.ExecuteAsync();
// a successful call to the above ensures you have
// a fresh AT that can be used for the next 30 min
}
catch (MsalServiceException e)
{
// log the exception, but do not throw,
// in case AAD is busy, try again later
}For user flows, this can be done in a similar way by calling AcquireTokenSilent plus WithForceRefresh from a background thread.
- Home
- Why use MSAL.NET
- Is MSAL.NET right for me
- Scenarios
- Register your app with AAD
- Client applications
- Acquiring tokens
- MSAL samples
- Known Issues
- Acquiring a token for the app
- Acquiring a token on behalf of a user in Web APIs
- Acquiring a token by authorization code in Web Apps
- AcquireTokenInteractive
- WAM - the Windows broker
- .NET Core
- Maui Docs
- Custom Browser
- Applying an AAD B2C policy
- Integrated Windows Authentication for domain or AAD joined machines
- Username / Password
- Device Code Flow for devices without a Web browser
- ADFS support
- High Availability
- Regional
- Token cache serialization
- Logging
- Exceptions in MSAL
- Provide your own Httpclient and proxy
- Extensibility Points
- Clearing the cache
- Client Credentials Multi-Tenant guidance
- Performance perspectives
- Differences between ADAL.NET and MSAL.NET Apps
- PowerShell support
- Testing apps that use MSAL
- Experimental Features
- Proof of Possession (PoP) tokens
- Using in Azure functions
- Extract info from WWW-Authenticate headers
- SPA Authorization Code