Note
Access to this page requires authorization. You can try signing in or changing directories.
Access to this page requires authorization. You can try changing directories.
Important
Effective May 1, 2025, Azure AD B2C will no longer be available to purchase for new customers. Learn more in our FAQ.
To authorize access to a web API, you can serve only requests that include a valid access token that Azure Active Directory B2C (Azure AD B2C) issues. This article shows you how to enable Azure AD B2C authorization to your web API. After you complete the steps in this article, only users who obtain a valid access token will be authorized to call your web API endpoints.
Before you begin, read one of the following articles, which discuss how to configure authentication for apps that call web APIs. Then, follow the steps in this article to replace the sample web API with your own web API.
- Configure authentication in a sample ASP.NET Core application
- Configure authentication in a sample single-page application (SPA)
Token-based authentication ensures that requests to a web API include a valid access token.
The app completes the following steps:
It authenticates users with Azure AD B2C.
It acquires an access token with the required permissions (scopes) for the web API endpoint.
It passes the access token as a bearer token in the authentication header of the HTTP request by using this format:
Authorization: Bearer <access token>
The web API completes the following steps:
It reads the bearer token from the authorization header in the HTTP request.
It validates the token.
It validates the permissions (scopes) in the token.
It reads the claims that are encoded in the token (optional).
It responds to the HTTP request.
To enable your app to sign in with Azure AD B2C and call a web API, you need to register two applications in the Azure AD B2C directory.
The web, mobile, or SPA application registration enables your app to sign in with Azure AD B2C. The app registration process generates an Application ID, also known as the client ID, which uniquely identifies your application (for example, App ID: 1).
The web API registration enables your app to call a protected web API. The registration exposes the web API permissions (scopes). The app registration process generates an Application ID, which uniquely identifies your web API (for example, App ID: 2). Grant your app (App ID: 1) permissions to the web API scopes (App ID: 2).
The application registrations and the application architecture are described in the following diagram:
In the next sections, you create a new web API project. Select your programming language, ASP.NET Core, or Node.js. Make sure you have a computer that's running either of the following software:
- Visual Studio Code, or another code editor
- Node.js runtime
Create a new web API project. First, select the programming language you want to use, ASP.NET Core or Node.js.
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 TodoList folder, create a file named app.js.
- In a command shell, run
npm init -y
. This command creates a default package.json file 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.
Add the necessary code to initiate the authentication library.
Add the following JavaScript code to your app.js file.
// Import the required libraries
const express = require('express');
const morgan = require('morgan');
const passport = require('passport');
const config = require('./config.json');
// Import the passport Azure AD library
const BearerStrategy = require('passport-azure-ad').BearerStrategy;
// Set the Azure AD B2C options
const options = {
identityMetadata: `https://${config.credentials.tenantName}.b2clogin.cn/${config.credentials.tenantName}.partner.onmschina.cn/${config.policies.policyName}/${config.metadata.version}/${config.metadata.discovery}`,
clientID: config.credentials.clientID,
audience: config.credentials.clientID,
issuer: config.credentials.issuer,
policyName: config.policies.policyName,
isB2C: config.settings.isB2C,
scope: config.resource.scope,
validateIssuer: config.settings.validateIssuer,
loggingLevel: config.settings.loggingLevel,
passReqToCallback: config.settings.passReqToCallback
}
// Instantiate the passport Azure AD library with the Azure AD B2C options
const bearerStrategy = new BearerStrategy(options, (token, done) => {
// Send user info using the second argument
done(null, { }, token);
}
);
// Use the required libraries
const app = express();
app.use(morgan('dev'));
app.use(passport.initialize());
passport.use(bearerStrategy);
//enable CORS (for testing only -remove in production/deployment)
app.use((req, res, next) => {
res.header('Access-Control-Allow-Origin', '*');
res.header('Access-Control-Allow-Headers', 'Authorization, Origin, X-Requested-With, Content-Type, Accept');
next();
});
Add two endpoints to your web API:
- Anonymous
/public
endpoint. This endpoint returns the current date and time. Use it to debug your web API with anonymous calls. - Protected
/hello
endpoint. This endpoint returns the value of thename
claim within the access token.
To add the anonymous endpoint:
In the app.js file, add the following JavaScript code:
// API anonymous endpoint
app.get('/public', (req, res) => res.send( {'date': new Date() } ));
To add the protected endpoint:
In the app.js file, add the following JavaScript code:
// API protected endpoint
app.get('/hello',
passport.authenticate('oauth-bearer', {session: false}),
(req, res) => {
console.log('Validated claims: ', req.authInfo);
// Service relies on the name claim.
res.status(200).json({'name': req.authInfo['name']});
}
);
The /hello
endpoint first calls the passport.authenticate()
function. The authentication function limits access to authenticated users only.
The authentication function also verifies that the web API is called with the right scopes. The allowed scopes are located in the configuration file.
In a development environment, set the web API to listen on incoming HTTP or HTTPS requests port number. In this example, use HTTP port 6000 and HTTPS port 6001. The base URI of the web API will be http://localhost:6000
for HTTP and https://localhost:6001
for HTTPS.
Add the following JavaScript code to the app.js file. It's possible to setup HTTP and HTTPS endpoints for the Node application.
// Starts listening on port 6000
const port = process.env.PORT || 6000;
app.listen(port, () => {
console.log('Listening on port ' + port);
});
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.json file, and then add it to the following JSON snippet:
{
"credentials": {
"tenantName": "<your-tenant-name>.partner.onmschina.cn",
"clientID": "<your-webapi-application-ID>",
"issuer": "https://<your-tenant-name>.b2clogin.cn/<your-tenant-ID>/v2.0/"
},
"policies": {
"policyName": "b2c_1_susi"
},
"resource": {
"scope": ["tasks.read"]
},
"metadata": {
"discovery": ".well-known/openid-configuration",
"version": "v2.0"
},
"settings": {
"isB2C": true,
"validateIssuer": true,
"passReqToCallback": false,
"loggingLevel": "info"
}
}
In the config.json file, update the following properties:
Section | Key | Value |
---|---|---|
credentials | tenantName | Your Azure AD B2C tenant name/domain name (for example, contoso.partner.onmschina.cn ). |
credentials | clientID | The web API application ID. In the preceding diagram, it's the application with App ID: 2. To learn how to get your web API application registration ID, see Prerequisites. |
credentials | issuer | The token issuer iss claim value. By default, Azure AD B2C returns the token in the following format: https://<your-tenant-name>.b2clogin.cn/<your-tenant-ID>/v2.0/ . Replace <your-tenant-name> with the first part of your Azure AD B2C tenant name. Replace <your-tenant-ID> with your Azure AD B2C tenant ID. |
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. To learn how to get your web API scope, see Prerequisites. |
Finally, run the web API with your Azure AD B2C environment settings.
In the command shell, start the web app by running the following command:
node app.js
You should see the following output, which means that your app is up and running and ready to receive requests.
Example app listening on port 6000!
To stop the program, in the command shell, select Ctrl+C. You can rerun the app by using the node app.js
command.
Tip
Alternatively, to run the node app.js
command, use the Visual Studio Code debugger. Visual Studio Code's built-in debugger helps accelerate your edit, compile, and debug loop.
Open a browser and go to http://localhost:6000/public
. In the browser window, you should see the following text displayed, along with the current date and time.
Try to call the protected web API endpoint without an access token. Open a browser and go to http://localhost:6000/hello
. The API returns an unauthorized HTTP error message, confirming that web API is protected with a bearer token.
Continue to configure your app to call the web API. For guidance, see the Prerequisites section.
Get the complete example in GitHub:
- Get the web API by using the Passport.js library.