Creating a SharePoint CSOM ClientContext with an authentication cookie

There are a few ways to use CSOM to authenticate to SharePoint. Some of those include:

- Using an AccessToken (OAuth2/SP2013 app model)
- With the SharePointOnlineCredential helper class where you supply a username and password

Now, I wanted to do neither of these things. In my case, I had already logged into SharePoint, and had a FedAuth and rtFa cookie available to me and wanted to construct a ClientContext from those. It took me a while to work out – skip to the end for the code :-)

Wictor Wilen did some work in this area a few years back with his MsOnlineClaimsHelper class. I tried to follow his methods to form my ClientContext by using a CookieContainer to add the FedAuth cookie to ClientContext WebRequest objects, and applying a UserAgent header, and so on…but was consistently met with a 403 response from SharePoint.

Then I came across a post comparing MsOnlineClaimsHelper with the SharePointOnlineCredentials class – which helpfully pointed out that the latter was a supported replacement and should be used. The SharePointOnlineCredential class makes CSOM really trivial to use with a username and password:

SecureString pw = new SecureString();
foreach (char c in "mypassword".ToCharArray())
pw.AppendChar(c);
context.Credentials = new SharePointOnlineCredentials("jonathan.cardy@repstor.com", pw);
context.Load(context.Web);
context.ExecuteQuery();

The crucial point is that at some point along the line, the SharePointOnlineCredentials class converts a username and password into a FedAuth cookie, and it’s the process of supplying the FedAuth cookie in ClientContext web requests that I was having trouble implementing myself. So at this point I opened up the JetBrains dotPeek decompiler for the Microsoft.SharePoint.Client.Runtime.dll assembly, and found the SharePointOnlineAuthenticationModule which did exactly that, in the GetSpoAuthCookieAndUpdateRequest method:

private bool GetSpoAuthCookieAndUpdateRequest(WebRequest request, SharePointOnlineCredentials spoCredentials, bool preAuthentication)
{
string uriString = request.RequestUri.ToString();
int length1 = uriString.IndexOf('?');
if (length1 > 0)
uriString = uriString.Substring(0, length1);
int length2 = uriString.IndexOf('#');
if (length2 > 0)
uriString = uriString.Substring(0, length2);
int length3 = uriString.IndexOf("/_vti_bin", StringComparison.OrdinalIgnoreCase);
if (length3 > 0)
uriString = uriString.Substring(0, length3);
int length4 = uriString.IndexOf("/_api", StringComparison.OrdinalIgnoreCase);
if (length4 > 0)
uriString = uriString.Substring(0, length4);
Uri url = new Uri(uriString);
string authenticationCookie;
if (preAuthentication)
{
authenticationCookie = spoCredentials.GetAuthenticationCookie(url, false, true);
if (string.IsNullOrEmpty(authenticationCookie))
authenticationCookie = spoCredentials.GetAuthenticationCookie(url, true, true);
}
else
authenticationCookie = spoCredentials.GetAuthenticationCookie(url, true, true);
if (string.IsNullOrEmpty(authenticationCookie))
return false;
request.Headers[HttpRequestHeader.Cookie] = authenticationCookie;
return true;
}

The important bit here is just the single line:
request.Headers[HttpRequestHeader.Cookie] = authenticationCookie;

Previously I had tried to set the cookies via a CookieContainer object, which didn’t work (I got 403 errors). I don’t know why, but setting the cookie directly via the Cookie header works.

Now in our case we have both a FedAuth and an rtFa cookie so we can put it all together like this:

ClientContext cc = new ClientContext(spSiteUrl);
cc.ExecutingWebRequest += (object sender, WebRequestEventArgs e) =>
{
    e.WebRequestExecutor.WebRequest.Headers[HttpRequestHeader.Cookie] = "FedAuth=" + _fedAuth + ";rtFa=" + _rtFa;
};

By trial and error I found that naming the cookie FedAuth and not SPOIDCRL – as it’s named in the SharePointOnlineCredential code – was required. Also, without passing the rtFa cookie, I got 403 errors.

Scaffolding a modern web application with ASP.NET Core

This post is a walkthrough of putting together a new application in the latest web technologies. Perfect for starting a new project! It’s incredibly easy with the new ASP.NET Core SPA (single-page application) templates.

The stack in use is as follows:

  • Visual Studio 2017 or Visual Studio Code (optional, but nice for intellisense, debugging etc)
  • TypeScript (extends JavaScript with features like classes and types)
  • React (client library for rendering your UI) and Redux (for handling state, allowing debug features like time travel)
  • Webpack (for bundling/minifying your scripts, and hot module replacement)
  • ASP.NET Core – letting us write our server in lovely C#! (Notably, server pre-rendering is available due to the AspNetCore.SpaServices assembly which calls into Node to execute scripts on the server)

Firstly you need to install the .NET Core SDK. The current version is 1.1. You can either install Visual Studio (if you are licensed for that) or just the command line tools. You can later install Visual Studio Code, the free cross-platform Visual Studio, if you like.

Next you need to install Node. If you’ve already got it, update it to the latest version. I found that I had an old version and I was getting bizarre errors until I realised I had to uninstall and reinstall. Node seems like an odd requirement since it’s a web server in itself, and aren’t we using IIS? The reason it’s needed is because we can take advantage of its extensive library of packages, and additionally, ASP.NET Core can use Node silently in the background to execute JavaScript, on the server, for pre-rendering the page. This can be done when you’re using React or Angular 2.

Now comes the fun part. We will use the ASP.NET SPA Services (Single-page application) generator to produce a ready-to-go, pre-configured application based on the client library we want. So, install both SPA Services and the Yeoman generator:

npm install -g yo generator-aspnetcore-spa

Now create a folder for your application, cd into it, and run the generator:

cd c:\appdirectory
yo aspnetcore-spa

You’ll be given a choice about which framework to use in your project:

In my case I picked React with Redux. It then asks if you want the ‘project.json’ or ‘csproj’ project format. csproj is the one to go with if you’re using Visual Studio 2017. Type a project name and you’re done.

Once the process completes you’ll have a project setup and ready to go:

Before running, you will want to switch to development mode. This allows dev features like hot module reloading to work:

set ASPNETCORE_ENVIRONMENT=Development

To run the project, you have two options. Either open the csproj in Visual Studio 2017 and hit F5 to start debugging, or back in your console, run:

dotnet run

Either way the server will start on port 5000, so have a browse of it. There’s a little basic application for you to muck about with:

Click ‘Counter’ and there’s a button that increments a variable:

Now open ClientApp/components/Counter.tsx. This is the TypeScript React component for the counter.  We’ll test out the hot module reloading by editing that component to add another element to the page:

Webpack at this point detects the file change, the client downloads it, and Redux is able to maintain the state and update the page:

Another major win when using a state manager like Redux is Time Travel. Time Travel is when the state of your app is recorded throughout the lifetime of the app, and you can use a timeline to move the state of the app backwards and forwards in time.

To get Time Travel working, you can use the Redux Dev Tools. The dev tools come in two formats: a JavaScript library that you can add to your app, or a Chrome browser extension. Check out this blog post for an explanation of it. Either way, the dev tools look like this:

To try it out, click the ‘Increment’ button a few times. The tools are already recording the state changes and you’ll see the ‘INCREMENT_COUNT’ action appearing along within a timestamp.

Make sure the slider is show by clicking the slider button:

And then just move the slider around to travel through time. You can also click on an individual action in the list on the left to jump to the state at that time.

Automatic chicken coop door opener

Don’t want to get up at sunrise to let your chickens out, and don’t want to pay £80 for one of those battery-powered coop door opening timer contraptions? Well, here’s how to make one for about £10 depending on what you have lying about the house.

Shopping list:

  • 1x Door lock actuator motor (~£3), from Amazon or any car parts place.
    Actually, buy two because if you’re anything like me you’ll accidentally burn one out.
  • A 12v power supply. I used an old phone charger. Check your drawer of electrical tat or buy one like this for £5.
  • A timer plug, I have a digital one with a 1 minute minimum interval. I got one for £2.
  • A pair of crocodile clips - £1.50
  • A plastic tupperware box/empty chinese food box/any container that you can make waterproof by sealing shut
  • Duck tape
  • Enough cable to stretch from your power supply (which must absolutely remain indoors!!) to the coop door. I used 0.75mm cable, it cost about 45p per metre. You might get away with cheaper stuff, I’m not sure.
So you could wire this up in a very basic fashion – with the timer plug coming on at dawn, powering the actuator, which will open the door. However, without actually breaking the circuit as the door opens, the actuator will burn out (as it’s going to be powered for the minimum interval on your timer). Hence, the crocodile clips attach to the catch on the door and the little metal ‘pole’ (which is metal), and the circuit breaks when the door opens.
When you switch the positive and negative terminals, you can choose whether the actuator goes ‘in’ or ‘out’ when it’s powered. You want it to go ‘in’.
See diagram:

Chicken coop opener….drawn in Paint!

The metal catch and pole both come included with the actuator pack.

Now, here’s the real thing! You can see I’ve encased the actuator and most of the wiring inside a little plastic box, with a hole cut for the metal pole to stick out of it. I know this looks a bit of a mess, I’ve kind of gone a bit mad with the duck tape:

I’m sure your cables will be tidier.

Here’s an up-close of the catch mechanism:

The long flat brass thing and the metal ‘pole’ are included with the actuator. At the top you can see that the pole sticks into a little metal staple nail. Click here to see exactly what this is if you can’t see it. Of course, if you have any other ‘hook’ type of thing you could use then go for it. I just used what I had.

The final piece of the puzzle for me was making sure the door actually flung open when it was unlocked. To make sure it did that, I put a screw behind the door – between it and the door frame – so that you have to apply a little bit of pressure to actually get the door to close. It works like a charm.

There are a few downsides to this arrangement:

  • The timer plug can only be set to a fixed time of day. So you’ve to change it every now and again to keep up with the sunrise. Maybe a light sensor plug would do the job.
  • It only opens! There isn’t really any scope to add a ‘closing’ mechanism. It has to be manually closed each night.