Flutter + Azure : Authentication with AD B2C

Jayesh
Flutter Community
Published in
6 min readJan 9, 2020

In this article, I will be sharing my experience building a Flutter app with Azure. Starting from what Azure AD B2C is, I’ll show how to connect our tenant with an Android app and exchange tokens.

Photo by Todd Diemer on Unsplash

Last fall, I had an idea for a productivity app that I wished to bring to life. I had worked out the details of what the app should feature, how the back-end should be designed and played around with mock-ups.

It struck me that there could be no better platform to demonstrate this idea than the Imagine Cup by Microsoft which was just around the corner (You should go check it out).
Although the process appeared smooth in the beginning, I soon realized that the Firebase solution I had in mind would not work for Imagine Cup, which requires Azure to be used in any project built.

I required authentication and a database to hold user profiles and information such as appointments tied to the users. I’ll cover the authentication part in this article and the data part in a future article(my approach involves building custom plugins).

Azure AD B2C

I remember being very confused about what any of these terms meant. Having only used Firebase before, all of the documentation on Azure Active Directory seemed very alien to me. For a long time, I wasn’t clear on what solution would work for my case; implementing one even further down the road.

From the docs, “Azure Active Directory B2C provides business-to-customer identity as a service. Your customers use their preferred social, enterprise, or local account identities to get single sign-on access to your applications and APIs”. I personally found this video really intuitive and it helped me understand what AD B2C actually does for the user to make authentication easier.

Before proceeding, you should know what a tenant is and how to create one in your Azure portal. You should also be familiar with User flows(policies) and should set up a basic sign-in/sign-up policy.

App Auth

The Microsoft identity platform uses open standards such as OAuth2.0 and OpenID Connect **. These standards allow you to leverage any library you wish to integrate with Azure Active Directory B2C (here we’ll use App Auth)

AppAuth is a client SDK for native apps to authenticate and authorize end-users using OAuth 2.0 and OpenID Connect. It doesn’t have an SDK for Flutter, however. As such, we’ll use a wrapper built by Michael Bui here.

** If you’re not familiar with these protocols, I suggest you first read about them so that you know what a discovery URL is and how and why the exchange of tokens takes place. However, if you just need to get the job done, you can go ahead with the instructions and still have a working model.

A call to get the id token

As you can see, to authorize and exchange tokens with your tenant, you need to provide a client id, a redirect URL, a discovery URL and the scopes you wish to include.

The client id helps Azure know that the application requesting authentication is indeed yours. To allow that, you have to first register your app in the tenant. This link has the steps required for the same.
You’ll notice that a “redirect URL” is required to complete the registration. This URL specifies the address to which the tokens and related information should be sent back from the authentication window.

Since we’re building a native application, we will want the user redirected to the app after authentication. For this we can register a custom URL scheme that’ll launch our app. This is done in build.gradle(app) under the Android folder.

defaultConfig {                                  		                                                     manifestPlaceholders = [                                                'appAuthRedirectScheme': 'com.imaginecup.prodplatform'                                        ]                                
}

Then, the redirect URL becomes com.imaginecup.prodplatform://oauthredirect where “oauthredirect” is the callback required by app auth.

Once an application is registered, the “Overview” page will give you the client id.

For the discovery URL, you need to go your policy’s page and click on “Run user flow”. This will reveal an endpoint which serves as the discovery URL.
It’ll be of the form :

"https://<Tenant_name>.b2clogin.com/<Tenant_ID>/v2.0/.well-known/openid-configuration?p=<Policy_Name>"

Caution
The discovery URL for Azure AD is different from the ones we’re using and look like this.
https://login.microsoftonline.com/{tenant}/v2.0/.well-known/openid-configuration
I’ll admit that I made this mistake during an early development phase and learnt the hard way.

Once the call to authorizeAndExchangeToken is made, a browser window pops up and the authorization is performed. You can then use the token to call various services and APIs on behalf of the user.

Alternative

The above method works well but if you’re looking for a deeper approach that allows you to clearly see the OAuth authorization code workflow in action, you can choose to make the network calls yourself.

This is accomplished by first making a GET request to the /authorize endpoint with the following specification

GET https://{tenant}.b2clogin.com/{tenant}.onmicrosoft.com/{policy}/oauth2/v2.0/authorize? client_id=90c0fe63-bcf...……….. &response_type=code 
&redirect_uri=………………
&scope=offline_access%20openid

The code for the same, in Dart, would be :

You can learn more about the parameters here.

Once you have the authorization code, you can send a POST request with the following specification, to obtain the access token in the response.

POST {tenant}.onmicrosoft.com/{policy}/oauth2/v2.0/token HTTP/1.1
Host: {tenant}.b2clogin.com
Content-Type: application/x-www-form-urlencoded
grant_type=authorization_code
&client_id=90c0fe63-b...………..
&scope=offline_access
&code=AwABAAAAvPM1KaPlrEqdFSBzjqfTGBCmLdgfSTLEMPGYuNHSUYBrq...
&redirect_uri=urn:ietf:wg:oauth:2.0:oob

What Next?

Once the access token is obtained, you can use it to make calls to Microsoft Graph to retrieve user information and with the right permissions, you can modify user fields and other attributes(you can define these attributes yourselves too, in the user policy you’ve created).

A subtle benefit of this option that I realized is: you can supplement it with the Azure App Center Data service(Cosmos DB) which allows only a single collection to be stored. Thus, you can use that collection allowance for storing any other important resource of your app and let Microsoft Graph handle the user database.

A sample request to retrieve information about the currently logged in user could look like this:

Conclusion

Building this project from the start to its current form drove me to dig deeper into authentication and the protocols that govern it. I got to explore Azure AD B2C and various other Azure features. There were multiple roadblocks that I ran into and the immense amount of documentation seemed overwhelming at first and even now, I sometimes get puzzled when searching for the things I need.

I feel I’ve done my best to list out all the resources that helped through the development of this app in the form of links and also, all the mistakes that I made.
I will be looking forward to writing the next part of this series that deals with database management through custom Flutter plugins ✌️

Thank you for reading! Please feel free to comment if there are any doubts ❤️

--

--

Jayesh
Flutter Community

MLOps @ZenML, IIT Bhubaneswar Graduate | Varied interests | Love interacting with people. I crave knowledge 📒📰