This is the first of three posts, where I will explain how to use the ADAL package in a multiplatform native app (iOS / Android / UWP) Xamarin Forms solution.
- The new .NET Standard Libraries, and the two roadblocks I’ve found trying to use ADAL in a Xamarin Forms solution.
- Using a .NET Standard library in a Xamarin Forms solution (To Be Done).
- Using Custom Renderers to call ADAL methods that need platform specific code to be used (To Be Done).
The ignite factor
All started after following the session of Vittorio Bertocci at Ignite: Secure your native and mobile applications with Microsoft identity and application management. The thing that triggered my curiosity was the demo, made with Windows Forms.
Then I asked myself: why in the earth was he using Windows Forms? Why not using a Xamarin and/or a UWP solution? So I’ve launched Visual Studio and tried to do it by myself, and discovered that using ADAL with Xamarin Forms is not so straightforward as it should be.
No one has to be blamed, because we are in a transition time, where library developers and NuGet packages makers are switching from PCL (Portable Class Library) to .NET Standard and the tools (Visual Studio and Xamarin for Visual Studio) are rapidly evolving to help us manage this mixed world of PCL and .NET Standard NuGet packages.
.NET Standard Libraries
While developing the new .NET Core, Microsoft has created a (very welcomed) standardization of the .NET Base Class Library called .NET Standard. You can think of it as the next generation of Portable Class Libraries (PCL).
This new standard is very important for libraries developers, because having a common API allow them to write an almost single code version of the library. I wrote “almost” because is still possible to write specialized code for platform specific implementation details. But for the most part of the library, when using the API defined by a .NET Standard version, the same code will be guaranteed to work on all the platforms that implement that version of the .NET Standard.
But the adoption of the new .NET Standard cannot be instantaneous, and now we are in the transition time where most of the available NuGet packages contains PCL libraries and only few of them have already been converted to .NET Standard. Time after time, most of those libraries will be converted, but some not.
To handle this mixed world scenario, a NuGet package can contain a PCL and a .NET standard version of the same library, but this is a choice up to the library developer, and there are already some important libraries that don’t have all the version needed on all scenarios. This can cause troubles when trying to install the NuGet package on some cases, as we will see on the description of the first roadblock that I’ve encountered.
For more info on the new .NET Standard, please refer to the Microsoft documentation.
First roadblock: Unable to install the ADAL NuGet package
As an example of the mixed world scenario described earlier, the ADAL package (Microsoft.IdentityModel.Clients.ActiveDirectory) contains the single platforms libraries and the .NET Standard 1.4 version, but not the PCL version.
So when we try to add it to the common PCL project of our Xamarin multiplatform app solution:
we get this error:
The cause is well known: A PCL library cannot reference a .NET Standard library.
Helpfully, the latest version of Xamarin for Visual Studio can use .NET Standard libraries, so the solution of this roadblock is to change the common library type from PCL to .NET Standard. On the second post of this series (To Be Done) we will see how to solve it.
Second roadblock: Unable to write specific platform code on the common .NET Standard library
While writing the authentication code using the ADAL library, I quickly discovered that the exposed API is different from platform to platform. Please note that this is not the API offered by the .NET Standard (that is the same for all the platforms that implement it) but the specific API (classes and methods) offered by the ADAL library.
As an example, the method AcquireTokenAsync(string resource, string clientId, Uri redirectUri, IPlatformParameters parameters) require a parameter of type IPlatformParameters that has different implementations depending on platform.
On iOS we have:
// Additional parameters used in acquiring user’s authorization
// UIViewController instance
public PlatformParameters(UIViewController callerViewController);
// activity calling ADAL to acquire token
public PlatformParameters(Activity callerActivity);
// Prompt behavior enum to control UI
// flag to enable logged in user authentication
public PlatformParameters(PromptBehavior promptBehavior, bool useCorporateNetwork);
Here the solution is to use Xamarin custom renderers to inject the platform specific implementation of the IPlatformParameters parameters, as we will see in the third post of this series (To Be Done).