I put out quite a bit of content around Azure AD B2C lately and how to integrate that with your Xamarin mobile apps using the MSAL library.

I talked about how to setup the tenant in the portal... how to use MSAL to facilitate the workflow of authentication... setting up an Azure Function app to take part in all the fun.

But there's one thing I didn't talk about ... and I've been getting asked about it quite a bit ... and that's ...

How to use Azure AD B2C with Azure Mobile App Service?!?

We're all mobile developers here, makes total sense we'd want to do that. So that's what I'm going to do in this post. Show you how to use the ZUMO (that's what all the cool kids call Azure Mobile App Services) library to get a resource token from Azure AD B2C.

(Wanna jump right to the code? Find it all on GitHub here.)

Check it out - there's some great Xamarin documentation for this too!

Let's go!

Setting Up the Azure AD B2C Tenant

There are some minor modifications that you'll need to do in your tenant in order to get this all to work.

I'm assuming you already have a Zumo app service created in the portal. And I'm also assuming you have a AADB2C tenant created too. If not, follow the Zumo steps here and the AADB2C steps here.

Next up - head into the Zumo app service in the portal and grab the URL.

Zumo portal with overview address

Once you have that, over to the tenant you go!

Open up the Application you want to assign the Zumo service to.

Then make sure Include Web App / Web API is set to True and Allow Implicit Flow is also True.

Finally, the Reply URL field should be your Zumo app service URL from above PLUS the following appended to it:

/.auth/login/aad/callback

Here's some info on how I came up with that URL

Everything ends up looking like the following:

Configured callback URL in AADB2C tenant's application

That's all there is to the AADB2C side of things (but don't close it, you're going to need some setting values).

On to the Zumo App Service!

Setting Up the Zumo App Service

Now you have to configure the Zumo App Service so it knows where to find your AADB2C.

Jump on into your Zumo App Service in the portal and then open up the Authentication / Authorization blade on the left hand side.

From there, make sure App Service Authentication is set to On and depending on how you want things to run, you can either change Action to take when request is not authenticated. I'm leaving it as Allow Anonymous requests - this way I can still serve both requests that require auth and ones that don't.

Finally, in the Advanced Settings section - add a value under ALLOWED EXTERNAL REDIRECT URLS. This value needs to be of the format {whatever}://easyauth.callback.

Mine is: zumob2c://easyauth.callback

Initial Zumo Authentication portal setup

On the mobile end of things during sign-in, our app is going to relinquish control to the OS, after the sign-in is done, the OS is going to call that URL (because we just set it up here). Our app will be registered with the OS to respond to that URL. Thus it'll open. Cool? Cool.

Configuring Zumo's Azure Active Directory

Next click on Azure Active Directory. In the new blade, make sure Management Mode is set to Advanced.

Then for Client ID, enter the value of the Application ID from your AADB2C application.

Here's what the application id in the tenant looks like:

Application ID in the tenant

You obtain the Issuer Url also from the AAB2C. This time it's in the Sign-up or Sign-in policies section. Click on the policy you want to use and then copy the URL it shows. Pop that thing into the Issuer Url in the Zumo side of things.

Issuer Url from the sign-up/sign-in policy

The final configuration for Azure Active Directory in the Zumo portal looks like this:

Final configuration for AAD in Zumo portal

That's it for the portal. Done and done. Time to setup the Zumo controllers to make sure they require authentication.

Zumo Custom API Controller Setup

Head on over to your server application. To whatever controller you want to make sure needs authentication to access it - add an attribute: [Authorize].

A simple example controller would look like:

[MobileAppController]
public class SecuredController : ApiController
{
    // GET api/Secured
    [Authorize]
    public string Get()
    {
        return "💰💍";
    }
}

(Obviously our secure controller is returning a money bag and diamond ring!)

That's it - the [Authorize] attribute takes care of it for you.

Xamarin.Forms Setup

Alrighty - we're getting to the good stuff now!

I'm assuming you're using the Microsoft.Azure.Mobile.Client NuGet package.

The login functionality is all going to run through this library, specifically the MobileServiceClient class.

As I mentioned above - the sign-in (or sign-up if the user is going to be brand new) is going to be a platform-specific function. So what I'm going to do to facilitate using the same MobileServiceClient class in both the shared project and each platform specific project is create a ZumoService class. That class will handle all my communication to the Azure Mobile App Services.

I will have a public field in that ZumoService class - and that will be of a type ... wait for it ... MobileServiceClient. This way I'll be able to access it from the platform as well as the shared project.

public static readonly MobileServiceClient CurrentClient = new MobileServiceClient(Constants.ApplicationUrl);

I also have a Login function in the ZumoService class. This is so I can invoke the login process from the shared project. So in order to make sure I can invoke the platform-specific version of the login - I have another property in the App class. Each platform project registers the class that does its login with that property. (Check out the GitHub project - it'll make sense.)

Logging In!

The login process then is the same as it is in when using MSAL - as far as configuration.

iOS

On this iOS side, you need to make some changes to the Info.plist. It's the same changes as you'll for MSAL here. The one change is that value of CFBundleURLSchemes is going to be: zumob2c://easyauth.callback.

The whole thing will look like:

<key>CFBundleURLTypes</key>  
<array>  
    <dict>
        <key>CFBundleTypeRole</key>
        <string>Editor</string>
        <key>CFBundleURLName</key>
        <string>YOUR BUNDLE NAME IS HERE</string>
        <key>CFBundleURLSchemes</key>
        <array>
            <string>zumob2c://easyauth.callback</string>
        </array>
    </dict>
</array> 

Then to login, all you need to do invoke this:

await ZumoService.CurrentClient.LoginAsync(UIApplication.SharedApplication.KeyWindow.RootViewController,
                      MobileServiceAuthenticationProvider.WindowsAzureActiveDirectory,
                      "zumob2c");

Done! The OS will take over and then perform the sign-in or sign-up. When it returns your app will reopen.

On iOS you'll have to implement this in the AppDelegate to make sure it opens successfully:

public override bool OpenUrl(UIApplication app, NSUrl url, NSDictionary options)
{
    return ZumoService.CurrentClient.ResumeWithURL(url);
}

The appropriate header will automatically be set in the MobileServiceClient so when you call the MobileServiceClient.InvokeApiAsync function - you don't have to do anything different.

Android

For Android, the configuration happens in the AndroidManifest.xml. You can read about the ins & outs of setting it up here.

The final product of the code you add however, will look like this:

<activity android:name="com.microsoft.windowsazure.mobileservices.authentication.RedirectUrlActivity" android:launchMode="singleTop" android:noHistory="true">
  <intent-filter>
    <action android:name="android.intent.action.VIEW" />
    <category android:name="android.intent.category.DEFAULT" />
    <category android:name="android.intent.category.BROWSABLE" />
    <data android:scheme="zumob2c" android:host="easyauth.callback" />
  </intent-filter>
</activity>

You call the same LoginAsync as you do over in iOS land.

Done!

You're now working with Azure AD B2C and Azure Mobile App Services ... and you're loving it! ❤️ ❤️ ❤️

The trick is the setup in the portal. You have to enter the proper callback URL within the tenant's application for the Zumo service. Then you also have to make sure you configure the Active Directory portion of the Zumo service properly so it connects back to AADB2C.

Then it's tying the pieces together in your app ... and don't forget that [Authorize] attribute!

Don't forget to check out the Xamarin-Microsoft documentation on this subject too!

You can find a full, working solution on GitHub here. And as always, reach out to me at @codemillmatt if you have any questions on this.