Desktop app that calls web APIs: Move to production

In this article, you learn how to move your desktop app that calls web APIs to production.

Handle errors in desktop applications

In the different flows, you've learned how to handle the errors for the silent flows, as shown in the code snippets. You've also seen that there are cases where interaction is needed, as in incremental consent and Conditional Access.


Getting consent for several resources works for the Microsoft identity platform but not for Azure Active Directory (Azure AD) B2C. Azure AD B2C supports only admin consent, not user consent.

You can't get a token for several resources at once with the Microsoft identity platform. The scopes parameter can contain scopes for only a single resource. You can ensure that the user pre-consents to several resources by using the extraScopesToConsent parameter.

For instance, you might have two resources that have two scopes each:

  • with the scopes and customer.write
  • with the scopes and vendor.write

In this example, use the .WithExtraScopesToConsent modifier that has the extraScopesToConsent parameter.

For instance:


string[] scopesForCustomerApi = new string[]
string[] scopesForVendorApi = new string[]

var accounts = await app.GetAccountsAsync();
var result = await app.AcquireTokenInteractive(scopesForCustomerApi)

In MSAL for iOS and macOS


NSArray *scopesForCustomerApi = @[@"",

NSArray *scopesForVendorApi = @[@"",

MSALInteractiveTokenParameters *interactiveParams = [[MSALInteractiveTokenParameters alloc] initWithScopes:scopesForCustomerApi webviewParameters:[MSALWebviewParameters new]];
interactiveParams.extraScopesToConsent = scopesForVendorApi;
[application acquireTokenWithParameters:interactiveParams completionBlock:^(MSALResult *result, NSError *error) { /* handle result */ }];


let scopesForCustomerApi = ["",

let scopesForVendorApi = ["",

let interactiveParameters = MSALInteractiveTokenParameters(scopes: scopesForCustomerApi, webviewParameters: MSALWebviewParameters())
interactiveParameters.extraScopesToConsent = scopesForVendorApi
application.acquireToken(with: interactiveParameters, completionBlock: { (result, error) in /* handle result */ })

This call gets you an access token for the first web API.

When calling the second web API, call the AcquireTokenSilent API.

AcquireTokenSilent(scopesForVendorApi, accounts.FirstOrDefault()).ExecuteAsync();

Microsoft personal account requires reconsent each time the app runs

For Microsoft personal account users, reprompting for consent on each native client (desktop or mobile app) call to authorize is the intended behavior. Native client identity is inherently insecure, which is contrary to confidential client application identity. Confidential client applications exchange a secret with the Microsoft identity platform to prove their identity. The Microsoft identity platform chose to mitigate this insecurity for consumer services by prompting the user for consent each time the application is authorized.

Enable logging

To help in debugging and authentication failure troubleshooting scenarios, the Microsoft Authentication Library provides built-in logging support. Logging in each library is covered in the following articles:

Here are some suggestions for data collection:

  • Users might ask for help when they have problems. A best practice is to capture and temporarily store logs. Provide a location where users can upload the logs. MSAL provides logging extensions to capture detailed information about authentication.

  • If telemetry is available, enable it through MSAL to gather data about how users sign in to your app.

Validate your integration

Test your integration by following the Microsoft identity platform integration checklist.

Build for resilience

Learn how to increase resiliency in your app. For details, see Increase resilience of authentication and authorization applications you develop

Next steps

To try out additional samples, see Desktop public client applications.