Missing Context Token in Low Trust App with SharePoint 2013

Should you decide that you want to write low trust apps for an on-premises SharePoint 2013 farm, there are a number of hoops you should expect to jump through (NOTE: this assumes the SPNs for your web apps are already configured in the MsolServicePrincipal for your o365 tenant):

  1. Create a new app in Visual Studio; in the wizard you select provider hosted app on the first page, and then client secret on the second page.
  2. Add a New Web Site to your solution, configure it to use SSL, and add all the necessary references to it (usually Microsoft.IdentityModel, Microsoft.IdentityModel.Extensions, Microsoft.SharePoint.Client, and Microsoft.SharePoint.Client.Runtime).
  3. Copy the TokenHelper.cs file from the app web created by the Visual Studio wizard and paste it into your new web site - create an ASP.NET Folder in your project for App_Code and copy it in there, then remove the "namespace" from the file.
  4. Copy all the goo from the web.config in the app web that the Visual Studio wizard created, and paste it into the web.config for your new web site.
  5. Add a new web form to your new web site called Default.aspx.
  6. Copy the code from the default.aspx.cs file in the app web that the Visual Studio wizard created, and paste it into the default.aspx.cs file in your new web site.

Now...that seems like a lot of good stuff, and it is, but when you try and run the application you'll probably get an error that looks like this:

Along with that, you'll see the error message about the parameter 'token' cannot be a null or empty string (yeah, I just added that in for the search engines...you're welcome :-) ). If you try debugging it you'll see that when the call is made in the code-behind to GetContextTokenFromRequest, the return value is null. So this is basically saying you're not getting the context token you need from SharePoint. What this means is that in all likelihood you don't have a synced up ClientId value between your new web app's web.config, the AppManifest.xml file for the SharePoint App, and the SharePoint site. 

After trying a few different ways around this, I honestly found the best way to resolve this problem is to do the following - go into your site into the /_layouts/15/appregnew.aspx page. Use that to generate a new ClientId and ClientSecret. Complete that page to register those values for the App Principal in the site. Now, paste the ClientId into the AppManifest.xml file (in the RemoteWebApplication element), and paste the ClientId AND the ClientSecret into the web.config for your new web application.

You will need to redeploy your SharePoint App at this point, which you can still do by pressing F5 in Visual Studio. After that it *should* work, however you may get an Access Denied error message too (I had this happen once). Just to make sure everything was squared away, I went into the Site Contents page, clicked the ellipsis next to my application, and then clicked on the Permissions link. That page contains a link that says "If there's something wrong with the app's permissions, click here to trust it again", and click it I did. In all honesty, things get wrapped up enough that it may very well have worked if I had just tried it again, but it seemed like an interesting link. :-)

Hopefully this gives you heads up and maybe a little background as you look to use low trust apps in provider hosted apps on premises.