0

Using SharePoint Online, I discovered that it's possible to perform server-wide searches using the SharePoint Search API.

This works brilliantly in my browser, if I am logged in with my account, when I access: https://mycompanytenant.sharepoint.com/_api/search/query?querytext=%27abc%27

I can see all the results there.

I am trying to use this functionality in a user-consented app. After performing the OAuth2 authorization flow and grabbing a token, performing the same request results in the following:

statusCode: 401,
message: '401 - "{\\"error_description\\":\\"Invalid issuer or 
signature.\\"}"',

This is the code used for the request:

const requestOptions = {
    url: `https://${tenant}/_api/search/query?querytext='${query}'`,
    headers: {
        'Authorization': 'Bearer ' + this.accountInfo.accessToken
    },
    method: 'GET'
}

return requestPromise(requestOptions) // node module that handles requests as promises
  .catch(error => {
      console.log('SP Error: ', error);
      return bluebird.reject(error);
  });

My problem is that, while the access token is fully functional for use in the Graph API (the only other API that my app consumes), it is not being authorized for the search API. I assume this must be an issue with the scopes. So, I have tried configuring all logical scopes for my app (and requesting permission in the app during authentication), and I have even granted admin consent for my app, to be sure. Here are the currently configured resources:

Scopes

In spite of this, the same error persists. What am I missing?

According to the documentation, this should be possible.

5
  • so when you say app? is it SharePoint provider hosted app? Commented Jun 3, 2019 at 10:39
  • I'm not overly familiar with Sharepoint terminology. It's just an app that allows users to access their sharepoint files through the graph API, and now we're implementing support for search as well, which is not possible to do in a single request through the Graph API - hence why we're looking into the Search API. I believe the answer to your question is no, though I am not sure. Commented Jun 3, 2019 at 10:47
  • is this node js app? Commented Jun 3, 2019 at 10:55
  • yes, it is a node js app. Commented Jun 3, 2019 at 10:56
  • interesting use case...given you direction in answer below..I would also try think myself later... Commented Jun 3, 2019 at 11:43

2 Answers 2

0

Accessing SharePoint data from a Non-SharePoint application is different from how you do it using graph API. As you are using SharePoint online and Node JS, there is one module 'node-sp-auth' which will help you to do authentication and get context and then call REST APIs.

With SharePoint online, you would have either use Add In Permission or SAML based user credentials.

For Add In permission you have to generate client Id and secret and grant required permission to tenant or SharePoint site(as per your requirement scope). You can refer to this article to know details on this approach

After you have client id and secret with required permission. methods available in node-sp-auth module

import * as spauth from 'node-sp-auth';
import * as request from 'request-promise';

var credentialOptions = {clientId:"",clientSecret:""};

    //get auth options
    spauth.getAuth(url, credentialOptions)
      .then(options => {

        //perform request with any http-enabled library (request-promise in a sample below):
        let headers = options.headers;
        headers['Accept'] = 'application/json;odata=verbose';

        request.get({
          url: "https://${tenant}/_api/search/query?querytext='${query}'",
          headers: headers
        }).then(response => {
          //process data
        });
      });

For SAML based token, you have to pass username and password of user to credentialOptions

Hope this gives you direction.... feel free to comment for any further queries.

5
  • ok wow, this seems very promising. I'll try this out and let you know as soon as I get it working (hopefully). Thank you in advance :) Commented Jun 3, 2019 at 12:04
  • Alright so I tried the add-in permission approach, which you suggested... and I think there is some progress. I managed to retrieve a token. The error code switched from 401 to 403 - "Access denied. You do not have permission to perform this action or access this resource." Which I assume must be some missing scope, not sure which. But all in all, this is rather weird - the app is simulating add-in permission, but for the app itself, not as a user - so all users would have the same permissions, all users would see the same search results, overwriting the sharepoint permission system. Commented Jun 3, 2019 at 14:10
  • @LuisFigueiredo...your observation is correct, with Add In permission, it will not consider user permission but add-in permission to display search result...for that you have to use SAML based token. Regarding scope, can you please provide what scope you added while granting permission...your use case is intresting, I will try and see if we can access via user principal from node js application. Commented Jun 3, 2019 at 18:38
  • Thanks for all the help Siddharth, we didn't really understand these concepts very well when we started trying to implement this. We're sure our use case is not possible after hearing your explanation. Even if it were technically possible, it wouldn't be useful for us, as requesting admin consent for the app is a deal-breaker, and storing usernames and passwords is equally a no-go. We'll go on to support only the search available through the graph API, that is, inside each drive individually. Which is a shame but oh well ^^ Oh and the scope we tried was sites.search.all and fullcontrol Commented Jun 4, 2019 at 9:05
  • understood....I was doing some research....Ideally we can implement our OAuth authentication with SharePoint where we will get user based context which will work.... I have not tried this but this should work... but in your case then you would need to start auth flow one for GRAPH API and one for SharePoint API which won't be very user friendly experience... but i will further dig into this and share if I found anything concrete .. Commented Jun 4, 2019 at 9:14
0

You'll need an app-principal to access SharePoint from outside SharePoint. See the Authorization Code OAuth flow for SharePoint Add-ins documentation.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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