2
votes

I am trying to use Microsoft Graph API to update another user in Active Directory.

I have the following permissions set for both user and application at https://apps.dev.microsoft.com/

I've requested the following scopes:

  • Directory.ReadWrite.All
  • User.ReadWrite.All
  • Group.ReadWrite.All

I am able to get a listing of all users in the directory, but when trying to update (in this case, the city) it fails:

GraphServiceClient graphClient = SDKHelper.GetAuthenticatedClient ();
var usersResponse = graphClient.Users.Request ().GetAsync ();
var users = usersResponse.Result;

// hard coding user id for now
var userId = "9a5b83cd-85ff-4ad1-ab2f-b443941a518e";

var user = users.FirstOrDefault (m => m.Id == userId);
if (user != null) {
    user.City = "New York";
    await graphClient.Me.Request ().UpdateAsync (user);
}

I get:

{
    Code : Authorization_RequestDenied
    Message : Insufficient privileges to complete the operation.
    Inner error
}

The user I am logged in as is a Global Administrator of the directory.

I took the JWT token, headed over to https://jwt.io and these are the roles I am seeing:

  • Directory.Read.All
  • Directory.ReadWrite.All
  • Files.ReadWrite
  • Group.ReadWrite.All
  • Mail.Send
  • User.Read
  • User.Read.All
  • User.ReadWrite.All

Do I need other permissions to make this happen?

At the end of the day, I'd like to create a console app (not web app) that I can update other user information in the directory. But I figured using this sample app provided by Microsoft is a good start.

1

1 Answers

3
votes

The reason you're seeing this is because you're passing the complete user object rather than only the city property. In other words, you're attempting to update every property in that user record, including several that are read-only.

This is one of those cases where having an SDK that wraps a REST API can be result in some confusing errors. As REST API, it is stateless so passing in the entire user property set is telling the API you want to PATCH all of those values.

You're also passing in a different user object into the me object (i.e. you're replacing all of your property values with this other user's property values):

await graphClient.Me.Request().UpdateAsync(user);

Instead, try this:

GraphServiceClient graphClient = SDKHelper.GetAuthenticatedClient ();

// hard coding user id for now
var userId = "9a5b83cd-85ff-4ad1-ab2f-b443941a518e";

await graphClient.Users[userId].Request ().UpdateAsync(new User
{
    City = "New York"
});