Today, Microsoft quietly launched the “search” permission scope in Azure AD Applications. This is huge step in delivering new scenarios with the Office 365 APIs that leverage SharePoint search and the Office Graph. In this post, I’ll illustrate how to leverage search with the Office 365 APIs and use it to query site collections and modern groups a user has access to (a difficult/impossible task with the Office 365 APIs until today). The video below illustrates some of the key components of the post.
Apps for SharePoint and Office are considered “contextual” since they are launched from the platform they extend (often with contextual detail such as the host site URL). In contrast, applications built with the Office 365 APIs can stand on their own and connect INTO Office 365. Because these modern applications lack contextual launch parameters, the Office 365 APIs use a Discovery Service to get information on the resources available to the user/tenant. The Discovery Service provides high-level resource details such as Mail, Contacts, Calendar and OneDrive. It does not provide detail on every site collection a user has access to (a frequent ask by developers). The new search permission scope for Azure AD Applications can be used to query more granular details.
Adding the Search Permission
Configuring an application with permissions to Office 365 is usually accomplished through the “Add Connect Service” wizard of Visual Studio. Behind the scenes, this wizard registers an application in Azure AD and configures its “permission to other applications”. The ability for Azure AD to manage permissions to multiple apps/services is often referred to as “common consent”. Search is a brand new permission we can add through common consent. At the time of this post, the Visual Studio tooling does not surface this new permission scope. However, it can easily be added by going to the “Configure” tab of the application in Azure AD.
Performing Search in Code
The Office 365 APIs provide a comprehensive set of libraries for authentication, discovery, and performing operations against resources in Office 365. Although strongly-typed APIs exist for many operations, search is brand new to the Office 365 APIs so no strongly-typed functions yet exists. That doesn’t mean we can’t use the Office 365 APIs to get an access token that we can use with the REST endpoints for SharePoint search. To do this, we need a resource-specific access token. I was able to perform a successful search using the “MyFiles” resource. I suspect the “MyFiles” service resource URI is specialized for file access only. However, the Discovery Service should have a new “RootSite” resource that will work. The “RootSite” represents the root site collection in SharePoint Online (https://tenant.sharepoint.com) and not to be confused with the OneDrive root site or “My Site Host” (https://tenant-my.sharepoint.com).
private async Task<string> getAccessToken()
// setup app info for AuthenticationContext
// create auth context (note: no token cache leveraged)
// create O365 discovery client
// query discovery service for endpoint for 'RootSite' endpoint
// get access token for RootSite
With our resource-specific access token, we can add it as a bearer token in the authorization header of our REST calls. The code below illustrates the full REST call and the parsing of JSON into strongly-typed classes.
private static async Task<List<SearchResult>> getSearchResults(string query)
The getSearchResults method takes a search string in REST format. The sample provides two simple examples…one that queries all site collections for the user (contentclass:sts_site) and one that queries all modern groups for a user (contentclass:sts_site WebTemplate:GROUP). It is generic enough to take just about any search string formatted for REST, but these scenarios have specific interest to me and my customers. Notice that all search string start with /search. This is because the RootSite resource endpoint URI ends with _api.
public static async Task<List<SearchResult>> GetSiteCollections()
public static async Task<List<SearchResult>> GetModernGroups()
Microsoft is really doubling down on the Office 365 APIs and the incorporating the search permission is a great example. I’m really excited to see what additional permissions 2015 will bring. You can download the sample MVC app used in the post and video HERE.