Using add-in only / app-only permissions with search queries in SharePoint Online

Previously it was not possible to use search APIs in the SharePoint only with add-in only or app-only permissions, but this capability has been included in the SharePoint Online and you can use the search APIs now with add-in only or app-only permissions. This is really interesting capability, which will open up multiple different additional scenarios and there has been pretty high demand for this capability from the community.

When you are using SharePoint Online search APIs with app-only permissions, you will need to request full permissions to the tenant when you are registering the add-in/app for the tenant. This will grant needed permissions to query information from the Office 365 tenant without security trimming applied.

Updated on 5th of August – Please note the updated guidance on providing tenant level permissions. You’ll need to grant these permissions under the tenant admin URL. See following PnP MSDN article for additional details – How to provide add-in app only tenant administrative permissions in SharePoint Online.

Step-by-Step configuration and testing

Here’s the needed steps to make this happen.

  • Start by registering a Client Id and Client Secret by going to /layouts/15/appregnew.aspx in your tenant. You can generate the Client Id and Secret by clicking the buttons next to the field.

image

  • When you are completed with registration, make sure that you copy the Client Id and Client Secret in the registration page, since we will use them in our sample application and while we provide needed permissions for the registration.

image

  • Continue by giving app/add-in registration needed permission by moving to /layouts/15/appinv.aspx. Perform lookup by using the just registered app id. Use following xml snippet as the App’s Permission Request XML entry
 <AppPermissionRequests AllowAppOnlyPolicy="true">
     <AppPermissionRequest Scope="https://sharepoint/content/tenant"
                           Right="FullControl" />
 </AppPermissionRequests>

image

  • Approve the requested permissions. Notice that since we are asking tenant wide permissions for this add-in/app registration, account used for this operation has to be also tenant administrator or granting the permissions will fail. It’s important to understand that this will grant full access on any information in this particular tenant for the add-in/app using the specific client identifier and secret.

image

  • Open up Visual Studio for testing the provided permissions and let’s create our test client
    • In this case we simply test this with Console application, but you could just as well use the same capability with provider hosted add-in/app or with for example Azure WebJobs.

image

  • Let’s right click the project name and choose Manage NuGet Packages…

image

  • Search for ‘pnp’ and select OfficeDevPnPCore16, which is the PnP Core component targeted for SharePoint Online. Technically you could also use only the SharePoint Online CSOM Nuget, but that’s also automatically included in the PnP Core component, which will give you additional capabilities and will increase productivity of developers.

image

  • Click Install and Accept the license agreements from the Nuget packages which are automatically pulled down from Nuget Gallery

image

  • Open app.config from the Visual Studio project and add new appSettings section, with ClientId and ClientSecret keys. Update the value attributes based on your app registration details, since these are tenant specific.

image

  • Add following using statements to Program.cs file
 using Microsoft.SharePoint.Client;
 using Microsoft.SharePoint.Client.Search.Query;
  • Update Main method of the Program.cs as following
    • We are creating
    • Notice that you wan to update the QueryText propery of the KeywordQuery object based on your environment
 static void Main(string[] args)
 {
     // Create client context with app-only permissions using 
     // client id and secret
     var tenantAdminUri = new Uri("https://vesaj.sharepoint.com");
     string realm = TokenHelper.GetRealmFromTargetUrl(tenantAdminUri);
     var token = TokenHelper.GetAppOnlyAccessToken(
                         TokenHelper.SharePointPrincipal,
                         tenantAdminUri.Authority, realm).AccessToken;
     using (var cc = TokenHelper.GetClientContextWithAccessToken(
                                 tenantAdminUri.ToString(), token))
     {
         // Just to double check permission setup
         Web web = cc.Web;
         cc.Load(web);
         cc.ExecuteQuery();
         string title = web.Title;
 
         // Actual query to be executed. You will need to have
         // tenant full permissions when used in app-only mode
         KeywordQuery keywordQuery = new KeywordQuery(cc);
         keywordQuery.QueryText = "WhateverYouWant";
         SearchExecutor searchExecutor = new SearchExecutor(cc);
         ClientResult<ResultTableCollection> results =
                     searchExecutor.ExecuteQuery(keywordQuery);
         cc.ExecuteQuery();
         // Just to output something
         Console.Write("Number of results - " + results.Value[0].RowCount);
         // Pause console for showing output
         Console.ReadLine();
     }
 }
  • All ready to go. If you have followed above step correct, you can simply start debugging by pressing F5 or select Start Debugging from the Debug menu to see how your query is performing.

 

FAQ – Frequently Asked Questions

Q - Does it work with permissions given directly using Azure Active Directory?

Unfortunately no. Currently this capability is only available if permissions are given using classic ACS based technique by using appregnew.aspx page. Having similar support with permissions given directly from the Azure Active Directory is being looked at, but there’s no exact schedule at the time of writing this blog post.

Q - Does this work in on-premises (SharePoint 2013 & 2016)?

Unfortunate no. This is currently specific capability implemented only for SharePoint Online and it’s not available in SharePoitn 2013 or in SharePoint 2016. Please use the UserVoice by providing us feedback around the requirements for this for on-premises.

Q - Does this model work with SharePoint hosted add-ins/apps?

No. SharePoint hosted add-ins do not support app-only or add-in only permissions. You cannot also provide tenant level permissions for SharePoint hosted add-ins.

Q - What permissions are needed for getting this to work?

To make the search queries work with add-in only or app-only context, app/add-in registration will need to have tenant full permissions like shown in the above sample. Person who will register these permissions for the add-in/app will need to be also tenant administrator.

Q - When permissions are set, app/add-in can then query all the information in SharePoint Online?

This is correct. If you provide add-in or app full permissions for the tenant, including the support or app-only / add-in only access, requests using this context will have full permission to the information in SharePoint Online regardless of the end user permissions.

Office 365 Developer Patterns and Practices

Office365PnPLogoRed_thumb1Techniques showed in this blog post are part of the Office 365 Developer Patterns and Practices (PnP) guidance, which contains guidance and reusable solutions for demonstrating different patterns and practices related  on the development for Office 365 and SharePoint on-premises.

Check the details around PnP from dev.office.com at https://aka.ms/OfficeDevPnP.  Please join us on sharing patterns and practices for the community for the benefit of the community. If you have any questions, comments or feedback related on this sample, blog post or anything on PnP, please use the Office 365 Developer Patterns and Practices Yammer group at https://aka.ms/OfficeDevPnPYammer.

“Sharing is caring”