10

I'm developing an Office add-in and am following an excellent blog post by Richard diZerega in order to leverage the O365 discovery service and enumerate the SharePoint sites to which a user has access. The discovery service is the fifth and final authentication scheme he discusses in his post.

Debugging locally, having configured the application in my development Azure AD tenant, it works. I get a response from the discovery service and am then able to initiate a search for SharePoint sites (just as Richard does in his sample code). The response looks like this:

{
  "@odata.context": "https://api.office.com/discovery/v1.0/me/$metadata#allServices",
  "value": [
    {
      "@odata.type": "#Microsoft.DiscoveryServices.ServiceInfo",
      "@odata.id": "https://api.office.com/discovery/v1.0/me/services('MyFiles@O365_SHAREPOINT')",
      "@odata.editLink": "services('MyFiles@O365_SHAREPOINT')",
      "capability": "MyFiles",
      "entityKey": "MyFiles@O365_SHAREPOINT",
      "providerId": "72f988bf-86f1-41af-91ab-2d7cd011db47",
      "providerName": "Microsoft",
      "serviceAccountType": 2,
      "serviceApiVersion": "v1.0",
      "serviceEndpointUri": "https://[tenant]-my.sharepoint.com/_api/v1.0/me",
      "serviceId": "O365_SHAREPOINT",
      "serviceName": "Office 365 SharePoint",
      "serviceResourceId": "https://[tenant]-my.sharepoint.com/"
    },
    {
      "@odata.type": "#Microsoft.DiscoveryServices.ServiceInfo",
      "@odata.id": "https://api.office.com/discovery/v1.0/me/services('RootSite@O365_SHAREPOINT')",
      "@odata.editLink": "services('RootSite@O365_SHAREPOINT')",
      "capability": "RootSite",
      "entityKey": "RootSite@O365_SHAREPOINT",
      "providerId": "72f988bf-86f1-41af-91ab-2d7cd011db47",
      "providerName": "Microsoft",
      "serviceAccountType": 2,
      "serviceApiVersion": "v1.0",
      "serviceEndpointUri": "https://[tenant].sharepoint.com/_api",
      "serviceId": "O365_SHAREPOINT",
      "serviceName": "Office 365 SharePoint",
      "serviceResourceId": "https://[tenant].sharepoint.com/"
    }
  ]
}

Peanut butter and jelly time? Well, sort of...

When testing the same add-in (with the same permissions in Azure AD) pointing to my client's SharePoint Online tenant, I receive a valid but empty response from the discovery service:

{
  "@odata.context": "https://api.office.com/discovery/v1.0/me/$metadata#allServices",
  "value": [ ]
}

For whatever reason, RootSite is not returned as it is when testing the add-in in my development environment. In fact, nothing is returned at all. I have confirmed that the OAuth token exchange is working in both environments thanks to the remote debugging capabilities available with Azure (in which the production web application is running). I just can't seem to get anything back from the discovery service when pointing to the client's SharePoint Online tenant/app catalog.

Here are the permissions for both the development and production applications in their respective Azure AD tenants:

  • Microsoft Graph
    • Delegated Permissions
      • Sign users in
  • Office 365 SharePoint Online
    • Delegated Permissions
      • Read managed metadata
      • Run search queries as a user
      • Read and write items in all site collections
  • Windows Azure Active Directory
    • Delegated Permissions
      • Sign in and read user profile

What determines whether or not RootSite is returned from the discovery service?

Do the user's permissions within the root SharePoint Online site matter? Is there some configuration setting within either Azure AD or the SharePoint Online administration interface to "light up" the discovery service and the RootSite capability? Why would additional permissions, such as "Read items in all site collections" be necessary in production when they don't appear to be necessary in development? The client uses federated authentication; does/should that matter?

Note: Special thanks to Richard diZerega and Jeremy Thake for replying to me on Twitter =).

[Update - 12/21]

Granting the "Read items in all site collections" delegated permission on both the Microsoft Graph application and the Office 365 SharePoint Online application doesn't change anything--the response from the discovery service is still valid but empty.

5

Okay, mystery solved, I guess. We ended up burning a Microsoft support case. It turns out that, even though the account(s) I was using to test the add-in had access to the client's SPO tenant, none of them had an O365 license associated to them. The accounts were initially created in the client's AD and then synced into their SPO tenant. While that granted access to the SharePoint sites and SharePoint administrative areas, it didn't implicitly confer a full-fledged O365 license to the accounts.

I understand why the OAuth flow succeeded anyway--that has to do with Azure and the delegated permissions granted to our add-in. However, what (still) bothers me a little is the fact that the O365 discovery service call returned a valid yet empty response. You'd think calling the O365 discovery service using a token obtained on behalf of a user that didn't have an O365 license would generate an HTTP response other than a 200.

Be sure that the accounts on behalf of which you're calling the O365 discovery service have an O365 license associated to them.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.