-
Notifications
You must be signed in to change notification settings - Fork 343
Multi tenant client_credential use
If you use ASP.NET Core, you are encouraged to adopt Microsoft.Indentity.Web, which provides a higher level API over token acquisition and has better defaults. See Is MSAL.NET right for me?
MSAL maintains a token cache which grows with each token acquired. MSAL manages token lifetimes in a smart way, so you should use its cache. If your service needs to call N tenants, there will be potentially N tokens in MSAL's cache, each around 2Kb in size. N can be very large, there are > 1 million tenants in AAD and this number is growing.
// each ConfidentiClientApplication object maintains its own internal cache
ConfidentiClientApplication cca = ConfidentiClientApplicationBuilder
.WithCertificate(x509certificate)
.Create("client_id");
var result = cca.AcquireTokenForClient().WithSendX5C(true) // for SNI
.ExecuteAsync();
// use result.AccessToken and result.ExpiresOn to cache your own token
// Problem: cca goes out of scope and MSAL's internal cache is lost
The problem is that you'd be missing out on the pro-active refresh feature MSALs implement. With this feature, services receive tokens available for a long time (12h) and are instructed to refresh them for half that time (6h). This ensures that even if AAD / ESTS goes down, your service has a fresh token that is available for a long time.
Note: does not work for OBO, use pattern 2 instead
// When your service starts, create a singleton / static ConfidentialClientApplication
static ConfidentiClientApplication s_cca = ConfidentiClientApplicationBuilder
.WithCertificate(x509certificate)
.Create("client_id");
// Then, whenever you need a token, specify the authority
var result = await s_cca .AcquireTokenForClient("scope_for_downstream_api")
.WithAuthority("https://login.microsoft.com/<tenant_id>") // do NOT use common or organizations here
.WithSendX5C(true) // for SNI
.ExecuteAsync();
// You can monitor if the cache was hit
bool cacheHit = result.AuthenticationResult.AuthenticationResultMetadata.TokenSource == TokenSource.Cache;
- MSAL does not evict items from the cache, and at 2KB size per token, you could eventually go out of memory.
- MSAL 4.30+ only
- But if you are migrating from ADAL and haven't run out of memory, this will have the same memory profile.
- If you need to use different client IDs, then maintain a dictionary of <client_id> -> ConfidentialClientApplication
This is the North Star and works for OBO as well.
// In your app initialization define a cache
// See https://github.com/Azure-Samples/active-directory-dotnet-v1-to-v2/blob/master/ConfidentialClientTokenCache/Program.cs#L83 for several implementations
static var s_cache = InMemoryWithLRU / Redis / SqlServer / L1InMemroy_L2Distributed / etc.
// Then when you need a token
var cca = ConfidentialClientApplicationBuilder.Create("client_id")
.WithAuthority("https://login.microsoftonline.com/<tenantid>")
.WithCertificate(certificate)
.Build();
s_cache.Initialize(cca.AppTokenCache); // configure the CCA to use your token cache
var result = await app.AcquireTokenForClient(new[] {"https://graph.windows.net/.default"})
.WithSendX5C(true) // SNI
.ExecuteAsync();
- Microsoft.Identity.Web project has several high performance token cache implementations
- If you are using ASP.NET Core, consider using Microsoft.Identity.Web - it's a higher level API that takes care of many aspects for you
- If not, see this simple sample that shows how to use a token cache from Microsoft.Identity.Web in ANY application
- For best performance, in-memory caching with LRU policies plus optional distributed cache, use the L1/L2 cache or the InMemoryCache.
- 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
- 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
- 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
- High Availability
- 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