Using Azure AD B2C to Authenticate Android App Users

Michael Collins
Neudesic Innovation
7 min readFeb 16, 2022
This image shows the log in form that is rendered by Azure Active Directory B2C in an Android web view.

Previously in this series, I have shown how to authenticate web users and iPhone or iPad users. In this post, I will turn my attention to the Android platform and how to use Azure AD B2C to authenticate the users of an Android app using the Microsoft Authentication Library for Android.

This is the tenth post in a series on Azure Active Directory B2C and how to use Azure Active Directory B2C to create an identity management system for a Software-as-a-Service application. If you are new to this series, I recommend reading the earlier posts in the series:

  1. Building Application Identity Solutions using Azure AD B2C
  2. Configure Azure AD B2C For Customization
  3. Understanding the B2C Directory
  4. Sign Up or Sign In Users With Azure AD B2C: Part 1
  5. Sign Up New Users Using Azure AD B2C
  6. Log In With Local Accounts on Azure AD B2C
  7. Combining Sign Up and Sign In Into a Single Policy Using Azure AD B2C
  8. Using Azure AD B2C to Authenticate Web App Users
  9. Using Azure AD B2C to Authenticate iOS App Users

Create an Android Application

📝 NOTE: I am using IntelliJ IDEA to do my Android development, but the instructions should also apply to Android Studio.

In the IDE, I created a new Android application. I selected the Empty Activity template to create a skeleton app with a starter activity that I can customize:

Select a Project Template view with the Empty Activity template selected

I chose Kotlin for the implementation language and based on demo on the Android SDK version 29:

Configuration settings for the new project

Add the Microsoft Authentication Library for Android

After creating the starter application, I added the dependency on the MSAL library for Android. To do that, I needed to add the MSAL library to the list of dependencies for Gradle, and register the Maven store where Gradle will look for the MSAL library.

New applications created by the IDE have two build.gradle files that need to be modified. The build.gradle in the root directory of the project is the main configuration for the build system. The app/build.gradle file contains the list of dependencies that are necessary to build the app module that implements the heart of the Android application.

I started by modifying the root build.gradle file. Inside of the buildscript.repositories property, I added the URL for the Maven repository where the MSAL library can be downloaded from:

I next added the MSAL library to the app/build.gradle configuration:

⚠️ The exclude block is in there because without it, I was receiving errors downloading another framework used by the Microsoft Surface Duo SDK. For more information, see the release notes for the 1.5.0 release.

I synchronized Gradle to download the dependencies and I was ready to move forward to the next step.

Configure the MSAL Library

The next step is to create a JSON configuration file that the MSAL library will use to determine how to operate at runtime. To create the configuration file:

  1. In the Project Explorer, expand the app/src/main/res folder.
  2. Right click on the res folder and choose New —> Android Resource Directory.
  3. In the New Resource Directory modal, change the Resource type value to raw.
  4. Click the OK button to create the directory.
  5. Right click on the new raw directory and choose New —> File.
  6. For the name of the new file, use auth_config_b2c.json.

My auth_config_b2c.json file looks like this:

I replaced the CLIENT-ID value with my application ID from Azure Active Directory B2C. For the HASH value, this can be generated for development by running this command in the terminal:

keytool -exportcert -alias androiddebugkey -keystore ~/.android/debug.keystore | openssl sha1 -binary | openssl base64

When you are prompted to enter the password for the key store, the default value is android. For the HASH value in the configuration file, you may need to replace = characters with the URL encoded equivalent of %3D.

Configure the Application Manifest

The next step is to update the application manifest. I needed to add the INTERNET and ACCESS_NETWORK_STATE permissions to the application. I also had to register the com.microsoft.identity.client.BrowserTabActivity activity that is used by MSAL to present the Azure Active Directory B2C UI.

My ApplicationManifest.xml file looks like this:

The HASH value in the path should not be URL encoded. = characters can appear as = and not %3D.

Configure the App Registration in Azure

The final configuration step is to register the Android application with the App Registration in the Azure Active Directory B2C tenant:

  1. Open a web browser to the Azure Portal and navigate to the App Registration in the Azure Active Directory B2C portal.
  2. Click in the Authentication link in the navigation list on the left.
  3. Click the Add a platform button.
  4. Choose the Android platform.
  5. In the Package name field, enter the application identifier from the app/build.gradle file.
  6. In the Signature hash field, enter the hash that you previously obtained and used in the earlier configuration steps.
  7. Click the Configure button to save the Android application information.

Later while testing the user authentication, I ran into a problem where MSAL would fail authentication unless I referenced an API. By default, Azure Active Directory B2C will not issue an OAuth 2.0 access token if there are no APIs that need to be authorized. I created a dummy application and API:

  1. In the Azure Active Directory B2C portal, navigate to the App Registrations screen.
  2. Click on the New registration link.
  3. Enter a simple name for the app. I used Project Center API.
  4. For the Supported account types field, I chose Accounts in this organizational directory only.
  5. Ensure that Grand admin consent to opened and offlineaccess permissions is checked.
  6. Click the Register button to create the app registraton.
  7. In the app registration screen, click on Expose an API in the left navigation menu.
  8. Click the Add a scope link to create a new scope.
  9. Accept the default value for the application in the next screen.
  10. On the Add a scope form, enter Files.Read in the Scope name field.
  11. Add a simple description and admin consent description.
  12. Ensure that Enabled is selected for the state value.
  13. Click the Add scope button to save the scope.
  14. Navigate back to your app registration (the app, not the API app).
  15. In the left navigation menu, choose the API permissions link.
  16. Click the Add permissions button.
  17. In the Request API Permissions view, change to the My APIs tab.
  18. Select the API application
  19. Check the Files.Read permission.
  20. Click the Add permissions button to save.
  21. On the Configured permissions view, click Grant admin consent for (app name) and approve the permissions.

Update the Main Activity Layout

The configuration is done! It’s time to get to the good stuff. The default application template creates a basic UI for our MainActivity class that displays a hello message in a text field. I will replace the text field with a button that the user can tap to log into the application:

  1. Open app/src/main/res/layout/activity_main.xml in the IDE.
  2. Select the text box in the view and delete it.
  3. Add a Button to the layout and align the button so that it appears in the center of the view.
  4. Change the text in the button to Log In and change the identifier to logInButton.

Implement the Log In Feature

Now for the code. Here is my MainActivity.kt file:

I declare two fields on MainActivity. The msalApplication field stores the reference to the MSAL library’s PublicClientApplication object that I will use to authenticate users. After logging in, the user’s account will be stored in the account field for future use.

In the onCreate function, I am attaching the logInButton to its event handler and then making it disabled by default. I am then trying to create the PublicClientApplication instance using the createSingleAccountPublicClientApplicationMethod. I am passing the function the reference to the configuration JSON resource that I created earlier. The callback listener uses the onCreated function to store the reference to the PublicClientApplication instance and enable the log in button.

When the user taps the log in button, the logIn function will be called. logIn will use the msalApplication.signIn function to authenticate the user using MSAL and Azure Active Directory B2C. The web browser will open up and the user will be presented with the Azure Active Directory B2C web UI to log in. When the user has logged in, the listener’s onSuccess function will be called and I can obtain and store the user’s account.

Testing the Implementation

With the code finally written, I can turn my attention to manual testing. When I run the app in the Android Emulator, I get presented with my MainActivity and I can see the log in button. Initially the log in button is disabled, but it should quickly change to enabled:

Main activity showing the log in button

When I tap the log in button, the web browser opens up and I am taken to the web log in form from Azure Active Directory B2C:

The Azure Active Directory B2C log in form shown in a web view

After entering my username and password that I established earlier in this series, I am sent back to the application. I can see in the debugger that the onSuccess function is called and I can see the account information and the claims inside. Everything worked!

Where Did We Go?

In the last three posts, I have shown you how to add user authentication to a single page web application, an iOS application, and an Android application. I may throw in some future posts showing additional application types such as Flutter or doing server-to-server authentication and authorization. But now that we have log in working and three demo apps, I’m going to switch back and start doing some more cool stuff with Azure Active Directory B2C’s custom policies.

--

--

Michael Collins
Neudesic Innovation

Senior Director of Application Innovation at Neudesic; Software developer; confused father