-
Notifications
You must be signed in to change notification settings - Fork 345
Client credential flows 2x
This page is for an older MSAL.NET version. See Client credential flows in MSAL.NET for updated documentation.
This article is for MSAL.NET 3.x. If you are interested in MSAL.NET 3.x, please visit Client credential flows in MSAL.NET
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, because the OAuth2 spec states that there should be a secure, dedicated connection between the application and the Identity Provider. This secure connection can be achieved on web app or web API back-ends by deploying a certificate. It's also possible to use secret string, even if this alternative is not recommended for production. However, it cannot be achieved on mobile and other client applications that are distributed to users. As such, these flows are not available on:
- Xamarin.Android
- Xamarin.iOS
- UWP
MSAL.NET supports three types of client credentials:
- Application secrets
- Certificates
- Optimized client assertions
These client credentials need to be:
- registered with Azure AD
- Passed in the constructors of
ConfidentialClientApplication
in your code
Then you can call AcquireTokenForClientAsync
.
You can register your application secrets either through the interactive experience in the Azure portal, or using command-line tools (like PowerShell)
The management of client credentials happens in the certificates & secrets page for an application:
- 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
The active-directory-dotnetcore-daemon-v2 sample shows how to register an application secret or a certificate with an Azure AD application:
- For details on how to register an application secret, see AppCreationScripts/Configure.ps1
- For details on how to register a certificate with the application, see AppCreationScripts-withCert/Configure.ps1
In MSAL client credentials are similar to what they are in ADAL.NET, except that the Client Credentials are passed as a parameter of both ConfidentialClientApplication
constructors.
Then, once the confidential client application is constructed, acquiring the token is a question of calling overrides of AcquireTokenForClientAsync
, passing the scope, and forcing or not a refresh of the token.
The ClientAssertionCertificate
class passed as an argument to the ConfidentialClientApplication constructors is similar to the ADAL.NET one, however, in this case, the ClientAssertionCertificate is a Client Assertion like the application secret.
Unsurprisingly, the ClientAssertionCertificate is instantiated passing a X509Certificate2 instance.
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. A client secret or a certificate is used depending whether the VariationWithCertificateCredentials
constant is defined or not. config.ClientSecret
and config.CertificateName
are both strings. For more information, see AuthenticationConfig.cs
// Even if this is a console application here, a daemon application is a confidential client application
ClientCredential clientCredentials;
#if !VariationWithCertificateCredentials
// Building the client credentials from a client secret (secret string)
clientCredentials = new ClientCredential(config.ClientSecret);
#else
// Building the client credentials from a certificate
X509Certificate2 certificate = ReadCertificate(config.CertificateName);
clientCredentials = new ClientCredential(new ClientAssertionCertificate(certificate));
#endif
var app = new ConfidentialClientApplication(config.ClientId, config.Authority, "https://daemon",
clientCredentials, null, new TokenCache());
// 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.AcquireTokenForClientAsync(scopes);
}
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
}
AcquireTokenForClientAsync
uses the application token cache (not the user token cache). The application token cache is the second token cache passed in the constructor of ConfidentialClientApplication
.
Don't call AcquireTokenSilentAsync
before calling AcquireTokenForClientAsync
as AcquireTokenSilentAsync
uses the user token cache. AcquireTokenForClientAsync
checks the application token cache itself and updates it.
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.AcquireTokenForClientAsync(scopes);
In the case where your confidential client application uses only client credentials flow, the reply URL passed in the constructor can be anything except null. It's not used. (In the future, null would be allowed: See issue #426)
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. The sample also illustrates the variation with certificates |
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. |
You can find more information in:
- The reference documentation for ConfidentialClientApplication Constructors and AcquireTokenForClientAsync
- The protocol documentation: Azure Active Directory v2.0 and the OAuth 2.0 client credentials flow
Vanity URL: https://aka.ms/msal-net-client-credentials
- 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
- Xamarin Docs
- UWP
- 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