Skip to content

Client credential flows

Bogdan Gavril edited this page Nov 19, 2020 · 48 revisions

Client credential flows in MSAL.NET

Availability by platform

MSAL is a multi-framework library. All Confidential Client flows, including the one presented here, are available on: .NET Core, .NET Desktop .NET Standard. They are not available on the mobile platforms (UWP, Xamarin.iOS, and Xamarin.Android) as these only support public client applications which don't know how to prove the application's identity to the Identity Provider. This secure connection can be achieved on web app or web API back-ends by deploying a certificate.

Overview of MSAL.NET public API for client credentials

MSAL.NET supports 2 types of client credentials:

  • Application secrets
  • 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

These client credentials need to be:

  • registered with Azure AD
  • Passed in the constructors of ConfidentialClientApplication in your code

Then you can call AcquireTokenForClient.

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

  • the application secret (also named client secret) is generated by Azure AD during the registration of the confidential client application when you select New client secret. At that point, you must copy the secret string in the clipboard for use in your app, before selecting Save. This string won't be presented any longer.
  • the certificate is uploaded in the application registration using the Upload certificate button

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.

Code snippet

The following code snippet shows how to acquire a token to call the Microsoft Graph. It uses the application permissions that were statically registered for the application. For more information, see AuthenticationConfig.cs

It is important to specify the tenant. Use of common or organizations is ambiguous and will be disallowed at some point in the future.

var app = ConfidentialClientApplicationBuilder.Create(config.ClientId)
           .WithAuthority(AzureCloudInstance.AzurePublic, "{tenantID}")
           .WithClientSecret(config.ClientSecret)
           .Build();
X509Certificate2 certificate = ReadCertificate(config.CertificateName);
var app = ConfidentialClientApplicationBuilder.Create(config.ClientId)
           .WithAuthority(AzureCloudInstance.AzurePublic, "{tenantID}")
           .WithCertificate(certificate)
           .Build();

With client credentials flows the scopes is ALWAYS of the shape "resource/.default", as the application permissions need to be set statically (in the portal or by PowerShell), and then granted by a tenant administrator

string[] scopes = new string[] { "https://graph.microsoft.com/.default" };

AuthenticationResult result = null;
try
{
 result = await app.AcquireTokenForClient(scopes)
                   .ExecuteAsync();
}
catch(MsalServiceException ex)
{
 // Case when ex.Message contains:
 // AADSTS70011 Invalid scope. The scope has to be of the form "https://resourceUrl/.default"
 // Mitigation: change the scope to be as expected
}

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 topology 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
active-directory-dotnet-daemon-v2 ASP.NET MVC topologyA web application that sync's data from the Microsoft Graph using the identity of the application, instead of on behalf of a user.

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