I've been using Microsoft Graph v3 and recently decided to upgrade to the latest version, v5.x. Previously, I used the ConfidentialClientApplicationBuilder
to create an IConfidentialClientApplication
instance, which I passed into the ClientCredentialProvider
to initialize the GraphServiceClient
for querying the Graph API.
Graph V3 Code
var applicationOptions = new ConfidentialClientApplicationOptions()
{
AadAuthorityAudience = AadAuthorityAudience.AzureAdMyOrg,
AzureCloudInstance = AzureCloudInstance.AzurePublic,
TenantId = Config.TenantId,
ClientId = Config.ClientId,
ClientSecret = Config.ClientSecret
};
var _app = ConfidentialClientApplicationBuilder.CreateWithApplicationOptions(applicationOptions).Build();
ClientCredentialProvider authProvider = new ClientCredentialProvider(_app);GraphServiceClient graphClient = new GraphServiceClient(authProvider);
var user = await graphClient.Users.Request().Select(o => new {o.Id,o.Mail}).GetAsync();
After upgrading to v5, I noticed there are several new ways to authenticate. I opted to use the ClientSecretCredential
, as it seemed similar and allowed me to reuse the same credentials.
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);
var requestBody = new User
{
BusinessPhones = new List<string>
{
"12342232132",
}
};
var result = await graphClient.Users["UserID"].PatchAsync(requestBody);
However, I'm now encountering an Insufficient privileges to complete the operation error. I'm unsure if this is due to missing scope permissions or some other issue. but I tried to add the necessary permissions, but the error persists.
Note: I am using the admin account
Thanks
Note that: As you are making use of client credential flow, you need to grant application type API permissions to the Microsoft Entra ID application.
To update the user properties, you need to grant User.ReadWrite.All
application type API permission:
And assign administrator role to the Microsoft Entra ID application as mentioned in this MsDoc
I assigned User administrator active role to the Microsoft Entra ID application:
I am able to successfully update the business phone of the user:
using Azure.Identity;
using Microsoft.Graph;
using Microsoft.Graph.Models;
using Microsoft.Graph.Models.ODataErrors;
namespace GraphApiExample
{
class Program
{
private static async Task Main(string[] args)
{
var scopes = new[] { "https://graph.microsoft.com/.default" };
var clientId = "ClientID";
var tenantId = "TenantID";
var clientSecret = "Secret";
var options = new ClientSecretCredentialOptions
{
AuthorityHost = AzureAuthorityHosts.AzurePublicCloud,
};
var clientSecretCredential = new ClientSecretCredential(tenantId, clientId, clientSecret, options);
var graphClient = new GraphServiceClient(clientSecretCredential, scopes);
var requestBody = new User
{
BusinessPhones = new List<string>
{
"12342232132",
}
};
try
{
var userId = "UserID";
var result = await graphClient.Users[userId].PatchAsync(requestBody);
Console.WriteLine($"Updated user's phone number");
}
catch (ODataError odataError)
{
Console.WriteLine(odataError.Error?.Code);
Console.WriteLine(odataError.Error?.Message);
throw;
}
}
}
}
Reference: