This guide will help you integrate Microsoft login with Firebase Auth. It contains the necessary settings required in Firebase and Microsoft.

Assumptions

This guide assumes you have the following:

  1. Base Next.js application already up and running.
  2. Firebase project is configured and firebase_config.json is already present in the app.

Step 1: Create the Application in Azure Portal

Login or create an account in the Azure portal.

Step 1.1: Entra login & Applications menu

Navigate to Microsoft Entra admin center, then navigate to Applications in the left side menu.

Step 1.2: Create an application

Click on New Registration and enter the details in the New Registration form. The Redirect URL can be added later, or if you have it handy (from Firebase), add it now.

Once the app is registered you will see the Overview screen.

Copy the Application ID, which is also the Client ID that is needed for Firebase (see Step 2.2).

Step 1.3: Create the Client Secret

Click on Certificates and Secrets in the left menu, then click on New client secret. Add the details in the secret creation form.

Once the secret is created, you should see it in the Client secrets list. Copy the Secret Value as required for Firebase.

Step 2: Firebase Configuration

Step 2.1: Login to the Firebase console

Go to the Firebase console and select Authentication.

Step 2.2: Add new provider

Under Authentication, select the Sign-in method and Add:

Step 2.3: Redirect URI

Copy the Redirect URI from Step 2.2 and add it in the Entra website under Authentication > Web > Redirect URI (Add URI).

Step 3: Code

Implement the button below in the front end.

Step 3.1: SVG file

Create a new file in the public folder of Next.js called microsoft-logo.svg and paste the below content into it:

<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 23 23">
    <path fill="#f3f3f3" d="M0 0h23v23H0z"/>
    <path fill="#f35325" d="M1 1h10v10H1z"/>
    <path fill="#81bc06" d="M12 1h10v10H12z"/>
    <path fill="#05a6f0" d="M1 12h10v10H1z"/>
    <path fill="#ffba08" d="M12 12h10v10H12z"/>
</svg>

Step 3.2: TSX Code for UI Button

In your login/page.tsx return, add the below code for the button that uses the above SVG.

Please note the below code uses Tailwind CSS.

<button
    disabled={isSigningIn}
    onClick={(e) => {
        onMicrosoftSignIn(e);
    }}
    className={`w-[50%] flex m-2 mx-auto items-center justify-center gap-x-3 py-2.5 border rounded-lg text-sm ${
        isSigningIn ? "cursor-not-allowed" : "hover:bg-gray-100 transition duration-300 active:bg-gray-100"
    }`}
>
    <object type="image/svg+xml" data="/microsoft-logo.svg"
            style={{width: '20px', height: '20px'}}>
        Microsoft Logo
    </object>
    {isSigningIn ? "Signing In..." : "Continue with Microsoft"}
</button>

Add the onMicrosoftSignIn implementation in the Login Page:

// Use State Variables, modify as needed
const [isSigningIn, setIsSigningIn] = useState(false)
const [credentialCheckInProgress, setCredentialCheckInProgress] = useState(false);
const [loginVerified, setLoginVerified] = useState(false);
const [loginSuccess, setLoginSuccess] = useState(false);

const processAfterLoginCookie = async (userEmailId: string) => {
  // Process this data as needed
  // Save or do next steps here.
}

const onLoginSuccessUI = () => {
   setCredentialCheckInProgress(false);
   setLoginVerified(true);
   setCredentialsFailed(false);
   setLoginSuccess(true);
}

const onLoginFailureUI = (reason) => {
   setCredentialCheckInProgress(false);
   setLoginVerified(true);
   setLoginSuccess(false);
   setCredentialsFailed(true);
   if (reason.charAt("/") <= 0) {
      setRoutePath(RouteUrls.LOGIN);
   }
}

const onMicrosoftSignIn = (e) => {
    e.preventDefault()
    setCredentialCheckInProgress(true);
    if (!isSigningIn) {
        setIsSigningIn(true);
        doSignInWithMicrosoft().then(result => {
            console.log("After login with Microsoft", result);
            if (result && result.email) {
                processAfterLoginCookieReceived(result.email).then(result => {
                    if (result !== "") {
                        onLoginSuccessUI();
                    }
                }).catch(err => {
                    console.error("Verification failed --", err);
                    onLoginFailureUI("Verification failed");
                });
            }
        }).catch(err => {
            setIsSigningIn(false);
            onLoginFailureUI("Verification failed");
            console.log("Login error inside Microsoft login after popup", err);
        })
    }

    setTimeout(() => {
        setIsSigningIn(false);
    }, 5000);
}

Step 3.3: Firebase Auth Code

The code below calls Firebase auth to process the login. This file would also have the doSignInWithGoogle and other functions.

Please note that tenant: 'common' is important to allow any domain to login to your app (live/work email etc). You can replace it with your tenant id if you want only a specific domain email id.

export const doSignInWithMicrosoft = async (): Promise<SignInData> => {
  const provider = new OAuthProvider('microsoft.com');
  const auth = getAuth();
  provider.setCustomParameters({
    tenant: 'common'
  });

  try {
    const result = await signInWithPopup(fbAuth, provider);
    // Get the OAuth access token and ID Token
    const credential = OAuthProvider.credentialFromResult(result);

    if (credential) {
      const idToken = credential.idToken;
      const accessToken = credential.accessToken; // use this if needed
      const signInData = {
        code: 200,
        email: result.user.email,
        token: idToken,
        full_name: result.user.displayName
      } as SignInData;
      return signInData;
    } else {
      return {code: 401} as SignInData; // Unauthorized
    }
  } catch (error) {
    console.error("Microsoft sign-in error:", error);
    return {code: 401} as SignInData; // Unauthorized
  }
};

Troubleshooting

1. Error AADSTS7000215

See Step 3.3 and specifically setCustomParameters(...). Also check Step 1.3 and copy the Secret Value properly (not the Secret ID).

FirebaseError: Firebase: Error getting access token from microsoft.com,
OAuth2 redirect uri is: https://xxx.firebaseapp.com/__/auth/handler,
response: OAuth2TokenResponse
error=invalid_client&error_description=AADSTS7000215: Invalid client secret provided.
Ensure the secret being sent in the request is the client secret value,
not the client secret ID, for a secret added to the app.

2. Permission error

Make sure that the API permissions are set as follows:

Permission Type: Delegated

"Grant Admin consent for Default Directory" is clicked and you see the green tick on the right.

If no permissions are present, click on "Add a permission" and add email and profile under the "Delegated" type in Microsoft Graph.

Continue the Discussion

If you are integrating Microsoft auth into a production app and want help with architecture, security, and rollout planning, book a CTO consultation.

You can also connect with me on LinkedIn for implementation-specific questions.