Skip to content

Latest commit

 

History

History
291 lines (212 loc) · 17.2 KB

File metadata and controls

291 lines (212 loc) · 17.2 KB
page_type name description languages products urlFragment extensions
sample
Sign in users in a sample Node.js & Express web app by using Microsoft Entra External ID for customers
This sample demonstrates a Node.js & Express web app authenticating users by using Microsoft Entra External ID for customers with Microsoft Authentication Library for Node (MSAL Node)
javascript
entra-external-id
msal-node
ms-identity-ciam-javascript-tutorial-5-sign-in-express
services sub-service platform endpoint level client
active-directory
ciam
JavaScript
AAD v2.0
100
Node.js & Express web app

Sign in users in a sample Node.js (Express.js) web app by using Microsoft Entra External ID for customers

Overview

This sample demonstrates how to sign users into a sample Node.js & Express web app by using Microsoft Entra External ID for customers. The samples utilizes the Microsoft Authentication Library for Node (MSAL Node) to simplify adding authentication to the Node.js web app.

Usage

Instruction Description
Use case This code sample applies to customer configuration uses caseYes button. If you're looking for a workforce configuration use case, use Tutorial: Enable a Node.js (Express) application to sign in users by using Microsoft Entra ID
Scenario Sign in users. You acquire an ID token by using authorization code flow with PKCE.
Add sign in to your app Use the instructions in Sign in users in a Node.js web app to learn how to add sign in to your Node web app.
Product documentation Explore Microsoft Entra ID for customers documentation

Contents

File/folder Description
App/app.js Application entry point.
App/authConfig.js Contains authentication parameters such as your tenant sub-domain, Application (Client) ID, app client secret and redirect URI.
App/auth/AuthProvider.js The main authentication logic resides here.
/App/views/ This folder contains app views. This Node/Express sample app's views uses Handlebars.
/App/routes/ This folder contains app's routes.

Prerequisites

  • You must install Node.js in your computer to run this sample.
  • We recommend Visual Studio Code for running and editing this sample.
  • An external tenant. To create one, choose from the following methods:
  • If you'd like to use Azure services, such as hosting your app in Azure App Service, VS Code Azure Tools extension is recommended for interacting with Azure through VS Code Interface.

Register the web application in your tenant

You can register an app in your tenant automatically by using Microsoft Graph PowerShell or via the Microsoft Entra Admin center.

When you use Microsoft Graph PowerShell, you automatically register the applications and related objects app secrets, then modify your project config files, so you can run the app without any further action:

  • To register your app in the Microsoft Entra admin center use the steps in Register the web app.

  • To register and configure your app automatically,

    Expand this section

    ⚠️ If you have never used Microsoft Graph PowerShell before, we recommend you go through the App Creation Scripts Guide once to ensure that you've prepared your environment correctly for this step.

    1. Ensure that you have PowerShell 7 or later installed.

    2. Run the script to create your Microsoft Entra ID application and configure the code of the sample application accordingly.

    3. For interactive process in PowerShell, run:

      cd .\AppCreationScripts\
      .\Configure.ps1 -TenantId "[Optional] - your tenant id" -AzureEnvironmentName "[Optional] - Azure environment, defaults to 'Global'"

    Other ways of running the scripts are described in App Creation Scripts guide. The scripts also provides a guide to automated application registration, configuration and removal which can help in your CI/CD scenarios.

    ❗ NOTE: This sample can make use of client certificates. You can use AppCreationScripts to register an Microsoft Entra ID application with certificates. For more information see, Use client certificate for authentication in your Node.js web app instead of client secrets.

Add app client secret

To create a client secret for the registered application, use the steps in Add app client secret

Grant API permissions

To grant delegated permissions, use the steps in Grant API permissions.

Create user flow

To create a user flow a customer can use to sign in or sign up for an application, use the steps in Create a user flow

Associate the web application with the user flow

To associate the web application with the user flow, use the steps in Associate the web application with the user flow.

Clone or download sample web application

To get the web app sample code, use the steps in Clone or download sample web application.

Install project dependencies

To install app dependencies, use the steps in Install project dependencies.

Configure the sample web app to use your app registration

Once you download the sample app, you need to update it so that it uses the settings of the web app that you registered. To do so, use the steps in Configure the sample web app.

Run and test sample web app

You can now test the sample Node.js web app. You need to start the Node.js server and access it through your browser at http://localhost:3000. To do so, use the steps in Run and test sample web app.

ℹ️ If the sample didn't work for you as expected, reach out to us using the GitHub Issues page.

We'd love your feedback

Were we successful in addressing your learning objective? Consider taking a moment to share your experience with us.

Troubleshooting

Expand for troubleshooting info
  • Use Stack Overflow to get support from the community. Ask your questions on Stack Overflow first and browse existing issues to see if someone has asked your question before. Make sure that your questions or comments are tagged with [azure-active-directory-b2c node ms-identity adal msal-js msal].

To provide feedback on or suggest features for Microsoft Entra ID or Microsoft Entra External ID, visit User Voice page.

About the code

Initialization

In order to use MSAL Node, we instantiate the ConfidentialClientApplication:

  1. Create the configuration object, msalConfig, as shown in the App/authConfig.js file:

    const msalConfig = {
        auth: {
            clientId: process.env.CLIENT_ID || 'Enter_the_Application_Id_Here', // 'Application (client) ID' of app registration in Microsoft Entra - this value is a GUID
            authority: process.env.AUTHORITY || `https://${TENANT_SUBDOMAIN}.ciamlogin.com/`, // Replace the placeholder with your tenant name
            clientSecret: process.env.CLIENT_SECRET || 'Enter_the_Client_Secret_Here', // Client secret generated from the app registration in Microsoft Entra admin center
        },
        ...
        ...
    };
  2. Use the msalConfig object to instantiate the confidential client application shown in the *App/auth/AuthProvider.js file (AuthProvider class):

    ...
    ...
    getMsalInstance(msalConfig) {
        return new msal.ConfidentialClientApplication(msalConfig);
    }
    ....
    ...

Sign in

The first leg of auth code flow generates an authorization code request URL, then redirects to that URL to obtain the authorization code. This first leg is implemented in the redirectToAuthCodeUrl method. Notice how we use MSALs getAuthCodeUrl method to generate authorization code URL, then redirect to the authorization code URL itself:

    async redirectToAuthCodeUrl(req, res, next, authCodeUrlRequestParams, authCodeRequestParams, msalInstance) {
        ...
        ...

        try {
            const authCodeUrlResponse = await msalInstance.getAuthCodeUrl(req.session.authCodeUrlRequest);
            res.redirect(authCodeUrlResponse);
        } catch (error) {
            next(error);
        }
    }

In the second leg of auth code flow uses, use the authorization code to request an ID token by using MSAL's acquireTokenByCode method. You can store the ID token and user account information in an express session.

    async handleRedirect(req, res, next) {
        const authCodeRequest = {
            ...req.session.authCodeRequest,
            code: req.body.code, // authZ code
            ...
        };

        try {
            const msalInstance = this.getMsalInstance(this.config.msalConfig);
            msalInstance.getTokenCache().deserialize(req.session.tokenCache);

            const tokenResponse = await msalInstance.acquireTokenByCode(authCodeRequest, req.body);

            req.session.tokenCache = msalInstance.getTokenCache().serialize();
            req.session.idToken = tokenResponse.idToken;
            req.session.account = tokenResponse.account;
            req.session.isAuthenticated = true;
            ...
            ...
        } catch (error) {
            next(error);
        }
    }

Sign out

When you want to sign the user out of the application, it isn't enough to end the user's session. You must redirect the user to the logoutUri. Otherwise, the user might be able to reauthenticate to your applications without reentering their credentials. If the name of your tenant is contoso, then the logoutUri looks similar to https://contoso.ciamlogin.com/contoso.onmicrosoft.com/oauth2/v2.0/logout?post_logout_redirect_uri=http://localhost:3000.

    async logout(req, res, next) {
        /**
         * Construct a logout URI and redirect the user to end the session with Microsoft Entra ID. 
        */
        const logoutUri = `${this.config.msalConfig.auth.authority}${TENANT_SUBDOMAIN}.onmicrosoft.com/oauth2/v2.0/logout?post_logout_redirect_uri=${this.config.postLogoutRedirectUri}`;
    
        req.session.destroy(() => {
            res.redirect(logoutUri);
        });
    }

Deploying Web app to Azure App Service

There is one web app in this sample. To deploy it to Azure App Services, you'll need to:

*Create an Azure App Service *Publish the projects to the App Services, and *Update its client(s) to call the website instead of the local environment.

Deploy your files of your web app

  1. In the VS Code activity bar, select the Azure logo to show the Azure App Service explorer.
  2. Select Sign in to Azure..., then follow the instructions. Once signed in, the explorer should show the name of your Azure subscription(s).
  3. On the App Service explorer section you see an upward-facing arrow icon. Select it publish your local files in the project folder to Azure App Services (use "Browse" option if needed, and locate the right folder).
  4. Choose a creation option based on the operating system to which you want to deploy. In this sample, we illustrate by using the Linux option.
  5. Select a Node.js version when prompted. We recommend a LTS version.
  6. Type a globally unique name for your web app and select Enter. The name must be unique across all of Azure services. After you respond to all the prompts, VS Code shows the Azure resources that are being created for your app in its notification popup.
  7. Select Yes when prompted to update your configuration. This action runs npm install on the target Linux server.

Update app registration to use deployed app

  1. Sign in to the Microsoft Entra admin center as at least an Application Developer.
  2. Browse to Identity >Applications > App registrations.
  3. From the app registration list, select the app that you want to update.
  4. Under Manage, select Authentication.
  5. Update your Redirect URIs to to match the site URL of your Azure deployment such as https://ciam-msal-node-webapp.azurewebsites.net/auth/redirect.
  6. Select Configure to save your changes.

⚠️ If your app use in-memory storage, Azure App Services will spin down your web site if it is inactive. This action empties any records in the memory. In addition, if you increase the instance count of your website, Azure Service distributes the requests among the instances. Therefore, your app's records won't be the same on each instance.

Contributing

If you'd like to contribute to this sample, see CONTRIBUTING.MD.

This project has adopted the Microsoft Open Source Code of Conduct. For more information, see the Code of Conduct FAQ or contact [email protected] with any additional questions or comments.

Learn More