Daemon app that calls web APIs - code configuration

Learn how to configure the code for your daemon application that calls web APIs.

Microsoft libraries supporting daemon apps

The following Microsoft libraries support daemon apps:

Language / framework Project on
GitHub
Package Getting
started
Sign in users Access web APIs Generally available (GA) or
Public preview1
.NET MSAL.NET Microsoft.Identity.Client Quickstart Library cannot request ID tokens for user sign-in. Library can request access tokens for protected web APIs. GA
Java MSAL4J msal4j Library cannot request ID tokens for user sign-in. Library can request access tokens for protected web APIs. GA
Node MSAL Node msal-node Quickstart Library cannot request ID tokens for user sign-in. Library can request access tokens for protected web APIs. GA
Python MSAL Python msal-python Quickstart Library cannot request ID tokens for user sign-in. Library can request access tokens for protected web APIs. GA

1 Universal License Terms for Online Services apply to libraries in Public preview.

Configure the authority

Daemon applications use application permissions rather than delegated permissions. So their supported account type can't be an account in any organizational directory or any personal Microsoft account (for example, Skype, Xbox, Outlook.com). There's no tenant admin to grant consent to a daemon application for a Microsoft personal account. You need to choose accounts in my organization or accounts in any organization.

The authority specified in the application configuration should be tenanted (specifying a tenant ID or a domain name associated with your organization).

Even if you want to provide a multitenant tool, you should use a tenant ID or domain name, and not common or organizations with this flow, because the service can't reliably infer which tenant should be used.

Configure and instantiate the application

In MSAL libraries, the client credentials (secret or certificate) are passed as a parameter of the confidential client application construction.

Important

Even if your application is a console application that runs as a service, if it's a daemon application, it needs to be a confidential client application.

Configuration file

The configuration file defines:

  • The cloud instance and tenant ID, which together make up the authority.
  • The client ID that you got from the application registration.
  • Either a client secret or a certificate.

Here's an example of defining the configuration in an appsettings.json file. This example is taken from the .NET console daemon code sample on GitHub.

{
    "AzureAd": {
        "Instance": "https://login.microsoftonline.com/",
        "TenantId": "[Enter here the tenantID or domain name for your Azure AD tenant]",
        "ClientId": "[Enter here the ClientId for your application]",
        "ClientCredentials": [
            {
                "SourceType": "ClientSecret",
                "ClientSecret": "[Enter here a client secret for your application]"
            }
        ]
    }
}

You provide a certificate instead of the client secret, or workload identity federation credentials.

Instantiate the MSAL application

To instantiate the MSAL application, add, reference, or import the MSAL package (depending on the language).

The construction is different, depending on whether you're using client secrets or certificates (or, as an advanced scenario, signed assertions).

Reference the package

Reference the MSAL package in your application code.

Add the Microsoft.Identity.Web.TokenAcquisition NuGet package to your application. Alternatively, if you want to call Microsoft Graph, add the Microsoft.Identity.Web.GraphServiceClient package. Your project could be as follows. The appsettings.json file needs to be copied to the output directory.

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net7.0</TargetFramework>
    <RootNamespace>daemon_console</RootNamespace>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="Microsoft.Identity.Web.GraphServiceClient" Version="2.12.2" />
  </ItemGroup>

  <ItemGroup>
    <None Update="appsettings.json">
      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
    </None>
  </ItemGroup>
</Project>

In the Program.cs file, add a using directive in your code to reference Microsoft.Identity.Web.

using Microsoft.Identity.Abstractions;
using Microsoft.Identity.Web;

Instantiate the confidential client application with a client secret

Here's the code to instantiate the confidential client application with a client secret:

   class Program
    {
        static async Task Main(string[] _)
        {
            // Get the Token acquirer factory instance. By default it reads an appsettings.json
            // file if it exists in the same folder as the app (make sure that the 
            // "Copy to Output Directory" property of the appsettings.json file is "Copy if newer").
            TokenAcquirerFactory tokenAcquirerFactory = TokenAcquirerFactory.GetDefaultInstance();

            // Configure the application options to be read from the configuration
            // and add the services you need (Graph, token cache)
            IServiceCollection services = tokenAcquirerFactory.Services;
            services.AddMicrosoftGraph();
            // By default, you get an in-memory token cache.
            // For more token cache serialization options, see https://aka.ms/msal-net-token-cache-serialization

            // Resolve the dependency injection.
            var serviceProvider = tokenAcquirerFactory.Build();

            // ...
        }
    }

The configuration is read from the appsettings.json:

Instantiate the confidential client application with a client certificate

Here's the code to build an application with a certificate:

The code itself is exactly the same. The certificate is described in the configuration. There are many ways to get the certificate. For details see https://aka.ms/ms-id-web-certificates. Here's how you would do to get your certificate from KeyVault. Microsoft identity delegates to Azure Identity's DefaultAzureCredential, and used Managed identity when available to access the certificate from KeyVault. You can debug your application locally as it then uses your developer credentials.

  "ClientCredentials": [
      {
        "SourceType": "KeyVault",
        "KeyVaultUrl": "https://yourKeyVaultUrl.vault.azure.net",
        "KeyVaultCertificateName": "NameOfYourCertificate"
      }

Advanced scenario: Instantiate the confidential client application with client assertions

In addition to using a client secret or certificate, confidential client applications can also prove their identity by using client assertions. See CredentialDescription for details.

Next steps

Move on to the next article in this scenario, Acquire a token for the app.