| title | Enable authentication in your own Node.js web API by using Azure Active Directory B2C |
|---|---|
| description | Follow this article to learn how to call your own web API protected by Azure AD B2C from your own node js web app. The web app acquires an access token and uses it to call a protected endpoint in the web API. The web app adds the access token as a bearer in the Authorization header, and the web API needs to validate it. |
| titleSuffix | Azure AD B2C |
| author | kengaderdus |
| manager | CelesteDG |
| ms.service | azure-active-directory |
| ms.custom | devx-track-js |
| ms.topic | how-to |
| ms.date | 01/11/2024 |
| ms.author | kengaderdus |
| ms.subservice | b2c |
[!INCLUDE active-directory-b2c-end-of-sale-notice-b]
In this article, you learn how to create your web app that calls your web API. The web API needs to be protected by Azure Active Directory B2C (Azure AD B2C). To authorize access to the web API, you serve requests that include a valid access token that's issued by Azure AD B2C.
-
Before you begin read and complete the steps in the Configure authentication in a sample Node.js web API by using Azure AD B2C. Then, follow the steps in this article to replace the sample web app and web API with your own web API.
-
Visual Studio Code, or another code editor
Follow these steps to create your Node.js web API.
Use Express for Node.js to build a web API. To create a web API, do the following:
- Create a new folder named
TodoList. - Under the
TodoListfolder, create a file namedindex.js. - In a command shell, run
npm init -y. This command creates a defaultpackage.jsonfile for your Node.js project. - In the command shell, run
npm install express. This command installs the Express framework.
Add the authentication library to your web API project. The authentication library parses the HTTP authentication header, validates the token, and extracts claims. For more information, review the documentation for the library.
To add the authentication library, install the packages by running the following command:
npm install passport
npm install passport-azure-ad
npm install morgan
The morgan package is an HTTP request logger middleware for Node.js.
In the index.js file, add the following code:
:::code language="JavaScript" source="~/active-directory-b2c-javascript-nodejs-webapi/index.js":::
Take note of the following code snippets in the index.jsfile:
-
Imports the passport Microsoft Entra library
:::code language="JavaScript" source="~/active-directory-b2c-javascript-nodejs-webapi/index.js" id="ms_docref_import_azuread_lib":::
-
Sets the Azure AD B2C options
:::code language="JavaScript" source="~/active-directory-b2c-javascript-nodejs-webapi/index.js" id="ms_docref_azureadb2c_options":::
-
Instantiate the passport Microsoft Entra library with the Azure AD B2C options
:::code language="JavaScript" source="~/active-directory-b2c-javascript-nodejs-webapi/index.js" id="ms_docref_init_azuread_lib":::
-
The protected API endpoint. It serves requests that include a valid Azure AD B2C-issued access token. This endpoint returns the value of the
nameclaim within the access token.:::code language="JavaScript" source="~/active-directory-b2c-javascript-nodejs-webapi/index.js" id="ms_docref_protected_api_endpoint":::
-
The anonymous API endpoint. The web app can call it without presenting an access token. Use it to debug your web API with anonymous calls.
:::code language="JavaScript" source="~/active-directory-b2c-javascript-nodejs-webapi/index.js" id="ms_docref_anonymous_api_endpoint":::
Add configurations to a configuration file. The file contains information about your Azure AD B2C identity provider. The web API app uses this information to validate the access token that the web app passes as a bearer token.
-
Under the project root folder, create a
config.jsonfile, and then add to it the following JSON object::::code language="json" source="~/active-directory-b2c-javascript-nodejs-webapi/config.json":::
-
In the
config.jsonfile, update the following properties:
| Section | Key | Value |
|---|---|---|
| credentials | tenantName | The first part of your Azure AD B2C tenant name (for example, fabrikamb2c). |
| credentials | clientID | The web API application ID. To learn how to get your web API application registration ID, see Prerequisites. |
| policies | policyName | The user flows, or custom policy. To learn how to get your user flow or policy, see Prerequisites. |
| resource | scope | The scopes of your web API application registration such as [tasks.read]. To learn how to get your web API scope, see Prerequisites. |
Follow these steps to create the Node web app. This web app authenticates a user to acquire an access token that is used to call the Node web API you created in step 1:
Create a folder to hold your node application, such as call-protected-api.
-
In your terminal, change directory into your node app folder, such as
cd call-protected-api, and runnpm init -y. This command creates a default package.json file for your Node.js project. -
In your terminal, run
npm install express. This command installs the Express framework. -
Create more folders and files to achieve the following project structure:
call-protected-api/ ├── index.js └── package.json └── .env └── views/ └── layouts/ └── main.hbs └── signin.hbs └── api.hbsThe
viewsfolder contains handlebars files for the web app's UI.
In your terminal, install the dotenv, express-handlebars, express-session, and @azure/msal-node packages by running the following commands:
npm install dotenv
npm install express-handlebars
npm install express
npm install axios
npm install express-session
npm install @azure/msal-node
-
In the
main.hbsfile, add the following code::::code language="html" source="~/active-directory-b2c-msal-node-sign-in-sign-out-webapp/call-protected-api/views/layouts/main.hbs":::
The
main.hbsfile is in thelayoutfolder and it should contain any HTML code that is required throughout your application. It implements UI built with the Bootstrap 5 CSS Framework. Any UI that changes from page to page, such assignin.hbs, is placed in the placeholder shown as{{{body}}}. -
In the
signin.hbsfile, add the following code::::code language="html" source="~/active-directory-b2c-msal-node-sign-in-sign-out-webapp/call-protected-api/views/signin.hbs":::
-
In the
api.hbsfile, add the following code::::code language="html" source="~/active-directory-b2c-msal-node-sign-in-sign-out-webapp/call-protected-api/views/api.hbs":::
This page displays the response from the API. The
bg-{{bg_color}}class attribute in Bootstrap's card enables the UI to display a different background color for the different API endpoints.
-
In the
.envfile, add the following code, which includes server http port, app registration details, and sign in and sign up user flow/policy details::::code language="html" source="~/active-directory-b2c-msal-node-sign-in-sign-out-webapp/call-protected-api/.env":::
Modify the values in the
.envfiles as explained in Configure the sample web app -
In your
index.jsfile, add the following code::::code language="JavaScript" source="~/active-directory-b2c-msal-node-sign-in-sign-out-webapp/call-protected-api/index.js":::
The code in the
index.jsfile consists of global variables and express routes.Global variables:
-
confidentialClientConfig: The MSAL configuration object, which is used to create the confidential client application object.:::code language="JavaScript" source="~/active-directory-b2c-msal-node-sign-in-sign-out-webapp/call-protected-api/index.js" id="ms_docref_configure_msal":::
-
apiConfig: ContainswebApiScopesproperty (it's value must be an array), which is the scopes configured in the web API, and granted to the web app. It also has URIs to the web API to be called, that isanonymousUriandprotectedUri.:::code language="JavaScript" source="~/active-directory-b2c-msal-node-sign-in-sign-out-webapp/call-protected-api/index.js" id="ms_docref_api_config":::
-
APP_STATES: A value included in the request that's also returned in the token response. Used to differentiate between responses received from Azure AD B2C. -
authCodeRequest: The configuration object used to retrieve authorization code. -
tokenRequest: The configuration object used to acquire a token by authorization code. -
sessionConfig: The configuration object for express session. -
getAuthCode: A method that creates the URL of the authorization request, letting the user input credentials and consent to the application. It uses thegetAuthCodeUrlmethod, which is defined in the ConfidentialClientApplication class.
Express routes:
/:- It's the entry to the web app, and renders the
signinpage.
- It's the entry to the web app, and renders the
/signin:- Signs in the user.
- Calls
getAuthCode()method and passes theauthorityfor Sign in and sign up user flow/policy,APP_STATES.LOGIN, andapiConfig.webApiScopesto it. - It causes the end user to be challenged to enter their logins, or if the user doesn't have an account, they can sign up.
- The final response resulting from this endpoint includes an authorization code from B2C posted back to the
/redirectendpoint.
/redirect:- It's the endpoint set as Redirect URI for the web app in Azure portal.
- It uses the
statequery parameter in Azure AD B2C's response, to differentiate between requests that are made from the web app. - If the app state is
APP_STATES.LOGIN, the authorization code acquired is used to retrieve a token using theacquireTokenByCode()method. When requesting for a token usingacquireTokenByCodemethod, you use the same scopes used while acquiring the authorization code. The acquired token includes anaccessToken,idToken, andidTokenClaims. After you acquire theaccessToken, you put it in a session for later use in to call the web API.
/api:- Calls the web API.
- If the
accessTokenisn't in the session, call the anonymous API endpoint (http://localhost:5000/public), otherwise, call the protected API endpoint (http://localhost:5000/hello).
/signout:- Signs out the user.
- clears the web app session is and makes an http call to the Azure AD B2C logout endpoint.
-
Follow the steps in Run the web app and API to test your web app and web API.