The title of this post actually makes this sound a lot more complicated than the final solution. It's really a case of combining the techniques I discussed in two previous posts: http://blogs.technet.com/b/speschka/archive/2010/09/25/retrieving-rest-data-in-a-claims-based-auth-site-in-sharepoint-2010.aspx and http://blogs.technet.com/b/speschka/archive/2011/04/01/retrieving-data-from-a-multi-auth-site-using-the-client-om-and-web-services-in-sharepoint-2010.aspx. The short version of the scenario is this - some folks wanted to do a something like a health check ping against a SharePoint site that used SAML authentication. Previously they had only been working against sites that used on Windows authentication, and as soon as they tried those tools against a site that supported multiple authentication types - SAML and Windows - those tools stopped working.
The point of the health check is just to make a request to a site and make sure that data is returned; if some error code is returned instead then they can start digging into it. I decided the easiest way to do this was just to make a call to the listdata.svc that is the REST endpoint for the site. It is something that will always be there, and configuring it to force it into using NTLM in a multi-auth site is something that I figured would be pretty easy, and in fact it was. The gist of the approach is just to make an HttpWebRequest and add the header I described in the second link above to force it use NTLM. The result is a fairly straightforward looking chunk of code that looks like this:
string endpoint = UrlTxt.Text + "/_vti_bin/listdata.svc"; //make a request to the REST interface for the dataHttpWebRequest webRqst = (HttpWebRequest)WebRequest.Create(endpoint);webRqst.UseDefaultCredentials = true;webRqst.Method = "GET";webRqst.Accept = "*/*";webRqst.KeepAlive = true;webRqst.Headers.Add("X-FORMS_BASED_AUTH_ACCEPTED", "f");
//read the response nowHttpWebResponse webResp = webRqst.GetResponse() as HttpWebResponse;
//make the request and get the responseStreamReader theData = new StreamReader(webResp.GetResponseStream(), true);string payload = theData.ReadToEnd();theData.Close();webResp.Close();
ResultsTxt.Text = payload;
So as you can see, I just create the request, set a few properties and then add my header that tells SharePoint to use Windows auth. Then I just make my request and I'm good to go. It's a pretty simple project, but I've attached the complete solution to this posting in case it's helpful.
<p>Great post. I have a question that may or may not be related. I've been working to create a Custom Claims Provider for SP2010. I am authenticating to ADFSv2 to get a SAML token with some claims, and I want a custom claims provider (farm feature in SP2010) to then augment those claims. However, I want it to access content from a SharePoint list (within the custom claims provider) to use in augmenting the user's claims. But, in the custom claims provider the SPContext.Current object is always NULL... so I can't get a Web and can't get the pre-defined list.</p>
<p>So, I'm wondering am I doing something wrong in trying to use the SPContext.Current object for this, or is using REST as you've defined here the only way to access SharePoint list content from within a Custom Claims Provider?</p>
<p>After 4 days of fighting with dual- auth and getting 403 Forbidden errors, when trying to access the Excel REST services, you finally saved me!! That one line of code is magical. THANKS!</p>