Search code examples
azureasp.net-core.net-coremicrosoft-graph-apimicrosoft-graph-sdks

Microsoft Graph API 5.x Upgrade Results in Insufficient Access Privilege Error


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


Solution

  • 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.

    • Client credential flow is a non-user interactive flow.

    To update the user properties, you need to grant User.ReadWrite.All application type API permission:

    enter image description here

    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:

    enter image description here

    enter image description here

    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;
                }
            }
        }
    }
    

    enter image description here enter image description here

    • The Microsoft Entra ID application must be having higher privileged role than the user.
    • For sample, if you are trying to update Global Admin user property then the application must be assigned Global Admin role.

    Reference:

    Update user - Microsoft Graph v1.0 | Microsoft