Skip to content

Client credential flows

pmaytak edited this page May 26, 2021 · 48 revisions

Client credential flows in MSAL.NET

Availability by platform

MSAL is a multi-framework library. Confidential Client flows are not available on the mobile platforms (UWP, Xamarin.iOS, and Xamarin.Android) since there is no secure way of deploying a secret there.

Credentials

MSAL.NET supports 2 types of client credentials, which must be registered in the AAD app registration portal

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

For advanced scenarios, 2 more types of credentials can be used. See details at Client assertions.

  • Signed client assertions
  • Certificate + additional claims to be sent

Code snippet

// 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 .WithSecret(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 tenanted 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();

For more information, see AuthenticationConfig.cs

Important: Token cache performance was significantly improved in MSAL 4.30

Custom Cache Serialization

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

You can serialize the token cache to a location of your choice for example in-memory or in distributed location like Redis. You would do this to:

  • share the token cache between several instances of ConfidentialClientApplication OR
  • persist the token cache to Redis to share it between different machines

Please see distributed cache implementations and binding the token cache.

This sample shows token cache serialization.

High Availability

Problem: My service is running out of memory. Solution: See MSAL for client credential flow in multi-tenant services. Provision enough RAM on the machines running your service or use a distributed cache. A single token is a only a few KB in size, but there is 1 token for each tenant! A multi-tenant service sometimes needs tokens for 0.5M tenants.

Problem: How can I avoid requesting new tokens on each machine of my distributed service? Solution: Use a distributed cache like Redis.

Problem: I customized my cache. How can I monitor the hit rate? Solution: The result object will tell you if the token comes from the cache or not:

authResult.AuthenticationResultMetadata.TokenSource == TokenSource.Cache

Problem: I am getting "loop detected" errors Solution: You are calling AAD for a token to often and AAD is throttling you. You need to use a cache - either the in-memory one (as per the sample above) or a persisted one.

Problem: AcquireTokenClient latency is too high Possible Solutions: 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_id or different tenant_id. It is not optimized for storing tokens with different scopes. You need to use a different cache key that includes the scope. See https://aka.ms/msal-net-performance-testing

Registration of application secret or certificate with Azure AD

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 an application:

image

Registering client secrets using PowerShell

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

Construction of ConfidentialClientApplication with client credentials

In MSAL.NET client credentials are passed as a parameter at the application construction

Then, once the confidential client application is constructed, acquiring the token is a question of calling overrides of AcquireTokenForClient, passing the scope, and forcing or not a refresh of the token.

Client assertions

Instead of a client secret or a certificate, the confidential client application can also prove its identity using client assertions. This advanced scenario is detailed in Client assertions

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.

Scopes to request

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

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

var result = app.AcquireTokenForClient(scopes);

No need to pass a Reply URL at app construction if your app is only a daemon

In the case where your confidential client application uses only client credentials flow, you don't need to pass a reply URL passed in the constructor.

Samples illustrating acquiring tokens interactively with MSAL.NET

Sample Platform Description
active-directory-dotnetcore-daemon-v2 .NET Core 2.1 Console

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

topology

The sample also illustrates the variation with certificates.

topology
active-directory-dotnet-daemon-v2 ASP.NET MVC

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

topology

More info

You can find more information in:

Vanity URL: https://aka.ms/msal-net-client-credentials

Getting started with MSAL.NET

Acquiring tokens

Web Apps / Web APIs / daemon apps

Desktop/Mobile apps

Advanced topics

FAQ

Other resources

Clone this wiki locally