March 3, 2023 Hemachandhiran Harimoorthy

In this blog we will explore how to setup Azure AD and use Microsoft Graph to get users details in .NET application. We are using .NET 6 application for the demo. But the steps are similar for .NET Framework as well.

Active Directory Setup

Login to your Azure and go to Active Directory https://portal.azure.com/#view/Microsoft_AAD_IAM/ActiveDirectoryMenuBlade/~/Overview

Go to App registration and select “New registration”.

Give a application name and select “Accounts in this organizational directory only (xxx – Single tenant)”. Leave Redirect URI. Click the “Register” button to create the application.

Go to the created application and select “API permissions” from the left panel. Add “User.Read.All” permission. Make sure you apply “Grant Admin Consent” option.

Go to “Certificates & secrets” menu and click “New client secret”

Give a Description and set Expires then click “Add” button at the bottom.

Copy the secret value to notepad. We will use this value in the later section.This is referred as “Client Secret” in the later section.

Go to the Overview page and copy Client ID and Tenant ID to notepad. We need this info in the later section.

Application

Now go to your .NET application and install nuget package “Microsoft.Graph” and “Azure.Identity” using Package manager console or Nuget Package Manager in Visual Studio

Install-Package Microsoft.Graph
Install-Package Azure.Identity

Open you appsettings.json and update the values you obtained in the previous steps.

"Graph": {
    "scope": "https://graph.microsoft.com/.default",
    "tenantId": "<Your Tenant Id>",
    "clientId": "<Your Client Id>",
    "clientSecret": "<Your Client Secret>"
  }

Create Graph Client

Use the below code to create Graph Client

string scope = configuration["Graph:scope"];
var scopes = new[] { scope };

// Multi-tenant apps can use "common",
// single-tenant apps must use the tenant ID from the Azure portal
var tenantId = configuration["Graph:tenantId"];

// Values from app registration
var clientId = configuration["Graph:clientId"];
var clientSecret = configuration["Graph:clientSecret"];

// using Azure.Identity;         
var options = new TokenCredentialOptions
{
AuthorityHost = AzureAuthorityHosts.AzurePublicCloud
};

var clientSecretCredential = new ClientSecretCredential(
                tenantId, clientId, clientSecret, options);

var graphClient = new GraphServiceClient(clientSecretCredential, scopes);

Once you have the graphClient ready you can invoke Graph Queries to get data from Microsoft.

You can access all the endpoints defined here https://learn.microsoft.com/en-us/graph/api/resources/users?view=graph-rest-1.0

We will implement simple List users with filters. You can find the API details here https://learn.microsoft.com/en-us/graph/api/user-list?view=graph-rest-1.0&tabs=csharp

Example

In the below example we query users based on surname, firstname, email id, phone number

string filter = $"startswith(displayName,'{searchString}') or startswith(givenName,'{searchString}') or startswith(surname,'{searchString}') or startswith(mail,'{searchString}') or startswith(userPrincipalName,'{searchString}') or businessPhones/any(p:startsWith(p, '{searchString}'))";

try
{
 UserCollectionResponse? users = await _graphClient.Users.GetAsync((requestConfiguration) =>
{
  requestConfiguration.QueryParameters.Filter = filter;
  requestConfiguration.QueryParameters.Select = new string[] { "id", "givenName", "surname", "displayName" };
  requestConfiguration.QueryParameters.Count = true;
  requestConfiguration.Headers.Add("ConsistencyLevel", "eventual");
 });
                                
 if (users == null || users.Value == null || users.Value.Count < 1)
 return null;

List<GraphUser> searchUsers = new List<GraphUser>();
foreach (User user in users.Value)
{
 GraphUser resUsers = new GraphUser
 {
 Id = user.Id,
 DisplayName = user.DisplayName,
 GivenName = user.GivenName,
 Surname = user.Surname
 };
 searchUsers.Add(resUsers);
}
}
catch(Exception ex)
{
}

Add Singleton to share the Graph Client across application. Open Program.cs in your application and the below lines

builder.Services.AddSingleton<GraphServiceClient>(sp =>
{
 return new GraphServiceClient(clientSecretCredential, scopes);
});

You can access the Graph Client from Controllers or in your Classes

public class MyController : ControllerBase
{
        private readonly GraphServiceClient _graphServiceClient;

        public CommonController(GraphServiceClient graphServiceClient)
        {
            _graphServiceClient = graphServiceClient ?? throw new ArgumentNullException(nameof(graphServiceClient));
        }
}