ms-identity-b2c-javascript-nodejs-management
v1.0.0
Published
JavaScript single-page application calling Microsoft Graph with delegated permissions to manage Azure AD B2C user accounts
Downloads
16
Maintainers
Readme
JavaScript single-page application calling Microsoft Graph with delegated permissions to manage Azure AD B2C user accounts
- Overview
- Scenario
- Contents
- Prerequisites
- Setup
- Registration
- Running the sample
- Explore the sample
- About the code
- More information
- Community Help and Support
- Contributing
Overview
This sample demonstrates a how to manage your B2C users with Microsoft Graph via a vanilla JavaScript single-page application (SPA) using delegated permissions, with the help of Microsoft Authentication Library of JavaScript (MSAL.js) for authentication and Microsoft Graph JavaScript SDK for querying Microsoft Graph.
Scenario
- The client JavaScript SPA uses MSAL.js to sign-in and obtain a JWT access token from Azure AD B2C.
- The access token is used as a bearer token to authorize the user to call Microsoft Graph.
Contents
| File/folder | Description |
|-------------------|---------------------------------------------------------------|
| authConfig.js
| Authentication parameters reside here. |
| authProvider.js
| Main authentication logic resides here. |
| graph.js
| Contains an implementation of MS Graph JavaScript SDK client. |
Prerequisites
- A user account with admin privileges in your Azure AD B2C tenant.
Setup
Locate the root folder of the sample in a terminal. Then:
cd Chapter1
npm install
Registration
:information_source: If you would like to use an existing B2C app registration that you use for signing-in users with user-flows (audience type 3), you can do so. However, you won't be able to grant delegated permissions via the Permissions blade on the App Registration portal. Still, because of dynamic consent, this won't be an issue, as you will already sign-in with an admin account that can consent to these permissions for herself. See "configure the code to use your app registration" section below for other differences.
Choose the Azure AD tenant where you want to create your applications
As a first step you'll need to:
- Sign in to the Azure portal.
- If your account is present in more than one Azure AD B2C tenant, select your profile at the top right corner in the menu on top of the page, and then switch directory to change your portal session to the desired Azure AD B2C tenant.
Register the app
- Navigate to the Azure portal and select the Azure AD B2C service.
- Select the App Registrations blade on the left, then select New registration.
- In the Register an application page that appears, enter your application's registration information:
- In the Name section, enter a meaningful application name that will be displayed to users of the app, for example
b2c-management-spa
. - Under Supported account types, select Accounts in this organizational directory only.
- In the Redirect URI (optional) section, select Single-page application in the combo-box and enter the following redirect URI:
http://localhost:3000
.
- In the Name section, enter a meaningful application name that will be displayed to users of the app, for example
- Select Register to create the application.
- In the app's registration screen, find and note the Application (client) ID. You use this value in your app's configuration file(s) later in your code.
- Select Save to save your changes.
- In the app's registration screen, select the API permissions blade in the left to open the page where we add access to the APIs that your application needs.
- Select the Add a permission button and then,
- Ensure that the Microsoft APIs tab is selected.
- In the Commonly used Microsoft APIs section, select Microsoft Graph
- In the Delegated permissions section, select the User.ReadWrite.All in the list. Use the search box if necessary.
- Select the Add permissions button at the bottom.
- Finally, grant Admin consent to these permissions.
Configure the code to use your app registration
Open the project in your IDE (like Visual Studio or Visual Studio Code) to configure the code.
In the steps below, "ClientID" is the same as "Application ID" or "AppId".
- Open the
App\authConfig.js
file. - Find the key
Enter_the_Application_Id_Here
and replace the existing value with the application ID (clientId) ofb2c-management-spa
app copied from the Azure portal. - Find the key
Enter_the_Tenant_Info_Here
and replace the existing value with your tenant ID copied form Azure portal.
:information_source: If you are using an existing B2C app registration that you use for signing-in users with user-flows, replace
Enter_the_Tenant_Info_Here
not with your tenant ID, but with "common".
Running the sample
Locate the root folder of the sample in a terminal. Then:
cd Chapter1
npm start
Explore the sample
- Open your browser and navigate to
http://localhost:3000
. - Click on the sign-in button on the top right corner (make sure to sign-in with an administrator account).
- Click on the Get Users button retrieve the users in your tenant.
- Click on the Add Users button to add a new user to your tenant (see here for requirements when adding a new user)
:information_source: Did the sample not work for you as expected? Then please reach out to us using the GitHub Issues page.
:information_source: if you believe your issue is with the B2C service itself rather than with the sample, please file a support ticket with the B2C team by following the instructions here.
We'd love your feedback!
Were we successful in addressing your learning objective? Consider taking a moment to share your experience with us.
About the code
Getting and passing access tokens
In authProvider.js, we initialize an MSAL client by passing a configuration object as shown below:
const pca = new msal.PublicClientApplication(msalConfig);
We then define a method for getting access tokens. To do so, we first attempt to acquire token silently from the browser cache, and fallback to an interactive method (here, popup) should that fails:
getTokenPopup(request) {
request.account = pca.getAccountByHomeId(accountId);
return pca.acquireTokenSilent(request)
.then((response) => {
// In case the response from B2C server has an empty accessToken field
// throw an error to initiate interactive token acquisition
if (!response.accessToken || response.accessToken === "") {
throw new msal.InteractionRequiredAuthError;
}
return response;
})
.catch(error => {
console.log(error);
console.log("silent token acquisition fails. acquiring token using popup");
if (error instanceof msal.InteractionRequiredAuthError) {
// fallback to interaction when silent call fails
return pca.acquireTokenPopup(request)
.then(response => {
console.log(response);
return response;
}).catch(error => {
console.log(error);
});
} else {
console.log(error);
}
});
}
Finally, we create MyAuthenticationProvider class that implements AuthenticationProvider
interface (see for more: Using Custom Authentication Provider). This class is used to instantiate a custom token middleware that is needed for enabling Microsoft Graph JavaScript SDK client object to communicate with the Microsoft Graph API.
class MyAuthenticationProvider {
async getAccessToken() {
return new Promise(async(resolve, reject) => {
// here we get an access token for MS Graph
const authResponse = await getTokenPopup(tokenRequest);
if (authResponse.accessToken && authResponse.accessToken.length !== 0) {
resolve(authResponse.accessToken);
} else {
reject(Error("Error: cannot obtain access token."));
}
});
}
}
Querying Microsoft Graph
We first initialize the Microsoft Graph JavaScript SDK client:
const clientOptions = {
authProvider: new MyAuthenticationProvider(),
};
const client = MicrosoftGraph.Client.initWithMiddleware(clientOptions);
After that, we can use it for CRUD operations on Graph resources. For instance, to update a user account:
async function updateUser(id, prop) {
try {
console.log('Graph API called at: ' + new Date().toString());
return await client.api(`/users/${id}`).patch(prop);
} catch (error) {
console.log(error);
return error;
}
}
More information
- What is Azure Active Directory B2C?
- Application types that can be used in Active Directory B2C
- Recommendations and best practices for Azure Active Directory B2C
- Azure AD B2C session
- Initialize client applications using MSAL.js
- Single sign-on with MSAL.js
- Handle MSAL.js exceptions and errors
- Logging in MSAL.js applications
- Pass custom state in authentication requests using MSAL.js
- Prompt behavior in MSAL.js interactive requests
- Use MSAL.js to work with Azure AD B2C
For more information about how OAuth 2.0 protocols work in this scenario and other scenarios, see Authentication Scenarios for Azure AD.
Community Help and Support
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
azure-ad-b2c
ms-identity
msal
].
If you find a bug in the sample, raise the issue on GitHub Issues.
To provide feedback on or suggest features for Azure Active Directory, visit User Voice page.
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.