Retrieving REST Data in a Claims Based Auth Site in SharePoint 2010

NOTE:   This posting is a very small part of one section of a new whitepaper coming out on claims and SharePoint 2010.  Look the whitepaper later this year or early next year.

SharePoint 2010 provides the ability to retrieve list data through a REST interface. In this example I'll reuse the code to get the FedAuth cookie that was included with this post: https://blogs.technet.com/b/speschka/archive/2010/06/04/using-the-client-object-model-with-a-claims-based-auth-site-in-sharepoint-2010.aspx. Once I have the FedAuth cookie I'll reuse it to make a call to retrieve list data via REST. The call will be slightly different because we’ll need to do HTTP GETs directly against the listdata service in SharePoint. The listdata service is available within any site by navigating to the _vti_bin directory. For example, if you have a site at https://claims, then to get all of the items in the Contacts list in that site you could make a request to https://claims/_vti_bin/listdata.svc/Contacts. The data is returned as Xml, which you can then process as needed for your application.

 

Here’s an example of code that reuses the method to obtain a FedAuth ticket, and then retrieves a list of all the items in the Contacts list:

 

private void GetRestDataBtn_Click(object sender, EventArgs e)

{

try

{

       //this is the REST endpoint I want to use to get all Contacts

       string endpoint = "https://fc1/_vti_bin/listdata.svc/Contacts";

 

       //get the FedAuth cookie

       string FedAuth = GetSamlToken();

 

       //make a request to the REST interface for the data

       HttpWebRequest webRqst = (HttpWebRequest)WebRequest.Create(endpoint);

       webRqst.UseDefaultCredentials = true;

  webRqst.Method = "GET";

       webRqst.Accept = "*/*";

       webRqst.KeepAlive = true;

 

       //create the FedAuth cookie that will go with our request

       CookieContainer cc = new CookieContainer();

       Cookie samlAuth = new Cookie("FedAuth", FedAuth);

       samlAuth.Expires = DateTime.Now.AddHours(1);

       samlAuth.Path = "/";

       samlAuth.Secure = true;

       samlAuth.HttpOnly = true;

       Uri samlUri = new Uri(SamlTxt.Text);

       samlAuth.Domain = samlUri.Host;

       cc.Add(samlAuth);

 

       //plug our cookie into the request

       webRqst.CookieContainer = cc;

 

       //read the response now

       HttpWebResponse webResp = webRqst.GetResponse() as HttpWebResponse;

 

       //make the request and get the response

       StreamReader theData = new StreamReader(webResp.GetResponseStream(), true);

       string payload = theData.ReadToEnd();

       theData.Close();

       webResp.Close();

 

       //create the Xml classes for working with the results

 

//xml doc, loaded with the results

       XmlDocument xDoc = new XmlDocument();

       xDoc.LoadXml(payload);

 

       //namespace manager, used for querying

       XmlNamespaceManager ns = new XmlNamespaceManager(xDoc.NameTable);

       ns.AddNamespace("b",

       "https://www.w3.org/2005/Atom");

       ns.AddNamespace("m",

       "https://schemas.microsoft.com/ado/2007/08/dataservices/metadata");

       ns.AddNamespace("d",

       "https://schemas.microsoft.com/ado/2007/08/dataservices");

 

       //query for items

  XmlNodeList nl = xDoc.SelectNodes("/b:feed/b:entry/b:content/m:properties", ns);

 

       //create a list to hold the results

       List<Contact> Contacts = new List<Contact>();

 

       //enumerate the results

       foreach (XmlNode xNode in nl)

       {

       Contacts.Add(new Contact(

xNode.SelectSingleNode("d:FirstName", ns).InnerText,

              xNode.SelectSingleNode("d:LastName", ns).InnerText,

              xNode.SelectSingleNode("d:Company", ns).InnerText,

              xNode.SelectSingleNode("d:JobTitle", ns).InnerText,

              xNode.SelectSingleNode("d:EMailAddress", ns).InnerText));

}

 

       //bind to the DataGridView on my form

       ContactGrd.DataSource = Contacts;

}

    catch (Exception ex)

    {

//your error handling here

 

    }

}

 

public class Contact

{

public string FirstName { get; set; }

public string LastName { get; set; }

public string Company { get; set; }

public string JobTitle { get; set; }

public string Email { get; set; }

 

public Contact(string First, string Last, string Company, string Title, string Email)

{

this.FirstName = First;

       this.LastName = Last;

       this.Company = Company;

       this.JobTitle = Title;

       this.Email = Email;

}

}

 

Stepping through the code, you can see that it starts out by getting the FedAuth cookie from SharePoint as demonstrated in the previous post I linked to above. Once the cookie is obtained, a new HttpWebRequest is made that will be used to call the REST interface in SharePoint to retrieve all items in the Contacts list. A new cookie is created where the FedAuth cookie that was retrieved can be placed; this is what allows SharePoint to view our request as being authenticated. Once the cookie has been added, the request is made to the REST interface in SharePoint to retrieve the data and the results are put into the string variable payload.

 

UPDATE:

If you are experiencing an error like "The HTTP request is unauthorized with client authentication scheme 'Negotiate'. The authentication header received from the server was 'Negotiate oW0wa6ADCgEBomQEYmBgBgkqhkiG9xIBAgIDAH5RME+gAwIBBaEDAgEepBEYDzIwMTEwODA1MjA1MTMzWqUFAgMDdRemAwIBKakPGw1DT05UT1NPLkxPQ0FMqhMwEaADAgEBoQowCBsGcG9ydGFs'.", then see the update in posting https://blogs.technet.com/b/speschka/archive/2010/06/04/using-the-client-object-model-with-a-claims-based-auth-site-in-sharepoint-2010.aspx for details on how to work through that.