How to issue Http Web Requests to a SharePoint 2010 site with FBA and SSL

The .NET Framework provides some handy classes that help you manage HTTP communication through requests and response objects.

Everything is plain and simple, as long as you are connecting to a resource endpoint that does not require authentication and is available through an unsecure channel (i.e. HTTP). Which, of course, is not always the case.

I had a requirement to “invoke” a SharePoint 2010 resource (a file, for example) that is protected by Forms Based Authentication and is exposed by a secured SSL channel. The task is slightly more complicated, since it has to be performed by a client that has no easy way to invoke web services using an autogenerated proxy. That is, no “Add Web Reference” available. Indeed, no RAD environment at all.

You can find my solution in the code snippet below. I have written it with PowerShell just as a prototyping tool, it will have to be translated. But anyway some interesting points can be highlighted:

  • I used the .NET Fx API to “ignore” SSL certificate warnings. This may not be an option sometimes, but the solution can be extended adding some certificate chain verification or whatever you need to check. This is done setting the ServerCertificateValidationCallback static property (line 1).
  • I had to invoke the Authentication.asmx SharePoint Web Service in order to authenticate and, then, reuse the authentication cookie in subsequent requests. This is a requirement for FBA access. I handcrafted the SOAP message since there’s no easy-to-use helper/proxy (line 2-24).
  • I finally issued my HTTP request, using the authentication cookie and adding an HTTP header (line 26-28).
   1: [System.Net.ServicePointManager]::ServerCertificateValidationCallback = {$true}

   2: $cookieContainer = new-object System.Net.CookieContainer

   3: $authEnvelope = '<?xml version="1.0" encoding="utf-8"?>

   4:                 <soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">

   5:                   <soap:Body>

   6:                     <Login xmlns="http://schemas.microsoft.com/sharepoint/soap/">

   7:                       <username>yourusername</username>

   8:                       <password>yourpassword</password>

   9:                     </Login>

  10:                   </soap:Body>

  11:                 </soap:Envelope>';

  12: $encoder = [System.Text.Encoding]::UTF8

  13: $authEnvelopeBytes = $encoder.GetBytes($authEnvelope)

  14:  

  15: $authRequest = [System.Net.HttpWebRequest]([System.Net.HttpWebRequest]::Create("https://yoursite/_vti_bin/authentication.asmx"))

  16: $authRequest.CookieContainer = $cookieContainer

  17: $authRequest.Headers.Add("SOAPAction", "http://schemas.microsoft.com/sharepoint/soap/Login");

  18: $authRequest.ContentType = "text/xml; charset=utf-8";

  19: $authRequest.ContentLength = $authEnvelopeBytes.Length

  20: $authRequest.Method = "POST";

  21: $authRequestStream = $authRequest.GetRequestStream()

  22: $authRequestStream.Write($authEnvelopeBytes, 0, $authEnvelope.Length)

  23: $authRequestStream.Flush()

  24: $authRequest.GetResponse()

  25:  

  26: $request = [System.Net.HttpWebRequest]([System.Net.HttpWebRequest]::Create("https://yoursite/yourcontent"))

  27: $request.CookieContainer = $authRequest.CookieContainer

  29: $request.GetResponse()

 

Leave a Reply

Your email address will not be published. Required fields are marked *