I am trying to get the Entra Id of a user from their email address before adding them to a specific group using Microsoft Graph API via a .Net Web App.
In Azure Portal I have registered the application and generated a client secret to use the Client credentials Auth Flow. For API permissions I have been granted User.Read and User.Read.All on our company tenant.
I create my GraphServiceClient using the following code:
public MicrosoftGraphService(IConfiguration configuration)
{
var scopes = new[] { "https://graph.microsoft.com/.default" };
var tenantId = configuration["MicrosoftGraph:TenantId"];
var clientId = configuration["MicrosoftGraph:ClientId"];
var clientSecret = configuration["MicrosoftGraph:Secret"];
var options = new ClientSecretCredentialOptions
{
AuthorityHost = AzureAuthorityHosts.AzurePublicCloud
};
var clientSecretCredential = new ClientSecretCredential(tenantId, clientId, clientSecret, options);
_graphServiceClient = new GraphServiceClient(clientSecretCredential, scopes);
}
I call the Graph API by passing in the email address trying to retrieve the user object where I can read the Entra ID. I do this using the following code:
public async Task<GraphUser> GetUserAsync(string emailAddress)
{
try
{
var foundUser = await _graphServiceClient.Users[emailAddress].GetAsync();
var user = (new GraphUser()
{
UserId = foundUser.Id,
DisplayName = foundUser.DisplayName,
Email = emailAddress
});
return user;
}
catch
{
// Not found in AD
return null;
}
}
However, when it invokes the _graphServiceClient.Users[emailAddress].GetAsync() call I get an error stating: "Insufficient privileges to complete the operation."
From the documentation I have read having the User.Read.All api permission granted for the application should be enough to get the data. What am I doing wrong?
The error "Insufficient privileges to complete the operation" usually occurs if the Microsoft Entra ID application doesn't have required permissions to perform the action.
Initially I got the same error:
To resolve the error, make sure to grant User.Read.All
application type API permission as you are making use of client credential flow.
User.Read.All
delegated type API permission must be granted when you make use of user interactive flow.Grant the User.Read.All
application type API permission like below:
I am able to successfully retrieve the users with UPN like below:
using Microsoft.Graph;
using Azure.Identity;
using Microsoft.Graph.Models.ODataErrors;
class Program
{
static async Task Main(string[] args)
{
var scopes = new[] { "https://graph.microsoft.com/.default" };
var clientId = "ClientID";
var tenantId = "TenantID";
var clientSecret = "ClientSecret";
var options = new ClientSecretCredentialOptions
{
AuthorityHost = AzureAuthorityHosts.AzurePublicCloud,
};
var clientSecretCredential = new ClientSecretCredential(
tenantId, clientId, clientSecret, options);
var graphClient = new GraphServiceClient(clientSecretCredential, scopes);
try
{
var result = await graphClient.Users["[email protected]"].GetAsync();
Console.WriteLine($"User details: {result.DisplayName}, {result.Mail}, {result.Id}");
}
catch (ODataError odataError)
{
Console.WriteLine(odataError.Error?.Code);
Console.WriteLine(odataError.Error?.Message);
throw;
}
}
}
Reference: