Configuring the Xamarin.Auth component to authenticate using Facebook and Google+

Overview

I recently had the need to implement delegated authentication for a new cross platform mobile app I'm helping to build. The app is being built using Xamarin. It’s the best tool out there for building cross platform native mobile apps. If you’re a mobile developer and you haven’t looked into Xamarin, I recommend it. If you'd like to learn more about it, here are a few references:
The app is under development and confidential, so I won't be able to use it for reference here. However, I have a few different playground apps I use to test out and document my professional development, as well as any technical challenges I encounter throughout my day to day development. For this post I'll be using my Movie Explorer app, which I originally built to demonstrate Xamarin cross platform development best practices and reference architecture. It's like a specialized, more robust version of the Tasky reference app provided by Xamarin.

Before I get into the details of the subject of this post, there’s a little background I should provide. If you’re familiar with OAuth and the typical challenges of identity and access management in mobile apps, or you don’t care and just want to get to the point, skip down to the section titled: Getting to it… finally.

Identity Confusion

First, when it comes to identity and access management, there are a few things you should know which are outside the scope of this post. The following terms are often misused, but it’s important to understand what each is, and the differences between them.

A few important and relevant excerpts:

“Other shared authentication schemes not to be confused with SSO include OAuthOpenIDOpenID Connect and Facebook Connect, which require the user to enter their login credentials each time they access a different site or application.” 
“OAuth is a service that is complementary to and distinct from OpenID.”
Our app will be implementing delegated authentication using OAuth. And even though we're using OAuth, we're not necessarily using OpenID, because Facebook Login doesn’t use it. See this StackOverflow question to get an idea of the confusion between OAuth and OpenID.

Setup

So with that background, I moved on to beginning my research to find the right tool for the job. We are required to provide delegated authentication through Facebook and Google+, as well as our own custom provider. I'm a very pragmatic developer, and as such, I like to start simple. I use real TDD when possible. I refactor when the code and requirements tell me it’s time. I develop for requirements I know now, not for requirements that might come later, but I plan for how to handle possibilities which later might become requirements.

So, when tasked with this, my first thought was to use each provider's native SDK. Xamarin's component store had both Facebook and Google SDKs, so I added them both to the iOS and Android projects and got to work.

iOS:
Android:
This work was easy, and in about an hour I had both apps connected to both authentication providers. Done, right? Well, technically yes, but not really. In doing this work, I had to treat each provider differently. I also learned that I would have to build something custom to abstract the details of the provider implementation, like configuration, saving each provider's credentials securely on each platform and retrieving and using that token with subsequent web API requests — all through a common API.

I looked into identity and access management providers like Azure Access Control ServiceAmazon Cognito and Auth0. These would provide a consistent API for authenticating, and would allow us to add providers later without having to add code and deploy an app update. That’s a good, forward-thinking design, but we don't currently have a requirement for this. So I noted it and moved on.

I quickly narrowed my research to Xamarin Components. I discovered the Xamarin.Auth component, which seemed to fit the bill. If we use this component, we can avoid the duplication of referencing multiple SDKs, and the duplicate code resulting from having to manage the OAuth token obtained from each of them. And if in the future we needed to move to Azure ACS or one of the other identity and access management providers, this component would minimize the impact of that change.

But in trying to get this component working, I found the documentation for configuring each provider to be lacking, and because of the nature of Xamarin cross platform development, each provider’s documentation for configuring for OAuth wasn’t exactly clear. So the purpose of this post is to provide some documentation which I found to be lacking.

Getting to it... finally

Now that you’ve waded through the overview, background and setup, I’m finally getting to the point. In order to use the Xamarin.Auth component for delegated authentication to any provider, you first need to configure each provider. But configuration is confusing. I found this especially true for Google+. Maybe that’s because the documentation for the Xamarin.Auth component provided an example for Facebook, which while it does conform to the OAuth 2 standard, does not support OpenID.

Facebook

First, sign into Facebook, then go to Manage Apps -> Add a New App.



Choose iOS or Android (it doesn't matter which and you'll only need one). Give it a name and create it. There may be some interstitial configuration screens, but what you enter there is not relevant to this post. Just fill them out as you see fit and get to the point of creating a new app ID.



You can ignore most of the instructions for getting started on the native platform and just include your bundle ID. I should note that if for some reason you're using different bundle IDs for iOS and Android, you'll have to create separate Facebook App IDs. Once you've added your bundle identifier, you're almost done.



Some additional configuration you should set: Embedded Browser OAuth Login needs to be turned on. You should also specify that this is for a native or desktop app.





Google+

I found this blog post pretty useful in helping me figure out the proper configuration of the Project in the Google Developers Console. First, sign into the Google Developers console, then Manage Projects -> Create project.



Create a new project. Give it a name and optionally customize the Project Id.



Once that's complete you'll be redirected to the dashboard. From the dashboard, choose "Enable and Manage APIs".


This will give you a list of APIs currently enabled for the project. When you create a new project, several APIs are already enabled.


For simplicity, I remove the APIs I'm not using. We only need the Google+ API, which currently isn't enabled by default. So after disabling all the APIs I'm not using, I add the Google+ API.

This is where it gets a little confusing. When you go to create a new credential, the configuration wizard starts by asking you where you'll be calling the API from. Even though this is being used in a native app, something about how Xamarin.Auth is designed requires this configuration to be for a web app. Select that option. You will be presented with a form to configure additional information. The configuration here is the callback URL. Set it to https://www.googleapis.com/plus/v1/people/me



You may get a confirmation screen that includes a clientSecret or other information. This is not needed by the Xamarin.Auth component.

Usage in Xamarin iOS and Android

Once you have those created and configured, using it is simple and the component documentation is clear. There are some considerations with app configuration, especially with Application Transport Security in iOS. Documentation there is pretty good, so I'll leave that out of scope for this post.

Facebook

Follow the documentation of the Xamarin.Auth component exactly. All you need to do is set the clientId parameter:

partial void btnFacebookSignIn_Click (NSObject sender) {
    var auth = new OAuth2Authenticator (
        "App ID from https://developers.facebook.com/apps",
        "",
        new Uri ("https://m.facebook.com/dialog/oauth/"),
        new Uri ("http://www.facebook.com/connect/login_success.html"));

    auth.Completed += (s, e) => {
        // We presented the UI, so it's up to us to dimiss it on iOS.
        this.DismissViewController (true, null);

        if (e.IsAuthenticated) {
            AccountStore.Create ().Save (e.Account, "Facebook");
            // Use eventArgs.Account to do wonderful things
        } else {
            // The user cancelled
        }
    };

    this.PresentViewController (auth.GetUI (), true, null);
}


Google +

Google configuration is similar, but you should include scope of "opened":

partial void btnGoogleSignIn_Click (NSObject sender) {
    var auth = new OAuth2Authenticator (
        "ClientID from google developer console",
        "openid",
        new Uri ("https://accounts.google.com/o/oauth2/auth"),
        new Uri ("https://www.googleapis.com/plus/v1/people/me
"));

    auth.Completed += (s, e) => {
        // We presented the UI, so it's up to us to dimiss it on iOS.
        this.DismissViewController (true, null);

        if (e.IsAuthenticated) {
            AccountStore.Create ().Save (e.Account, "MovieExplorer");
            // Use eventArgs.Account to do wonderful things
        } else {
            // The user cancelled
        }
    };

    this.PresentViewController (auth.GetUI (), true, null);
}

One final caveat

This is meant to supplement the quick start documentation provided by Xamarin.Auth in the Component Store. When dealing with Identity, you must consider security. This quick start does not cover this very important topic.

Comments

Popular posts from this blog

StackExchange Friday: Brazil reference in The Last Jedi

Tweedism: what's really wrong with US democracy

StackExchange Friday: Proper use cases for Android UserManager.isUserAGoat()?