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 Supplemental terms of use for Microsoft Azure Previews 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'll 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 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 cannot 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 from the .NET Core console daemon code sample on GitHub.

{
  "Instance": "https://login.microsoftonline.com/{0}",
  "Tenant": "[Enter here the tenantID or domain name for your Azure AD tenant]",
  "ClientId": "[Enter here the ClientId for your application]",
  "ClientSecret": "[Enter here a client secret for your application]",
  "CertificateName": "[Or instead of client secret: Enter here the name of a certificate (from the user cert store) as registered with your application]"
}

You provide either a ClientSecret or a CertificateName. These settings are exclusive.

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.Client NuGet package to your application, and then add a using directive in your code to reference it.

In MSAL.NET, the confidential client application is represented by the IConfidentialClientApplication interface.

using Microsoft.Identity.Client;
IConfidentialClientApplication app;

Instantiate the confidential client application with a client secret

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

app = ConfidentialClientApplicationBuilder.Create(config.ClientId)
           .WithClientSecret(config.ClientSecret)
           .WithAuthority(new Uri(config.Authority))
           .Build();

The Authority is a concatenation of the cloud instance and the tenant ID, for example https://login.microsoftonline.com/contoso.onmicrosoft.com or https://login.microsoftonline.com/eb1ed152-0000-0000-0000-32401f3f9abd. In the appsettings.json file shown in the Configuration file section, these are represented by the Instance and Tenant values, respectively.

In the code sample the previous snippet was taken from, Authority is a property on the AuthenticationConfig class, and is defined as such:

/// <summary>
/// URL of the authority
/// </summary>
public string Authority
{
    get
    {
        return String.Format(CultureInfo.InvariantCulture, Instance, Tenant);
    }
}

Instantiate the confidential client application with a client certificate

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

X509Certificate2 certificate = ReadCertificate(config.CertificateName);
app = ConfidentialClientApplicationBuilder.Create(config.ClientId)
    .WithCertificate(certificate)
    .WithAuthority(new Uri(config.Authority))
    .Build();

Advanced scenario: Instantiate the confidential client application with client assertions

Instead of a client secret or a certificate, the confidential client application can also prove its identity by using client assertions.

MSAL.NET has two methods to provide signed assertions to the confidential client app:

  • .WithClientAssertion()
  • .WithClientClaims()

When you use WithClientAssertion, provide a signed JWT. This advanced scenario is detailed in Client assertions.

string signedClientAssertion = ComputeAssertion();
app = ConfidentialClientApplicationBuilder.Create(config.ClientId)
                                          .WithClientAssertion(signedClientAssertion)
                                          .Build();

When you use WithClientClaims, MSAL.NET will produce a signed assertion that contains the claims expected by Azure AD, plus additional client claims that you want to send. This code shows how to do that:

string ipAddress = "192.168.1.2";
var claims = new Dictionary<string, string> { { "client_ip", ipAddress } };
X509Certificate2 certificate = ReadCertificate(config.CertificateName);
app = ConfidentialClientApplicationBuilder.Create(config.ClientId)
                                          .WithAuthority(new Uri(config.Authority))
                                          .WithClientClaims(certificate, claims)
                                          .Build();

Again, for details, see Client assertions.

Next steps

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