loading...
The 425 Show

Integrate Azure AD with Firebase and call MS Graph in a Node.js app

christosmatskas profile image Christos Matskas ・6 min read

Today was the first day of Firebase Summit. Although not my default "go-to" technology for building apps, I always try to stay ahead of the curve and keep my self up-to-date with the latest and greatest in the software development space. And since Microsoft Identity permeates so many languages, technologies and platforms, I want to ensure that we have a good story for our developers.

So today, my curiosity got the best of me, and after watching the session on Firebase authentication, I decided to go ahead and implement a custom authentication provider in Firebase. I, yes you guessed it, wanted to integrate Azure Active Directory to authenticate users and call MS Graph to get user profile and email data using the Firebase.Auth service.

In case you haven't heard or used Firebase before, Firebase is a collection of services such as auth, storage, messaging etc that you can use to build apps (mobile, web etc) on top of. You can find more information in the official docs.And as we know, there is very little you can do without touching authentication. Firebase offers a number of authentication options, including custom providers. This is a great opportunity to show how you can integrate Azure Active Directory with Firebase to authenticate users.

Download and run the code

The working sample is available on GitHub to clone and run locally. If you want to understand how the app was put together, you can use the included Code Tour to step through my code changes. Code Tour is a VS Code extension to record and add explanations/annotation in your code to help others understand what you build.

Create your Firebase project and app

There are three things we need to do to enable Firebase to work with Azure AD, before writing any code.

  • Create a Firebase project
  • Register an app in Firebase.
  • Register an app in Azure AD

We can complete these 3 tasks following the official docs (Firebase and Azure AD)

To create a new Firebase project, if you don't have one, go to your dashboard and click on the Add project button.

Alt Text

Give the project a meaningful name:

Alt Text

Press Continue on the next screen and on the final step, select a Google Analytics account to use for logging. Finally, press the Create project to finalize the project creation

Alt Text

Step 1 done, 2 to go.

Next, we need to add an app to get started. The app indicates our intent to use Firebase and its underlying services. On the project we just created, we need to click on the appropriate platform to add the app. In this instance, we will be working on a web app, so let's go ahead and create it:

Alt Text

On the next screen, give it a name and press Create. This will register the app and provide us with the the necessary configuration to instantiate the Firebase client in our code later. I love how it generates everything I need in one place!

Alt Text

Step 2 done, 1 (and a bit) to go.

For users to be able to authenticate against Azure AD, we also need to create an app registration in Azure AD. Let's head over to the Azure portal and create a new one. In the Azure AD portal, select the App registrations blade and hit the New registration button

Alt Text

Let's give our app a meaningful name, I chose FirebaseAuth and press the Register button. Next, we need to head to the Certificates & secrets blade to create a new secret. This secret will be used by Firebase to authenticate against AAD.

Alt Text

Make sure to copy the secret. Now, let's take a small diversion and head back to our Firebase dashboard to configure our custom Authentication with Azure AD. Click on the Authentication option on the navigation bar, select the Sign-in method and click on Microsoft to configure the Azure AD settings.

On the new popup window, paste the Azure AD application Id and secret we created in the steps above. Make sure to toggle the "Enable" to true so that you can edit the settings. Next, copy the redirect URL so that we can finalize the Azure AD app registration with the right information.

Alt Text

Let's hop back to our Azure AD app registration in the Azure portal to finalize the configuration. Head to the Authentication blade and press the Add a platform.

Alt Text

In the Redirect URIs, add the URI that was provided in our Firebase configuration and press Configure. Unlike using a normal redirect URI, like http://localhost:<port> with this URI we instruct Azure AD to redirect the successful logins back to Firebase first, before returning the user back to the app.

Alt Text

The last (optional) step is to add any extra permissions to our app registration. This is required if you need to speak to another custom API (maybe your API?), Azure service, MS Graph etc. Let's head over to the API permissions and add an extra Graph permission to request access to the user's emails. Open the API Permissions blade and click on the Add a permission button. Select MS Graph on the new tab.

Alt Text

Next, select Delegated permissions, search for Mail.Read, select the permission and click the Add permissions button.

Alt Text

With this last step, our configuration is over and we can start writing some code.

Create the Node.js app

Instead of trying to create something from scratch, I decided to download one of our quick start samples from AAD and convert it to use Firebase - simples :)

You can find a very large number of samples in our Azure AD docs, but there is also another, often overlooked, place that can help you get started. Inside the Azure AD app registration, open the Quickstart blade and select the technology you wish to work with:

Alt Text

Since I want something as barebones as possible, I went with Single-page application (SPA) -> JavaScript (auth code flow)

On the next step, ignore the settings and click on the Download the code sample. Unzip and open in your favorite code editor. I work with VS Code in this instance.

Next, we need to add a new file to handle the Firebase authentication. In the app folder, add firebaseAuth.js. In this file we will configure the signIn, signOut and calls to MS Graph. I know, not the best or cleanest design, but it does the job. Open the file and add the following code:

let firebaseConfig = {
    apiKey: "<your API Key>",
    authDomain: "<your domain>.firebaseapp.com",
    databaseURL: "https://<your domain>.firebaseio.com",
    projectId: "<your project name>",
    storageBucket: "<your domain>.appspot.com",
    messagingSenderId: "00000000000",
    appId: "1:549489080000:web:0000f4d2211ad0710219e7",
    measurementId: "G-11111G97CMT"
  };
  // Initialize Firebase
  firebase.initializeApp(firebaseConfig);
  firebase.analytics();

let provider = new firebase.auth.OAuthProvider('microsoft.com');
// set the persistence to session
// firebase.auth().setPersistence(firebase.auth.Auth.Persistence.SESSION);
let accessToken = '';

provider.setCustomParameters({
    tenant: 'b55f0c51-61a7-45c3-84df-33569b247796',
});

// this is required for Graph
provider.addScope('mail.read');

function signIn(){
    firebase.auth().signInWithPopup(provider)
        .then(function(result){
            showWelcomeMessage(result.additionalUserInfo.profile.displayName);
            accessToken = result.credential.accessToken;
            console.log('Authentication successful');
        })
        .catch(function(error) {
            console.log(`Error during authentication: ${error}`);
        });
}

function signOut(){
    firebase.auth().signOut().then(function() {
        // Sign-out successful.
        accessToken='';
        showSignOutMessage();
        console.log('user signed out');
      }).catch(function(error) {
        // An error happened.
        console.error('Sign out messed up somewhere...meh');
      });
}

function seeProfile(){
    callMSGraph(graphConfig.graphMeEndpoint, accessToken, updateUI);
    profileButton.classList.add('d-none');
    mailButton.classList.remove('d-none');
}

function readMail() {
    callMSGraph(graphConfig.graphMailEndpoint, accessToken, updateUI);
}
Enter fullscreen mode Exit fullscreen mode

Note: you can grab the Firebase config directly from your Firebase app registration, so don't worry about providing the individual details here, unless you know them.

The above code is called when we want to sign in our sign out users or get MS Graph data. It then calls the UI.js methods to update the UI accordingly. You can see the code in action below:

Alt Text

You can play with some of the default settings to ensure that the signin/signout experience is tailored to your needs. For example, I changed how the auth state is persisted on the user's browsers once the user signs in. You can choose from local, session, none:

Alt Text

Alt Text

Conclusion

As you can see, integrating our existing identity provider, in this instance Azure AD, with Firebase is pretty straightforward. If you are a Firebase developer then the ability to add AAD as a custom identity provider opens up a lot of possibilities for building secure and rich aps that rely on open standards such as OAuth to keep your users safe while you focus on your business needs.

Discussion

pic
Editor guide