Using Azure AD B2C to Authenticate Android App Users
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:
- Building Application Identity Solutions using Azure AD B2C
- Configure Azure AD B2C For Customization
- Understanding the B2C Directory
- Sign Up or Sign In Users With Azure AD B2C: Part 1
- Sign Up New Users Using Azure AD B2C
- Log In With Local Accounts on Azure AD B2C
- Combining Sign Up and Sign In Into a Single Policy Using Azure AD B2C
- Using Azure AD B2C to Authenticate Web App Users
- 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:
I chose Kotlin for the implementation language and based on demo on the Android SDK version 29:
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:
- In the Project Explorer, expand the
app/src/main/res
folder. - Right click on the
res
folder and choose New —> Android Resource Directory. - In the New Resource Directory modal, change the Resource type value to raw.
- Click the OK button to create the directory.
- Right click on the new
raw
directory and choose New —> File. - 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:
- Open a web browser to the Azure Portal and navigate to the App Registration in the Azure Active Directory B2C portal.
- Click in the Authentication link in the navigation list on the left.
- Click the Add a platform button.
- Choose the Android platform.
- In the Package name field, enter the application identifier from the
app/build.gradle
file. - In the Signature hash field, enter the hash that you previously obtained and used in the earlier configuration steps.
- 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:
- In the Azure Active Directory B2C portal, navigate to the App Registrations screen.
- Click on the New registration link.
- Enter a simple name for the app. I used
Project Center API
. - For the Supported account types field, I chose Accounts in this organizational directory only.
- Ensure that Grand admin consent to opened and offlineaccess permissions is checked.
- Click the Register button to create the app registraton.
- In the app registration screen, click on Expose an API in the left navigation menu.
- Click the Add a scope link to create a new scope.
- Accept the default value for the application in the next screen.
- On the Add a scope form, enter Files.Read in the Scope name field.
- Add a simple description and admin consent description.
- Ensure that Enabled is selected for the state value.
- Click the Add scope button to save the scope.
- Navigate back to your app registration (the app, not the API app).
- In the left navigation menu, choose the API permissions link.
- Click the Add permissions button.
- In the Request API Permissions view, change to the My APIs tab.
- Select the API application
- Check the Files.Read permission.
- Click the Add permissions button to save.
- 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:
- Open
app/src/main/res/layout/activity_main.xml
in the IDE. - Select the text box in the view and delete it.
- Add a
Button
to the layout and align the button so that it appears in the center of the view. - Change the text in the button to
Log In
and change the identifier tologInButton
.
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:
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:
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.