教程:使用 Azure AD B2C 保护 Node.js Web API 并授予从单页应用程序访问该 API 的权限Tutorial: Protect and grant access to a Node.js web API from a single-page application with Azure AD B2C

本教程介绍如何从单页应用程序调用受 Azure Active Directory B2C (Azure AD B2C) 保护的 Node.js Web API。This tutorial shows you how to call an Azure Active Directory B2C (Azure AD B2C)-protected Node.js web API from a single-page application.

本教程是由两个部分组成的教程系列的第二部分,将介绍以下操作:In this tutorial, the second in a two-part series:

  • 在 Azure AD B2C 租户中创建 Web API 应用程序注册Create a web API application registration in your Azure AD B2C tenant
  • 配置 Web API 的作用域Configure scopes for the web API
  • 授予 Web API 权限Grant permissions to the web API
  • 修改 Web API 代码示例,使其适用于你的租户Modify a web API code sample to work with your tenant

在本教程系列的第一篇教程中,你已下载代码示例并已对其进行修改,以使用 Azure AD B2C 租户中的用户流将用户登录。In the first tutorial in this series, you downloaded the code sample and modified it to sign in users with a user flow in your Azure AD B2C tenant.

如果没有 Azure 订阅,可在开始前创建一个试用帐户If you don't have an Azure subscription, create a trial account before you begin.

先决条件Prerequisites

添加 Web API 应用程序Add a web API application

Web API 资源需要先在租户中注册,然后才能接受并响应通过提供访问令牌的客户端应用程序所提出的受保护资源请求。Web API resources need to be registered in your tenant before they can accept and respond to protected resource requests by client applications that present an access token.

要在 Azure AD B2C 租户中注册应用程序,可以使用新的统一“应用注册”体验或旧版“应用程序(旧版)”体验 。To register an application in your Azure AD B2C tenant, you can use our new unified App registrations experience or our legacy Applications (Legacy) experience. 详细了解此新体验Learn more about the new experience.

  1. 登录 Azure 门户Sign in to the Azure portal.
  2. 在顶部菜单中选择“目录 + 订阅”筛选器,然后选择包含Azure AD B2C 租户的目录。Select the Directory + subscription filter in the top menu, and then select the directory that contains your Azure AD B2C tenant.
  3. 在左侧菜单中,选择“Azure AD B2C”。In the left menu, select Azure AD B2C. 或者,选择“所有服务”并搜索并选择“Azure AD B2C”。Or, select All services and search for and select Azure AD B2C.
  4. 选择“应用注册”,然后选择“新建注册” 。Select App registrations, and then select New registration.
  5. 输入应用程序的“名称”。Enter a Name for the application. 例如,“webapi1”。For example, webapi1.
  6. 在“重定向 URI”下选择“Web”,然后输入 Azure AD B2C 会将应用程序请求的任何令牌返回到其中的终结点。Under Redirect URI, select Web, and then enter an endpoint where Azure AD B2C should return any tokens that your application requests. 本教程中的示例在本地运行并在 http://localhost:5000 上进行侦听。In this tutorial, the sample runs locally and listens at http://localhost:5000.
  7. 选择“注册”。Select Register.
  8. 记录“应用程序(客户端) ID”,以便在后续步骤中使用。Record the Application (client) ID for use in a later step.

接下来,启用隐式授权流:Next, enable the implicit grant flow:

  1. 在“管理”下,选择“身份验证”。 Under Manage, select Authentication.
  2. 选择“尝试新体验”(如果已显示)。Select Try out the new experience (if shown).
  3. 在“隐式授权”下,选中“访问令牌”和“ID 令牌”复选框 。Under Implicit grant, select both the Access tokens and ID tokens check boxes.
  4. 选择“保存”。Select Save.

配置作用域Configure scopes

可通过作用域控制对受保护资源的访问。Scopes provide a way to govern access to protected resources. Web API 使用作用域实施基于作用域的访问控制。Scopes are used by the web API to implement scope-based access control. 例如,可以让某些用户拥有读取和写入访问权限,让另一些用户拥有只读权限。For example, some users could have both read and write access, whereas other users might have read-only permissions. 在本教程中,你将定义 Web API 的读取和写入权限。In this tutorial, you define both read and write permissions for the web API.

  1. 选择 “应用注册”Select App registrations.
  2. 选择“webapi1”应用程序以打开其“概览”页。Select the webapi1 application to open its Overview page.
  3. 在“管理”下,选择“公开 API” 。Under Manage, select Expose an API.
  4. 选择“应用程序 ID URI”旁边的“设置”链接。 Next to Application ID URI, select the Set link.
  5. 将默认值(一个 GUID)替换为 api,然后选择“保存”。Replace the default value (a GUID) with api, and then select Save. 完整的 URI 已显示,应采用 https://your-tenant-name.partner.onmschina.cn/api 格式。The full URI is shown, and should be in the format https://your-tenant-name.partner.onmschina.cn/api. Web 应用程序在请求 API 的访问令牌时,应将此 URI 添加为你为 API 定义的每个范围的前缀。When your web application requests an access token for the API, it should add this URI as the prefix for each scope that you define for the API.
  6. 在“此 API 定义的范围”下选择“添加范围”。 Under Scopes defined by this API, select Add a scope.
  7. 输入以下值来创建一个定义对 API 的读取访问权限的范围,然后选择“添加范围”:Enter the following values to create a scope that defines read access to the API, then select Add scope:
    1. 范围名称demo.readScope name: demo.read
    2. 管理员许可显示名称Read access to demo APIAdmin consent display name: Read access to demo API
    3. 管理员许可说明Allows read access to the demo APIAdmin consent description: Allows read access to the demo API
  8. 选择“添加范围”,输入以下值来添加一个定义对 API 的写入访问权限的范围,然后选择“添加范围”: Select Add a scope, enter the following values to add a scope that defines write access to the API, and then select Add scope:
    1. 范围名称demo.writeScope name: demo.write
    2. 管理员许可显示名称Write access to demo APIAdmin consent display name: Write access to demo API
    3. 管理员许可说明Allows write access to the demo APIAdmin consent description: Allows write access to the demo API

记下“作用域”下的 demo.read 作用域值,因为稍后在配置单页应用程序的步骤中需要使用该值。 Record the value under Scopes for the demo.read scope to use in a later step when you configure the single-page application. 完整作用域值类似于 https://contosob2c.partner.onmschina.cn/api/demo.readThe full scope value is similar to https://contosob2c.partner.onmschina.cn/api/demo.read.

授予权限Grant permissions

若要从另一应用程序调用受保护的 Web API,需授予应用程序访问该 Web API 的权限。To call a protected web API from another application, you need to grant that application permissions to the web API.

在先决条件教程中,你已创建名为 webapp1 的 Web 应用程序。In the prerequisite tutorial, you created a web application named webapp1. 在本教程中,你要将该应用程序配置为调用在上一部分创建的 Web API:webapi1In this tutorial, you configure that application to call the web API you created in a previous section, webapi1.

  1. 选择“应用注册”,然后选择应该有权访问 API 的 Web 应用程序。Select App registrations, and then select the web application that should have access to the API. 例如,“webapp1”。For example, webapp1.
  2. 在“管理”下选择“API 权限”。Under Manage, select API permissions.
  3. 在“已配置权限”下,选择“添加权限”。Under Configured permissions, select Add a permission.
  4. 选择“我的 API”选项卡。Select the My APIs tab.
  5. 选择应授予 Web 应用程序对其的访问权限的 API。Select the API to which the web application should be granted access. 例如,“webapi1”。For example, webapi1.
  6. 在“权限”下展开“演示”,然后选择前面定义的范围。 Under Permission, expand demo, and then select the scopes that you defined earlier. 例如,demo.readdemo.writeFor example, demo.read and demo.write.
  7. 选择“添加权限”。Select Add permissions.
  8. 选择“向(租户名称)授予管理员许可”。Select Grant admin consent for (your tenant name).
  9. 如果系统提示你选择一个帐户,请选择当前登录的管理员帐户,或者使用至少分配了“云应用程序管理员”角色的 Azure AD B2C 租户中的帐户登录。If you're prompted to select an account, select your currently signed-in administrator account, or sign in with an account in your Azure AD B2C tenant that's been assigned at least the Cloud application administrator role.
  10. 请选择“是”。Select Yes.
  11. 选择“刷新”,然后确认两个范围的“状态”下是否均显示“已授予...”。 Select Refresh, and then verify that "Granted for ..." appears under Status for both scopes.

现在,已经为单页 Web 应用程序授予了在指定作用域内对受保护 Web API 的权限。Your single-page web application has now been granted permissions to the protected web API for the scopes specified. 用户通过 Azure AD B2C 进行身份验证,以使用单页应用程序。A user authenticates with Azure AD B2C to use the single-page application. 该单页应用使用授权流通过 Azure AD B2C 返回的访问令牌访问受保护的 Web API。The single-page app uses the authorization grant flow to access the protected web API with an access token returned by Azure AD B2C.

配置示例Configure the sample

注册 Web API 并定义作用域后,请配置 Web API 代码,使之适用于你的 Azure AD B2C 租户。Now that the web API is registered and you've defined scopes, configure the web API code to work with your Azure AD B2C tenant. 在本教程中,你将配置一个可从 GitHub 下载的示例 Node.js Web API。In this tutorial, you configure a sample Node.js web API you download from GitHub.

下载 *.zip 存档,或者从 GitHub 克隆示例 Web API 项目。Download a *.zip archive or clone the sample web API project from GitHub. 还可以直接浏览到 GitHub 上的 Azure-Samples/active-directory-b2c-javascript-nodejs-webapi 项目。You can also browse directly to the Azure-Samples/active-directory-b2c-javascript-nodejs-webapi project on GitHub.

git clone https://github.com/Azure-Samples/active-directory-b2c-javascript-nodejs-webapi.git

配置 Web APIConfigure the web API

  1. 在代码编辑器中打开 config.js 文件。 Open the config.js file in your code editor.

  2. 修改变量值,以反映前面创建的应用程序注册的值。Modify the variable values to reflect those of the application registration you created earlier. 另外,使用作为先决条件的一部分创建的用户流更新 policyNameAlso update the policyName with the user flow you created as part of the prerequisites. 例如 B2C_1_signupsignin1。 For example, B2C_1_signupsignin1.

    const clientID = "<your-webapi-application-ID>"; // Application (client) ID
    const b2cDomainHost = "<your-tenant-name>.b2clogin.cn";
    const tenantId = "<your-tenant-ID>.partner.onmschina.cn"; // Alternatively, you can use your Directory (tenant) ID (a GUID)
    const policyName = "B2C_1_signupsignin1";
    

启用 CORSEnable CORS

若要允许单页应用程序调用 Node.js Web API,需要在该 Web API 中启用 CORSTo allow your single-page application to call the Node.js web API, you need to enable CORS in the web API. 在生产应用程序中,应密切关注哪个域正在发出请求,但对于本教程,可允许来自任何域的请求。In a production application you should be careful about which domain is making the request, but for this tutorial, allow requests from any domain.

若要启用 CORS,请使用以下中间件。To enable CORS, use the following middleware. 在本教程所述的 Node.js Web API 代码示例中,此中间件已添加到 index.js 文件。 In the Node.js web API code sample in this tutorial, it's already been added to the index.js file.

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();
});

配置单页应用程序Configure the single-page application

本教程系列的前一篇教程中所述的单页应用程序 (SPA) 使用 Azure AD B2C 进行用户注册和登录,并且默认会调用 fabrikamb2c 演示租户保护的 Node.js Web API。 The single-page application (SPA) from the previous tutorial in the series uses Azure AD B2C for user sign-up and sign-in, and by default, calls the Node.js web API protected by the fabrikamb2c demo tenant.

在本部分,你将更新该单页 Web 应用程序,以调用你的 Azure AD B2C 租户保护的 Node.js Web API(在本地计算机上运行)。 In this section, you update the single-page web application to call the Node.js web API protected by your Azure AD B2C tenant (and which you run on your local machine).

若要更改 SPA 中的设置:To change the settings in the SPA:

  1. 在学习上一篇教程时下载或克隆的 active-directory-b2c-javascript-msal-singlepageapp 项目中,打开 JavaScriptSPA 文件夹中的 apiConfig.js 文件。 In the active-directory-b2c-javascript-msal-singlepageapp project you downloaded or cloned in the previous tutorial, open the apiConfig.js file inside the JavaScriptSPA folder.

  2. 使用前面创建的 demo.read 作用域的 URI 以及 Web API 的 URL 配置示例。Configure the sample with the URI for the demo.read scope you created earlier and the URL of the web API.

    1. apiConfig 定义中,将 b2cScopes 值替换为 demo.read 作用域(前面记下的“作用域”值)的完整 URI。 In the apiConfig definition, replace the b2cScopes value with the full URI for the demo.read scope (the Scope value you recorded earlier).
    2. webApi 值中的域更改为在前面的步骤中注册 Web API 应用程序时所添加的重定向 URI。Change the domain in the webApi value to the redirect URI you added when you registered the web API application in an earlier step.

    由于可在 /hello 终结点上访问该 API,因此请保留 URI 中的 /hello。 Because the API is accessible at the /hello endpoint, leave /hello in the URI.

    apiConfig 定义应类似于以下代码块,不过,应将其中的 <your-tenant-name> 替换为你的 B2C 租户名称:The apiConfig definition should look similar to the following code block, but with your B2C tenant's name in the place of <your-tenant-name>:

    // The current application coordinates were pre-registered in a B2C tenant.
    const apiConfig = {
      b2cScopes: ["https://<your-tenant-name>.partner.onmschina.cn/api/demo.read"],
      webApi: "http://localhost:5000/hello" // '/hello' should remain in the URI
    };
    

运行 SPA 和 Web APIRun the SPA and web API

现已准备好测试单页应用程序在限定作用域内对 API 的访问。You're now ready to test the single-page application's scoped access to the API. 在本地计算机上同时运行 Node.js Web API 和示例 JavaScript 单页应用程序。Run both the Node.js web API and the sample JavaScript single-page application on your local machine. 然后登录到该单页应用程序,并选择“调用 API”按钮向受保护的 API 发起请求。 Then, sign in to the single-page application and select the Call API button to initiate a request to the protected API.

尽管在本教程中这两个应用程序都在本地运行,但你已将它们配置使用 Azure AD B2C 进行安全注册/登录并授予对受保护 Web API 的访问权限。Although both applications are running locally when you follow this tutorial, you've configured them to use Azure AD B2C for secure sign-up/sign-in and to grant access to the protected web API.

运行 Node.js Web APIRun the Node.js web API

  1. 打开控制台窗口,切换到包含 Node.js Web API 示例的目录。Open a console window and change to the directory containing the Node.js web API sample. 例如:For example:

    cd active-directory-b2c-javascript-nodejs-webapi
    
  2. 运行以下命令:Run the following commands:

    npm install && npm update
    node index.js
    

    控制台窗口将显示托管该应用程序的端口号。The console window displays the port number where the application is hosted.

    Listening on port 5000...
    

运行单页应用Run the single-page app

  1. 打开另一个控制台窗口,并切换到包含 JavaScript SPA 示例的目录。Open another console window and change to the directory containing the JavaScript SPA sample. 例如:For example:

    cd active-directory-b2c-javascript-msal-singlepageapp
    
  2. 运行以下命令:Run the following commands:

    npm install && npm update
    npm start
    

    控制台窗口将显示该应用程序所在的端口号。The console window displays the port number of where the application is hosted.

    Listening on port 6420...
    
  3. 在浏览器中导航到 http://localhost:6420,查看此应用程序。Navigate to http://localhost:6420 in your browser to view the application.

    浏览器中显示的单页应用程序示例应用

  4. 使用在上一篇教程中所用的电子邮件地址和密码登录。Sign in using the email address and password you used in the previous tutorial. 成功登录后,应会看到 User 'Your Username' logged-in 消息。Upon successful login, you should see the User 'Your Username' logged-in message.

  5. 选择“调用 API” 按钮。Select the Call API button. SPA 将获取 Azure AD B2C 授予的授权,然后访问受保护的 Web API 以显示登录用户的名称:The SPA obtains an authorization grant from Azure AD B2C, then accesses the protected web API to display the name of the logged-in user:

    浏览器中的单页应用程序,其中显示了 API 返回的用户名 JSON 结果

后续步骤Next steps

在本教程中,你已完成以下操作:In this tutorial, you:

  • 在 Azure AD B2C 租户中创建了 Web API 应用程序注册Created a web API application registration in your Azure AD B2C tenant
  • 配置了 Web API 的作用域Configured scopes for the web API
  • 授予了对 Web API 的权限Granted permissions to the web API
  • 修改了 Web API 代码示例,使其适用于你的租户Modified a web API code sample to work with your tenant

了解 SPA 如何从受保护的 Web API 请求资源后,接下来可以更深入地了解这些应用程序类型如何彼此交互以及与 Azure AD B2C 交互。Now that you've seen an SPA request a resource from a protected web API, gain a deeper understanding of how these application types interact with each other and with Azure AD B2C.