Great News for Mobile Developers from Build 2016

Miguel de Icaza's breakout session at Build

In case you haven’t been following the news around Microsoft’s purchase of Xamarin here is some exciting news. When this merger was first announced we were excited to see Microsoft commit to the Xamarin toolset as well as being hopeful that the business editions would become part of the MSDN collection of software (and thus save us about $2,000 per developer). What we weren’t expecting was for Microsoft to make Xamarin a standard part of Visual Studio, available to all Visual Studio developers. Not just MSDN or retail licensed developers, but all developers, including Visual Studio Community Edition.

Miguel de Icaza presenting at the Build Day 2 KeynoteThis is a big deal for us and other companies wanting to do cross-platform mobile development with C# and .NET. Not only have our expenses been drastically reduced to continue to use the toolsets we love, but now the conversation about working with internal resources at a client to maintain, augment, or otherwise work with this product just got a lot easier. We no longer need to sell them on buying on of their developers a $2000/yr subscription to be able to work with the source we deliver them.

Hopefully this will entice other developers to take their apps to .NET and hopefully that will get their apps on Windows Phone and give it some traction in the market.

In addition to all this already great news, they have also announced that the Xamarin codebase will be open sourced and made available through GitHub. I think we can expect some great community driven improvements coming to Xamarin.Forms as those of us who have been working with it get our hands on the source.

This is a great time to be a .NET developer, and an even better time to be a .NET cross-platform mobile developer.

You can read more details about the announcements on Xamarin’s blog.

Xamarin Forms and the Active Directory Authentication Library (ADAL)

We just finished working on a proof of concept for a project that needed to do Active Directory authentication, primarily using Azure AD. We wanted to do this in Xamarin Forms as the app falls into the realm of a typical line of business UI app and will have a pretty straightforward design.

We started off with some great sample code from the ADAL project team. They have a beta release that supports traditional Xamarin projects (native UI) for Android and iOS as well as Windows Phone. It looked really simple and had great conveniences like async/await support. We thought it would be a walk in the park, not so.

It turns out that the beta version with Xamarin support does not support targeting Silverlight based Windows Phone assemblies. This is important, because Xamarin Forms support for Windows Phone uses the Silverlight implementations. This precluded us from including the authentication login inside the common PCL project. After a little digging it turns out that the ADAL just recently (Jan 15) released a new stable version that introduced support for Silverlight based Windows Phone apps. This was exciting, but there was no complete sample solution and the blog post announcing was missing a couple helpful nuggets of information in the code snippets.

We ended up getting it working, but not as elegantly as we had hoped. By the time I was done I understood a bit more why the original library didn’t handle Silverlight projects, it is a bit more bulky to work with for this situation.

This code is part of a client’s project so there is no sample available right now, we’ll work on getting a stripped down set of code for reference, until then here are some notes on the relevant code changes we made.

Changes for the Windows Phone Project

interface IWebAuthenticationContinuable
{
    /// <summary>
    /// This method is invoked when the web authentication broker returns
    /// with the authentication result
    /// </summary>
    /// <param name="args">Activated event args object that contains returned authentication token</param>
    void ContinueWebAuthentication(WebAuthenticationBrokerContinuationEventArgs args);
}
//Changes to make to your Windows Phone App (not Xamarin Forms App)
public partial class App : Application
{
    public App()
    {        
        PhoneApplicationService.Current.ContractActivated += Application_ContractActivated;
    }
    
    private void Application_ContractActivated(object sender, Windows.ApplicationModel.Activation.IActivatedEventArgs e)
    {
        var webAuthenticationBrokerContinuationEventArgs = e as WebAuthenticationBrokerContinuationEventArgs;
        if (webAuthenticationBrokerContinuationEventArgs != null)
        {
            var wabPage = RootFrame.Content as IWebAuthenticationContinuable;
            if (wabPage != null)
            {
                wabPage.ContinueWebAuthentication(webAuthenticationBrokerContinuationEventArgs);
            }
        }
    }
}
//The Root Page of your WP Project
public partial class MainPage : FormsApplicationPage, IWebAuthenticationContinuable
{
    public static AuthenticationContext AuthContext { get; private set; }
    public static Action<string> TheCallback { get; set; }

    public static async void CreateAuthContext(string authUrl)
    {
        AuthContext = await AuthenticationContext.CreateAsync(authUrl, true, new TokenCache());
    }
    
    public async void ContinueWebAuthentication(WebAuthenticationBrokerContinuationEventArgs args)
    {
        await AuthContext.ContinueAcquireTokenAsync(args);
    }
}
//Service defined and called from ViewModel, passes in the method to callback.
public class WindowsPhoneAuthorizationService : IAuthorizationService
{
    public void GetAuthorizationToken(string oAuthUrl, string site, Action<string> callbackAction)
    {
        string clientId = "YOUR CLIENT ID"; 
        Uri returnUri = new Uri("YOUR RETURN URI"); 

        MainPage.TheCallback = callbackAction;
        try
        {
            MainPage.CreateAuthContext(oAuthUrl);

            var authContext = MainPage.AuthContext; 
            if (authContext.TokenCache.ReadItems().Count() > 0)
                authContext = AuthenticationContext.CreateAsync(authContext.TokenCache.ReadItems().First().Authority).GetResults();

            authContext.AcquireTokenAndContinue(site, clientId, returnUri, MainPage.callback);
        }
        catch (Exception ee)
        {
            callbackAction(string.Empty);
        }
    }
}

Usage from the ViewModel

//Ueed in my ConnectCommand
private async void ConnectExecute(object param)
{

    var authService = DependencyService.Get<IAuthorizationService>();

    authService.GetAuthorizationToken(oAuthUrl, SiteUrl, setToken); 

}

//callback from authentication
private void setToken(string token)
{
    if (!string.IsNullOrWhiteSpace(token))
    {
        Device.BeginInvokeOnMainThread(() =>
        {
            //Do something with the token.
        });
    }
}

Maybe Xamarin will make some changes that allows them to target Windows Runtime based projects in the future and this will all be irrelevant, but until then hopefully this bit of code helps you make some progress doing Active Directory Authentication in your Xamarin Forms projects.

Update: It looks like last week there was a refresh to the ADAL v3 Preview, but as stated “This refresh does not work with Xamarin.Forms. We are looking into it – and if you have feedback please send it our way! – but we didn’t do work in this refresh to that end.” Good news that they are investigating integrating support. Until then Xamarin Forms and ADAL will continue to be bleeding edge.