I decided to write a post on this topic because there’s surprisingly little information out on the Web about how to do this, and most of the blog posts and articles I found that came close to addressing it were pretty old (2011 or 2012 timeframe). Considering SharePoint Online was upgraded last year to Office/SharePoint 2013 I wanted to get some more current information out there.
The scenario I’m covering is connecting to a SharePoint Online (Office 365) REST or CSOM API from an on-premise SharePoint 2010 farm. Why do that? Well, in my case it’s because I was building an event receiver in SharePoint 2010 to automatically copy documents (files) out to a SharePoint Online site for a hybrid on-premise/online solution. The 2010 farm I was using is slated for an upgrade to 2013 later this year but for now I was stuck with 2010. Also, because of the “background” nature of an event receiver, an implicit requirement of this scenario is non-interactive (“headless”) authentication to SharePoint Online.
Options I Considered
The “Old” Ways
I started, of course, by looking at what’s already out on the Internet. I found the two famous (but older) articles everyone reads who tries to connect to SharePoint Online: the MSDN article by Rob Bogue and the “headless authentication” blog post by Chris Johnson. I’ve worked with Rob before and he’s a smart guy. His approach does work but requires an interactive user which wasn’t an option in my case. The approach by Chris Johnson probably works too but given that it was written back in 2011 and seemed a little “hackish” I wanted to find something better if possible. (For the sake of completeness there’s also a famous blog post by Wictor Wilen on this topic but much of his approach was rolled into what Chris Johnson wrote about.)
The “New” Ways
Given SharePoint Online’s upgrade to Office 2013 last year I decided to consider the new “app” model. In particular I thought a provider-hosted app might be a good solution with the event receiver being the “provider-hosted” portion of the app. An MSDN article on OAuth authentication for apps needing on-the-fly permissions in SharePoint 2013 got me really close. The app model has concepts like authentication built right into it, after all. The problem, however, is the user at some point is still required to grant the app permissions to access what it needs (much like Facebook or mobile apps often ask you to do). High trust apps are a workaround for that requirement but can’t be used in SharePoint Online. So the app model was out.
Another newer approach is the SharePoint 2013 Client-Side Object Model and SharePointOnlineCredentials class which are built to do non-interactive authentication to SharePoint 2013/Online. However there are three problems with this:
- The SharePoint 2013 CSOM targets .NET 4.0+. Code running within SharePoint 2010 can only use up to .NET 3.5.
- Given the .NET 3.5 constraint I could use the SharePoint 2010 CSOM but the SharePointOnlineCredentials class didn’t exist in that version.
- Even the newer 2013 stuff doesn’t readily support calling the REST API. I wanted a common authentication mechanism for both CSOM and REST.
I really liked the new SharePointOnlineCredentials approach in the 2013 CSOM so I decided to duplicate it in my SharePoint 2010 code. My first step was using ILSpy to crack open the 2013 code and “copy” that class (plus a few others that it uses) into my project. A few minor tweaks were needed but nothing show-stopping. In addition I also created a lightweight SharePointOnlineClientContext class that inherits from ClientContext (the 2010 version) and makes some very slight tweaks to get it working with the 2013 version of SharePoint Online.
The result is I can write code that looks like this in my 2010 event receiver:
var creds = new SharePointOnlineCredentials(
using (var ctx = new SharePointOnlineClientContext(SPO_URL))
if (ctx != null)
ctx.Credentials = creds;
List list = ctx.Web.Lists.GetByTitle("Shared Documents");
var fileCreateInfo = new FileCreationInformation();
fileCreateInfo.Content = myFileAsByteArray;
fileCreateInfo.Overwrite = true;
fileCreateInfo.Url = new Uri(SPO_URL, "/Shared Documents/" + myFileName).AbsoluteUri;
File file = list.RootFolder.Files.Add(fileCreateInfo);
This obviously isn’t production-ready code (for example, it doesn’t include copying metadata, error handling, etc.) but serves to demonstrate the point. And again, this is using the SharePoint 2010 CSOM from within a 2010 farm to create a file in the current (2013) version of SharePoint Online. What’s involved in upgrading this to the 2013 CSOM later? Not much. Basically you’d just need to:
- Update the project references to use the 2013 CSOM DLLs (which you can download here).
- Delete the custom SharePointOnlineCredentials class (and other classes it uses) because they’re already built into 2013 (but you don’t have the change your code because the constructor syntax is the same).
- Switch the SharePointOnlineClientContext class in the ‘using’ statement back to just ‘ClientContext.’
Now what about the REST API for SharePoint Online?
Here’s a code sample that connects to the REST API:
var creds = new SharePointOnlineCredentials(
HttpWebRequest request = (HttpWebRequest)
HttpWebRequest.Create(SPO_URL + "/_api/web/lists");
request.Credentials = creds;
request.Method = "GET";
request.Accept = "application/json;odata=verbose";
var response = (HttpWebResponse)request.GetResponse();
using (var reader = new System.IO.StreamReader(response.GetResponseStream()))
This code sample was taken from a console app running on the 2010 farm (but still targeting .NET 3.5 and using my same custom SharePointOnlineCredentials class). All it does is connect to the “/lists” REST endpoint and do a text dump to the console of whatever it gets back. The key in making this work is the line that adds the “X-FORMS_BASED_AUTH_ACCEPTED” header. Without that line connecting to SharePoint Online’s REST API will fail with a 403 forbidden error.
Both of the above code snippets work without requiring an interactive user which meets my requirement for “background” code. The only caveat is you’d need an account in SharePoint Online whose username and password you can use for authentication. There’s no pass-through/impersonation of an account from the 2010 farm. But I think that’s actually a good thing because it gives you fine-grained control over what this code is allowed to do on the SharePoint Online side because you control those permissions there.
One last piece of this solution is a certificate (trusted root authority) that must be installed in the SharePoint 2010 farm if you use this code from within SharePoint itself. The reason is you’re connecting to SharePoint Online over ‘https’ which means there’s a certificate on the Office 365 side your farm needs to trust. The root authority on the Office 365 side is a “Baltimore CyberTrust” certificate which you can download from https://cacert.omniroot.com/bc2025.crt. Install this certificate in your farm using either PowerShell or the “Manage Trusts” page in Central Administration and you should be good to go. Without it you’d see an error in the event viewer (not the ULS logs) about an untrusted root authority.
Get the Code
A sample project can be downloaded at http://inclinetechnical.com/learning/code/DotNet35ToSPO.zip. It’s a .NET 3.5 console application created in Visual Studio 2013 and demonstrates connecting to both the CSOM and REST APIs of SharePoint Online as I’ve written about in this post. Moving the code from the console into SharePoint is mostly a matter of installing the certificate I mentioned a moment ago but for testing purposes a console app is just easier to play with.
I’ve seen several people in forums, on LinkedIn, etc. asking how to do this so I’m hoping someone out there finds this information useful. And if you find ways to improve it please comment as that would benefit all of us, myself included. Likewise if you run into problems those are good to know about too. Happy coding!