3

I am getting 401 unauthorized error when calling a sharepoint search rest api (http://:/_api/search/query?querytext=) from a .net application using claims based authentication.

My request and error as below

private void GetSearchResponse(HttpWebRequest httpWebRequest)
{
    try
    {
        using (var httpWebResponse = httpWebRequest.GetResponse() as HttpWebResponse)
        {
            using (var stream = httpWebResponse.GetResponseStream())
            {
                ProcessSearchResponse(stream);
            }
        }
    }
    catch (WebException ex)
    {//catch and log the error
    } 

stack trace : "{\"error\":{\"code\":\"-2147024891, System.UnauthorizedAccessException\",\"message\":{\"lang\":\"en-US\",\"value\":\"Access denied. You do not have permission to perform this action or access this resource.\"}}}"

Thanks a lot in advance for your help and time.

3 Answers 3

1

Since SharePoint Online/Office 365 relies on Claims authentication use:

The following example demonstrates how to consume SharePoint Search REST using HttpWebRequest class:

public static SharePointOnlineCredentials PrepareSPOCredentials(string userName, string passWord)
{
    var securePassWord = new SecureString();
    foreach (var c in passWord.ToCharArray()) securePassWord.AppendChar(c);
    var credentials = new SharePointOnlineCredentials(userName, securePassWord);
    return credentials;
}

public static string ExecuteSearchRequest(Uri address,ICredentials credentials,string query)
{
   string result;
   var endpointUrl = new Uri(address,string.Format("/_api/search/query?querytext='{0}'",query));

   var request = WebRequest.Create(endpointUrl) as HttpWebRequest;
   request.Credentials = credentials;
   request.Headers.Add("X-FORMS_BASED_AUTH_ACCEPTED", "f");
   request.Method = "GET";
   request.Accept = "application/json; odata=verbose";
   var response = request.GetResponse();
   using (var reader = new StreamReader(response.GetResponseStream()))
   {
       result = reader.ReadToEnd();
   }
   return result;
}


//Usage
var credentials = PrepareSPOCredentials(userName, password);
var result = ExecuteSearchRequest(webUri, credentials, "contentclass:STS_ListItem AND ContentType:Task");
2
  • Thanks for your reply. We are using HTTP Post. And i tried all your parameters in request but getting the same 401 unauthorized error. Is it something we need to give access at centeral admin or AD level? because the same piece of code is working fine production but it is not working in dev.
    – Selvakumar
    Sep 15, 2014 at 15:19
  • I am also getting [MessageSecurityException: The HTTP request is unauthorized with client authentication scheme 'Anonymous'. The authentication header received from the server was ''.
    – Selvakumar
    Sep 15, 2014 at 16:37
0

The Search results have results which the particular user does not have access to . That is why you receive forbidden error .

While using the REST API provides a much more succinct way to retrieve data, there are apparently areas where you’ll need to use the more robust CSOM.

6
  • How and where can i add the permission to the particular user? Thanks for your help in advance. I am struggling a lot on this :(
    – Selvakumar
    Sep 12, 2014 at 19:57
  • sharepointbrandon.com/2013/08/… . . Please add the code as well to your question .
    – Nikhil J
    Sep 12, 2014 at 19:58
  • i may not change my code since the code is working fine in production.
    – Selvakumar
    Sep 12, 2014 at 20:12
  • @Nikil, Please refer my question for the updated code.
    – Selvakumar
    Sep 12, 2014 at 20:13
  • is your site anonymous and also using workflows ?
    – Nikhil J
    Sep 12, 2014 at 20:41
0

I have been using below. Worked for me for 10 days. Not sure what happened after that. The user account is still a SCA on the site and the password is still valid.

var securePassword = new SecureString();
                    foreach (var c in GlobalVar.siteSCAPassword)
                    {
                        securePassword.AppendChar(c);
                    }
                    credentials = new SharePointOnlineCredentials(GlobalVar.siteSCAUserName, securePassword);

using (var client = new WebClient())
                    {
                        client.Headers.Add("X-FORMS_BASED_AUTH_ACCEPTED", "f");
                        client.Credentials = credentials;
                        client.Headers.Add(HttpRequestHeader.ContentType, "application/atom+xml;type=entry");
                        client.Headers.Add(HttpRequestHeader.Accept, "application/atom+xml");

                        #region TOTAL PAGES
                        WriteLog("===TOTAL PAGES");
                        var uriTP = new Uri(GlobalVar.siteUrl + GlobalVar.searchApiSuffix + @"'*'&trimduplicates=false&rowlimit=10000&selectproperties='Title'&sourceid='fba6c3ac-3b5f-4714-9e27-87637da9e5fd'");
                        uriTP = new Uri(GlobalVar.siteUrl + GlobalVar.searchApiSuffix + @"'*'&trimduplicates=true&rowlimit=10&selectproperties='Title'");
                        WriteLog("Rest API : " + uriTP.AbsoluteUri);
                        var resultTP = client.DownloadString(uriTP);
}

The bottom line var resultTP = client.DownloadString(uriTP); now starts throwing 401 (unauthorized) error.

Your Answer

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