Client credential flows

Supported platforms

While MSAL.NET is a multi-framework library, Confidential Client flows are not available on mobile and client-facing platforms (e.g., UWP, Xamarin.iOS, and Xamarin.Android) since there is no secure way of deploying a secret with an application.

Supported client credentials

MSAL.NET supports two types of client credentials, which must be registered in the Microsoft Entra portal:

  • Application secrets (not recommended for production scenarios).
  • Certificates.

For advanced scenarios, two other types credentials can be used:

  • Signed client assertions.
  • Certificate and additional claims to be sent.

For additional details, refer to the Confidential client assertions document.

Example usage

// This object will cache tokens in-memory - keep it as a singleton
var singletonApp = ConfidentialClientApplicationBuilder.Create(config.ClientId)
        // Don't specify authority here, we'll do it on the request 
        .WithCertificate(certificate) // or .WithClientSecret(secret)
        .Build();

// If instead you need to re-create the ConfidentialClientApplication on each request, you MUST customize 
// the cache serialization (see below)

// When making the request, specify the tenant-based authority
var authResult = await app.AcquireTokenForClient(scopes: new [] {  "some_app_id_uri/.default"})        // Uses the token cache automatically, which is optimized for multi-tenant access
        .WithAuthority(AzureCloudInstance.AzurePublic, "{tenantID}")  // Do not use "common" or "organizations"!
        .ExecuteAsync();

Important

Do not use common or organizations authority for client credential flows. Specify the tenant ID in the authority.

Custom cache serialization

If your service is multi-tenant (i.e., it needs tokens for a resource that is in a different tenant), see MSAL for client credential flow in multi-tenant services.

You can serialize the token cache to a location of your choice (e.g., in-memory or through a distributed system like Redis). You would do this to:

  • Share the token cache between several instances of ConfidentialClientApplication.
  • Persist the token cache to share it between different machines.

Please see distributed cache implementations and binding the token cache for additional implementation details.

Check our sample to see how token cache serialization works.

Ensuring high availability of your applications

Service is running out of memory

See Using MSAL.NET for client credential flow in multi-tenant services for an in-depth overview of the multi-tenant architecture with MSAL.NET.

Make sure to provision enough RAM on the machines running your service or use a distributed cache. A single token is a few kilobytes (KB) in size, and one token is stored for each tenant with which the application interacts.

Avoid requesting new tokens on each machine of a distributed service

Use a distributed cache, like Redis.

Monitoring cache hit rates

The authentication result object can tell you if the token comes from the cache:

authResult.AuthenticationResultMetadata.TokenSource == TokenSource.Cache

Handling "loop detected" errors

You are calling Microsoft Entra ID for a token too often and the service is throttling you. To mitigate this issue, you need to use a cache - either the in-memory one (as per the sample above) or a persisted one.

High latency for token acquisition

Please ensure you have a high token cache hit rate. The in-memory cache is optimized for searching through tokens that come from different client IDs or different tenant IDs. It is not optimized for storing tokens with different scopes. You need to use a different cache key that includes the scope. See Performance testing for additional recommendations.

Configuring application secrets or certificates with Microsoft Entra ID

You can register your application secrets either through the interactive experience in the Azure portal, or using command-line tools like PowerShell.

Registering client secrets using the application registration portal

The management of client credentials happens in the Certificates & secrets page for a registered application in the Microsoft Entra portal:

Certificates & secrets view in the Azure Portal

Registering client secrets using PowerShell

The active-directory-dotnetcore-daemon-v2 sample shows how to register an application secret or a certificate with a Microsoft Entra application:

Using client credentials

In MSAL.NET, client credentials are passed as a parameter during ConfidentialClientApplication instantiation. Once the confidential client application is constructed, acquiring the token requires calling AcquireTokenForClient(IEnumerable<String>) or one of its overloads, passing the scope and indicating whether a token refresh is required.

Client assertions

Instead of a client secret or a certificate, the confidential client application can also prove its identity using client assertions. This scenario is outlined in detail in the Confidential client assertions document.

Remarks

AcquireTokenForClient uses the application token cache

AcquireTokenForClient uses the application token cache (not the user token cache).

Don't call AcquireTokenSilent before calling AcquireTokenForClient as AcquireTokenSilent uses the user token cache.

AcquireTokenForClient checks the application token cache itself and updates it.

See Token cache types for details on differences between application and user token caches.

Scopes to request

The scope to request for a client credential flow is the name of the resource followed by /.default. This notation tells Microsoft Entra ID to use application level permissions declared statically during the application registration. The API permissions must be granted by a tenant administrator.

This configuration can look as such:

ResourceId = "someAppIDURI";
var scopes = new [] {  ResourceId+"/.default"};

var result = app.AcquireTokenForClient(scopes);

No need for reply URL if app is a daemon

If your confidential client application uses only the client credentials flow, you don't need to specify a reply URL in the constructor.

Samples

Sample Platform Description
active-directory-dotnetcore-daemon-v2 .NET

A simple .NET application that displays the users of a tenant querying Microsoft Graph using the identity of the application, instead of on behalf of a user.

Daemon app topology

The sample also illustrates the variation with certificates.

Daemon certificate-based auth topology
active-directory-dotnet-daemon-v2 ASP.NET MVC

A web application that syncs data from Microsoft Graph using the identity of the application, instead of on behalf of a user.

UserSync app topology

More info

You can find more information in the protocol documentation.