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.
Comments
Anonymous
January 01, 2003
The comment has been removedAnonymous
January 01, 2003
Hi Steve, Thanks for this post. Is it necessary to use this method when in a Claims-based authentication enabled site? Can't you just use a normal Web Reference and it's context? I'm asking because I've been getting errors with my silverlight web part (which uses listdata.svc) in a claims-based authentication enabled site. Cheers, YohanAnonymous
June 09, 2011
Hi, do you have a link to the GetSamlToken() method you're using? Can this method be modified to look into AD instead of a custom or Adfs provider? I want to do this to connect to a site in a web app which is in claims mode (Active Directory only) and FBA (Ldaps). I don't know how to get the cookie. If I copy the cookie using Fiddler (and IE) and set it in the GET call it works. ThanksAnonymous
October 24, 2011
Do we need to add servcice reference to use this service, the way you have described?Anonymous
June 12, 2012
this is brutal man! :) it saved me a lot of investigation, thanx.Anonymous
June 23, 2013
Nice Post !!. Is there any way to get this working using Jquery.ajax() ?Anonymous
January 30, 2014
Although this article is very old, I hope you still get a notification for this. I got the problem that a site with mixed authentication windows + fba in sharepoint 2013 claims doesn't allow for specific credentials to be handed over. If I use DefaultCredentials everything is fine, if not, 401 Unauthorized is returned. Thanks for your helpAnonymous
April 09, 2014
This seems to be serving my requirements. Thanks to you!
However when I copied the code into my windows application in VS 2012, I found VS could not able to locate GetSamlToken() method, I searched in google too but no luck.
Could you please help me which namespace I forgot to include in my project.
Thanks in Advance.Anonymous
August 16, 2014
I'm not sure what is SamlTxt.Text in the code. Could you please explain?Anonymous
September 18, 2014
The comment has been removedAnonymous
March 01, 2015
The comment has been removedAnonymous
March 01, 2015
The comment has been removed