简体   繁体   中英

REST Search API The remote server returned an error: (401) Unauthorized

I have created a console application by using this tutorial:

http://blogs.msdn.com/b/kaevans/archive/2014/03/02/building-a-sharepoint-app-as-a-timer-job.aspx

With some differences of course, in my console app, I want to make a rest call to the search api.

Read this: Giving the App Principal Permissions Instead of using tenant manage as in the example I used this:

 <AppPermissionRequests>
    <AppPermissionRequest Scope="https://sharepoint/search" Right="QueryAsUserIgnoreAppPrincipal" />
  </AppPermissionRequests>

Then I went to “_layouts/AppInv.aspx”. And registered the app using the client id and the xml above.

Then I clicked on Trust it.

My app.config is like this:

<xml version="1.0" encoding="utf-8" ?>
<configuration>
  <configSections>
    <section name="Sites"
             type="System.Configuration.NameValueSectionHandler"/>
  </configSections>
  <appSettings>
    <add key="ClientId" value="xx-1c6c-45e7-8a2a-7364a705c836"/>
    <add key="ClientSecret" value="+xx="/>
  </appSettings>
  <startup> 
        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
    </startup>
  <Sites>
    <add key="site1" value="https://xx.sharepoint.com/sites/developersitecollection"/>
  </Sites>
</configuration>

Then my console app fails with Unauthorized Exception on the getresponse

static void Main(string[] args)
        {
            var config = (NameValueCollection)ConfigurationManager.GetSection("Sites");


            foreach (var key in config.Keys)
            {
                Uri siteUri = new Uri(config.GetValues(key as string)[0]);

                using (ClientContext clientContext = new ClientContext(siteUri))
                {
                    string realm = TokenHelper.GetRealmFromTargetUrl(siteUri);
                    string accessToken =
                        TokenHelper.GetAppOnlyAccessToken(TokenHelper.SharePointPrincipal,
                        siteUri.Authority, realm).AccessToken;

                    HttpWebRequest endpointRequest = (HttpWebRequest)HttpWebRequest.Create(siteUri +"/_api/search/query?querytext=%27*.pptx%27");
                    endpointRequest.Method = "GET";
                    endpointRequest.Accept = "application/json;odata=verbose";
                    endpointRequest.Headers.Add("Authorization", "Bearer " + accessToken);
                    HttpWebResponse endpointResponse = (HttpWebResponse)endpointRequest.GetResponse();
                    StreamReader reader = new StreamReader(endpointResponse.GetResponseStream());
                    var searchXml = new XmlDocument();
                    searchXml.LoadXml(reader.ReadToEnd()); 

                }
            }
        }

I wonder what the problem might be

QueryAsUserIgnoreAppPrincipal permission does exactly what it says... it queries search as the current user, ignoring the app permission. Your code gets an app-only permission, which does not provide user information. I would expect the 401 unauthorized in this scenario.

Remember that search queries are security-trimmed based on a user. You might try using Tenant Read permissions for an app-only context, removing the QueryAsUserIgnoreAppOnly, but I haven't tried to see if that will work. A better option might be simply using the SharePointOnlineCredentials class to specify a user that has sufficient permissions to access the content (if the user does not have access to the content, the content will not appear in search results).

http://blogs.msdn.com/b/kaevans/archive/2014/02/23/call-o365-using-csom-with-a-console-application.aspx

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM