Edit

Share via


Build .NET apps with Microsoft Graph and app-only authentication

This tutorial teaches you how to build a .NET console app that uses the Microsoft Graph API to access data using app-only authentication. App-only authentication is a good choice for background services or applications that need to access data for all users in an organization.

Note

To learn how to use Microsoft Graph to access data on behalf of a user, see this user (delegated) authentication tutorial.

In this tutorial, you will:

Tip

As an alternative to following this tutorial, you can download or clone the GitHub repository and follow the instructions in the README to register an application and configure the project.

Prerequisites

Before you start this tutorial, you should have the .NET SDK installed on your development machine.

You should also have a Microsoft work or school account with the Global administrator role. If you don't have a Microsoft 365 tenant, you might qualify for one through the Microsoft 365 Developer Program; for details, see the FAQ. Alternatively, you can sign up for a one-month free trial or purchase a Microsoft 365 plan.

Note

This tutorial was written with .NET SDK version 7.0.102. The steps in this guide might work with other versions, but that hasn't been tested.

Register application for app-only authentication

Register an application that supports app-only authentication using client credentials flow.

  1. Open a browser and navigate to the Microsoft Entra admin center and sign in using a Global administrator account.

  2. Select Microsoft Entra ID in the left-hand navigation, expand Identity, expand Applications, then select App registrations.

    A screenshot of the App registrations

  3. Select New registration. Enter a name for your application, for example, Graph App-Only Auth Tutorial.

  4. Set Supported account types to Accounts in this organizational directory only.

  5. Leave Redirect URI empty.

  6. Select Register. On the application's Overview page, copy the value of the Application (client) ID and Directory (tenant) ID and save them. You'll need these values in the next step.

    A screenshot of the application ID of the new app registration

  7. Select API permissions under Manage.

  8. Remove the default User.Read permission under Configured permissions by selecting the ellipses (...) in its row and selecting Remove permission.

  9. Select Add a permission, then Microsoft Graph.

  10. Select Application permissions.

  11. Select User.Read.All, then select Add permissions.

  12. Select Grant admin consent for..., then select Yes to provide admin consent for the selected permission.

    A screenshot of the Configured permissions table after granting admin consent

  13. Select Certificates and secrets under Manage, then select New client secret.

  14. Enter a description, choose a duration, and select Add.

  15. Copy the secret from the Value column, you'll need it in the next steps.

    Important

    This client secret is never shown again, so make sure you copy it now.

Note

Notice that, unlike the steps when registering for user authentication, in this section you did configure Microsoft Graph permissions on the app registration. App-only auth uses the client credentials flow, which requires that permissions be configured on the app registration. See The .default scope for details.

Create a .NET console app

Begin by creating a new .NET console project using the .NET CLI.

  1. Open your command-line interface (CLI) in a directory where you want to create the project. Run the following command.

    dotnet new console -o GraphAppOnlyTutorial
    
  2. Once the project is created, verify that it works by changing the current directory to the GraphTutorial directory and running the following command in your CLI.

    dotnet run
    

    If it works, the app should output Hello, World!.

Install dependencies

Before moving on, add some dependencies that you use later.

To install the dependencies, run the following commands in your CLI.

dotnet add package Microsoft.Extensions.Configuration.Binder
dotnet add package Microsoft.Extensions.Configuration.Json
dotnet add package Microsoft.Extensions.Configuration.UserSecrets
dotnet add package Azure.Identity
dotnet add package Microsoft.Graph

Load application settings

Add the details of your app registration to the project.

  1. Create a file in the GraphAppOnlyTutorial directory named appsettings.json and add the following code.

    {
      "settings": {
        "clientId": "YOUR_CLIENT_ID_HERE",
        "tenantId": "YOUR_TENANT_ID_HERE"
      }
    }
    
  2. Update the values according to the following table.

    Setting Value
    clientId The client ID of your app registration
    tenantId The tenant ID of your organization.

    Tip

    Optionally, you can set these values in a separate file named appsettings.Development.json.

  3. Add your client secret to the .NET Secret Manager. In your command-line interface, change the directory to the ___location of GraphAppOnlyTutorial.csproj and run the following commands, replacing <client-secret> with your client secret.

    dotnet user-secrets init
    dotnet user-secrets set settings:clientSecret <client-secret>
    
  4. Update GraphAppOnlyTutorial.csproj to copy appsettings.json to the output directory. Add the following code between the <Project> and </Project> lines.

    <ItemGroup>
      <None Include="appsettings*.json">
        <CopyToOutputDirectory>Always</CopyToOutputDirectory>
      </None>
    </ItemGroup>
    
  5. Create a file in the GraphAppOnlyTutorial directory named Settings.cs and add the following code.

    using Microsoft.Extensions.Configuration;
    
    public class Settings
    {
        public string? ClientId { get; set; }
        public string? ClientSecret { get; set; }
        public string? TenantId { get; set; }
    
        public static Settings LoadSettings()
        {
            // Load settings
            IConfiguration config = new ConfigurationBuilder()
                // appsettings.json is required
                .AddJsonFile("appsettings.json", optional: false)
                // appsettings.Development.json" is optional, values override appsettings.json
                .AddJsonFile($"appsettings.Development.json", optional: true)
                // User secrets are optional, values override both JSON files
                .AddUserSecrets<Program>()
                .Build();
    
            return config.GetRequiredSection("Settings").Get<Settings>() ??
                throw new Exception("Could not load app settings. See README for configuration instructions.");
        }
    }
    

Design the app

Create a console-based menu.

  1. Open ./Program.cs and replace its entire contents with the following code.

    Console.WriteLine(".NET Graph App-only Tutorial\n");
    
    var settings = Settings.LoadSettings();
    
    // Initialize Graph
    InitializeGraph(settings);
    
    int choice = -1;
    
    while (choice != 0)
    {
        Console.WriteLine("Please choose one of the following options:");
        Console.WriteLine("0. Exit");
        Console.WriteLine("1. Display access token");
        Console.WriteLine("2. List users");
        Console.WriteLine("3. Make a Graph call");
    
        try
        {
            choice = int.Parse(Console.ReadLine() ?? string.Empty);
        }
        catch (System.FormatException)
        {
            // Set to invalid value
            choice = -1;
        }
    
        switch(choice)
        {
            case 0:
                // Exit the program
                Console.WriteLine("Goodbye...");
                break;
            case 1:
                // Display access token
                await DisplayAccessTokenAsync();
                break;
            case 2:
                // List users
                await ListUsersAsync();
                break;
            case 3:
                // Run any Graph code
                await MakeGraphCallAsync();
                break;
            default:
                Console.WriteLine("Invalid choice! Please try again.");
                break;
        }
    }
    
  2. Add the following placeholder methods at the end of the file. You implement them in later steps.

    void InitializeGraph(Settings settings)
    {
        // TODO
    }
    
    async Task DisplayAccessTokenAsync()
    {
        // TODO
    }
    
    async Task ListUsersAsync()
    {
        // TODO
    }
    
    async Task MakeGraphCallAsync()
    {
        // TODO
    }
    

This implements a basic menu and reads the user's choice from the command line.

Next step