1
votes

I'm using the Microsoft Graph Users API to validate a list of user names or email addresses against our ActiveDirectory. The name search:

https://graph.microsoft.com/v1.0/me/people/?$search=john.smith

returns additional data such as officeLocation and jobTitle. But if I use the email search:

https://graph.microsoft.com/v1.0/users/[email protected]

these additional fields are empty. I've enabled these API permissions in Azure:

  • People.Read
  • User.Read
  • User.ReadBasic.All
  • email

Do I need additional permissions to get the same data?

Update: I tried this in https://developer.microsoft.com/en-us/graph/graph-explorer as suggested below and it works, but Graph Explorer comes with these permissions by default which can't be disabled:

  • Calendars.ReadWrite
  • Contacts.ReadWrite
  • Directory.Read.All
  • Files.ReadWrite.All
  • Mail.ReadWrite
  • Notes.ReadWrite.All
  • openid
  • People.Read
  • Sites.ReadWrite.All
  • Tasks.ReadWrite
  • User.ReadBasic.All
  • User.ReadWrite

Update 2: I'm using Python 3.7 so I borrowed device_flow_session() from https://github.com/microsoftgraph/python-sample-console-app/blob/master/helpers.py#L25. The data I get back from https://graph.microsoft.com/me/people/?$search=John.Smith looks like:

{
    "@odata.context": "https://graph.microsoft.com/v1.0/$metadata#users("XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX")/people",
    "value": [{
            "id": "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX",
            "displayName": "John Smith",
            "givenName": "John",
            "surname": "Smith",
            "birthday": "",
            "personNotes": "",
            "isFavorite": False,
            "jobTitle": "Software Engineer",
            "companyName": "Company",
            "yomiCompany": "",
            "department": "Fish",
            "officeLocation": "London",
            "profession": "",
            "userPrincipalName": "[email protected]",
            "imAddress": "sip:[email protected]",
            "scoredEmailAddresses": [{
                    "address": "[email protected]",
                    "relevanceScore": -6.0991198031917175,
                    "selectionLikelihood": "notSpecified"
                }
            ],
            "phones": [],
            "postalAddresses": [],
            "websites": [],
            "personType": {
                "class": "Person",
                "subclass": "OrganizationUser"
            }
        }
    ]
}

Whereas the data from https://graph.microsoft.com/users/[email protected] is:

{
    "@odata.context": "https://graph.microsoft.com/v1.0/$metadata#users/$entity",
    "businessPhones": [],
    "displayName": "John Smith",
    "givenName": "John",
    "jobTitle": None,
    "mail": "[email protected]",
    "mobilePhone": None,
    "officeLocation": None,
    "preferredLanguage": None,
    "surname": "Smith",
    "userPrincipalName": "[email protected]",
    "id": "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX"
}
2
I didn't see the same scene as yours from my side. The fields officeLocation and jobTitle return the same results for both endpoints. Could you have a retry in Microsoft Graph Explorer: developer.microsoft.com/en-us/graph/graph-explorer?Allen Wu
@allen-wu I've tried that and updated my question with the results.parsley72
The additional permissions in Graph Explorer don't affect the result. I created an Azure AD App which enables the same API permissions: People.Read, User.Read, User.ReadBasic.All, email as yours. I can still get the correct response when I test it in Restlet Client. So the permissions above are enough. You enabled Delegated permission rather than Application permission right? Please add any screenshots which show the responses of your two calls.Allen Wu
@allen-wu I've added some (obfuscated) sample data above.parsley72

2 Answers

1
votes

Based on my test, I found that the information obtained by these two APIs came from different places.

"officeLocation" returned from /me/people seems to be maintained in SharePoint. You can sign in https://apc.delve.office.com/?u=3df5295a-e4b1-46fe-8969-e715ccd11077&v=editprofile to check it.

"officeLocation" returned from /me or /users/{id | userPrincipalName} is maintained in Azure AD. So you can check it in Azure AD -> Users.

After I update the "Office" in Azure AD, I query with the two endpoints. But they gave me two different result. One (/me/people) is old and the other one (/users/{id | userPrincipalName}) is new. Maybe this will take some time to synchronize. Or maybe they won't sync.

I also test it in Microsoft Graph Explorer. And the "officeLocation"s are different as well. So I'm not sure why Microsoft Graph Explorer works fine for you. But you can dig it along with my ideas.

I hope my findings will be helpful to you.

1
votes

Each "service" in the Graph (Active Directory, Exchange, SharePoint, etc.) make decisions on the data to return by default in calls. These decisions are made to best suit Microsoft in running the service, not necessarily what callers need. ;) I suggest adding the $select parameter to specify the attributes you require.

From https://docs.microsoft.com/en-us/graph/query-parameters#select-parameter:

Important: In general, we recommend that you use $select to limit the properties returned by a query to those needed by your app. This is especially true of queries that might potentially return a large result set. Limiting the properties returned in each row will reduce network load and help improve your app's performance.

In v1.0, some Azure AD resources that derive from directoryObject, like user and group, return a limited, default subset of properties on reads. For these resources, you must use $select to return properties outside of the default set.