DEV Community

Christos Matskas for The 425 Show

Posted on

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

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.

Top comments (8)

Collapse
 
shahzad6077 profile image
Muhammad Shahzad Ali

Thanks for the great article, Is that possible we can get the assigned user roles in azure AD within firebase?

Collapse
 
christosmatskas profile image
Christos Matskas

If a user is assigned roles, then these will be part of the ID Token. You will need to create some mapping in the Firebase DB but to be honest I don't think you need this as the roles will always be part of the ID Token. Any reason why you need to persist them?

Collapse
 
shahzad6077 profile image
Muhammad Shahzad Ali

Yes we are getting the roles in ID Token but only when user sign-in otherwise ID Token isn't included in authstatuschanged or I'm missing something?

Thread Thread
 
proskurindima profile image
proskurindima

Hi!
Did you manage to solve this problem?
We ran into exactly the same problem today and haven't been able to find a solution yet.

Thread Thread
 
christosmatskas profile image
Christos Matskas

I think the problem here is with Firebase and not Azure AD... You can certainly reach out to our dev support team to get some assistance aka.ms/425Show/help

Thread Thread
 
shahzad6077 profile image
Muhammad Shahzad Ali

Thanks @christosmatskas for the response. Yeah you right the problem is with the Firebase. I didn't find a reliable solution yet. you can get the user app role with the MS graph API using OAuth token.

stackoverflow.com/questions/635008...
docs.microsoft.com/en-us/graph/api...
https://docs.microsoft.com/en-us/graph/api/group-list-approleassignments?view=graph-rest-1.0&tabs=http

If anyone found a reliable solution share with us :) Thanks!

Collapse
 
hiroshinishio profile image
Hiroshi Nishio

When I go to Login with Microsoft, one of the options is a sign in option, but it didn't work for me. Did it work for Christos?
learn.microsoft.com/en-us/answers/...

Collapse
 
sahildange1 profile image
Sahil

Awesome