Radi Atanassov

SharePoint MCM, MVP, MCT and owner of OneBit Software

The Mystery of Microsoft.IdentityModel.Extensions

When doing development with SharePoint Server and SharePoint Online, we have to do API calls that are authenticated and authorized. Authentication and authorization over HTTP in regards to SharePoint API's, for the better part of it, nowadays is based on principles and techniques predominantly stepping on the OAuth protocol, which deals with authorization by its definition. We have to do handshaking with token providers and resource owners, and include HTTP headers with our calls. From a development perspective, as long as you have an HTTP request/response interceptor and code that can generate/manipulate/transform HTTP packets and tokens – you pretty much have whatever you need to call an OAuth secured endpoint, such as SharePoint API's.

Every modern web development platform has these capabilities. You can build SharePoint provider-hosted add-ins and console applications on whatever platform you want and use whatever HTTP mangling language you want (See the Python example here for proof https://github.com/SharePoint/PnP/tree/master/Samples/Python.Office365.AppAuthentication). The only thing you really need to do is deal with the authentication and authorization side of things, then just call the API's.

When it comes to the Microsoft promoted development set of tools, we use Visual Studio, ASP.NET and Office Developer Tools to build provider-hosted apps for SharePoint. Our development model steps on ASP.NET, which steps on Windows Identity Foundation and ASP.NET (System.Web and supporting libraries). Visual Studio knows nothing about SharePoint add-ins unless you install Office Developer Tools.

If you've been around for a while, you will recall Windows Identity Foundation and how it got integrated into the .NET Framework (4.5) (see this Namespace Mapping between WIF 3.5 and WIF 4.5 and Guidelines for Migrating an Application Built Using WIF 3.5 to WIF 4.5). "Beginning with .NET 4.5, Windows Identity Foundation (WIF) has been fully integrated into the .NET Framework". *Almost* everything under the namespaces Microsoft.IdentityModel have been moved to System.Security.Claims, System.ServiceModel.Security, and the System.IdentityModel namespace.

One odd fella, Microsoft.IdentityModel.Extensions, has been left aside. This is the namespace in the Microsoft.IdentityModel.Extensions.dll file and is where the code for SharePoint provider-hosted apps mangling of OAuth and S2S tokens is located. During that era SharePoint development had a decline in general, mostly due to the growth of Office 365 and Azure AD, so the libraries got left aside (btw, they are all owned by the almighty and unhuman idol of mine Vittorio Bertocci). Microsoft.IdentityModel.Extensions is not maintained by anyone, yet SharePoint add-ins depend on it. The future of SharePoint server-side development depends on it. Development of SharePoint add-ins on the Microsoft development platform depends on it. SharePoint PnP depends on it, so we need to show that library some deep love.

Enough history, let's look at where we use it and where it comes from.

 

Understanding the dependency chain

I'm going to focus on SharePoint provider-hosted add-ins and applications that use App-only calls, because that's where this stuff gets used for the most of it.

You create a SharePoint Add-in project in Visual Studio and you get a bunch of stuff in the project. Some are .cs/.vb files, others are assembly refences and a few nuget packages.

If you look at the AppForSharePointOnlineWebToolkit nuget package, it contains Framework assembly references. Notice the Microsoft.IdentityModel.Extensions assembly and the fact that it doesn't exist in the nuget package itself. AppForSharePointOnlineWebToolkit brings in SharePointContext and TokenHelper classes to your project (together with the ASP.NET MVC SharePointContextFilter attribute). Before the AppForSharePointOnlineWebToolkit package was available, we used to copy those classes to get a console application to authenticate with SharePoint. Here is a view of the package in NuGet Package Explorer. You might recognize SharePointContext.cs/.vb and TokenHelper.cs/.vb.

So, where does Microsoft.IdentityModel.Extensions.dll come from? This is the mysterious question that we have to answer, so we can reliably build PnP tooling that helps developers.

Let's look at the Microsoft.SharePoint.CSOM NuGet package:

No dependencies. No Microsoft.IdentityModel.Extensions.dll to be found.

This is quite a bad design decision – both Microsoft.SharePointOnline.CSOM and AppForSharePointOnlineWebToolkit require Microsoft.IdentityModel.Extensions.dll to be present, TokenHelper has direct managed code calls to classes in it. Inherently, our OfficeDevPnP.Core library depends on Microsoft.IdentityModel.Extensions.dll, and this is where it affects PnP.

The answer to the question: the actual assembly gets delivered with Office Developer Tools for Visual Studio 2015: https://www.visualstudio.com/vs/office-tools/ through one of its packaged MSI's, which steps on Web Platform Installer. This means that the entire development toolchain depends on the abovementioned dependencies.

The problem doesn't exist only here either. There's quite a few nuget packages that depend on Framework assemblies. That is OK. Our problem is that it is delivered with a Visual Studio extension.

NOTE: At one point of our careers me and a colleague of mine did a silly thing and packaged the DLL as an NuGet package and published it on nuget.org. We delisted it, but can never remove it from the feed (that's how nuget.org rolls): https://www.nuget.org/packages/Microsoft.IdentityModel.Extensions/1.0.0

 

You can actually download the MSI

Funny enough, you can directly download the MSI packages that copy over the DLL to your machine:

If you open the MSI with 7-ZIP (yes, you can do that), or any other MSI explorer, you can see that it only contains that DLL.

This is the only way I know, that you can get the assembly without VS Office Developer Tools… until…

SharePointPnP.IdentityModel

As part of PnP, we want to help developers build stuff. We pay a lot of attention towards what you need to get going and how easy it is to get it. We currently have a new agenda, too – getting PnP to run on .NET Core. This is possible, see my previous blog posts on Developing the ASP.NET Core Authentication/Authorization Middleware for SharePoint Provider-Hosted Apps (Add-ins), and the OfficeDevPnP.Core.Framework.Authentication library. Keep an eye for developments here, because we're investing time into it.

The OfficeDevPnP.Core.Framework.Authentication library achieves one awesome goal – it lets you build an ASP.NET Core web application that authenticate with SharePoint, just like every other SharePoint provider-hosted add-in, but you can make use of the ASP.NET Core stack, which is tons better than System.Web.Mvc etc. You can use CSOM with it to manipulate SharePoint. Awesome, but it doesn't solve one next challenge – to use OfficeDevPnP.Core to help you manipulate SharePoint better.

OfficeDevPnP.Core naturally depends on Microsoft.IdentityModel.Extensions.dll, which depends on System.IdentityModel.dll, and that causes hell when you want to run in .NET Core.

Our solution is simple – port Microsoft.IdentityModel.Extensions.dll to a .NET Core project in Visual Studio. The hard work of this is done here: https://github.com/SharePoint/PnP/tree/dev/Solutions/AspNetCore.Authentication/src/SharePointPnP.IdentityModel

For the time being, you can build a custom OfficeDevPnP.Core assembly with reference to SharePointPnP.IdentityModel instead of Microsoft.IdentityModel.Extensions and happily continue referncing it in .NET Core.

We are working with the PnP team to do this once for good in January (2017). Stay tuned…

Add comment

Loading