使用 Azure Active Directory B2C 在示例 Node.js Web API 中配置身份验证

本文介绍如何配置一个示例 Node.js Web 应用程序以调用示例 Node.js Web API。 该 Web API 需要由 Azure AD B2C 本身提供保护。 在此设置中,某个 Web 应用(例如“应用 ID:1”)将调用某个网络 API(例如“应用 ID:2”)。 用户在该 Web 应用中进行身份验证以获取访问令牌,该令牌随后用于调用受保护的 Web API。

概述

基于令牌的身份验证确保对 Web API 的请求附带有效的访问令牌。

该 Web 应用完成以下事件:

  • 通过 Azure AD B2C 对用户进行身份验证。

  • 获取一个具有对 Web API 终结点的必需权限(作用域)的访问令牌。

  • 在 HTTP 请求的身份验证标头中将该访问令牌作为持有者令牌进行传递。 它使用以下格式:

Authorization: Bearer <token>

该 Web API 完成以下事件:

  • 从 HTTP 请求中的授权标头读取持有者令牌。

  • 验证该令牌。

  • 验证令牌中的权限(作用域)。

  • 响应 HTTP 请求。 如果令牌无效,则 Web API 终结点将以 401 Unauthorized HTTP 错误做出响应。

应用注册概述

要使应用能够通过 Azure AD B2C 登录并调用 Web API,必须在 Azure AD B2C 目录中注册两个应用程序。

  • Web 应用注册能让你的应用使用 Azure AD B2C 登录。 在注册过程中,请指定重定向 URI。 重定向 URI 是用户完成身份验证之后 Azure AD B2C 将用户重定向到的终结点。 此应用注册过程会生成应用程序 ID(也称为“客户端 ID”),将其作为该应用的唯一标识。 你还将为应用生成客户端机密。 应用使用该客户端机密交换访问令牌的授权代码。

  • Web API 注册可使应用调用安全的 Web API。 注册内容包括 Web API 的作用域。 作用域提供了一种方法来管理受保护资源(例如你的 Web API)的访问权限。 你可以向 Web API 的作用域授予 Web 应用访问权限。 在请求访问令牌时,你的应用需要在请求的作用域参数中指定所需的访问权限。

下图描绘了应用程序注册和应用程序体系结构:

Diagram of the application registrations and the application architecture for an app with web A P I.

先决条件

步骤 1:配置用户流

当用户尝试登录你的应用时,该应用会通过用户流向授权终结点发起身份验证请求。 用户流定义并控制用户体验。 用户完成用户流后,Azure AD B2C 会生成一个令牌,然后将用户重定向回应用程序。

创建用户流或自定义策略(如果你尚未这样做)。 重复这些步骤以按如下所述创建三个单独的用户流:

  • 组合的“登录和注册”用户流,例如 susi。 此用户流还支持“忘记密码”体验。
  • “个人资料编辑”用户流,例如 edit_profile
  • “密码重置”用户流,例如 reset_password

Azure AD B2C 将在用户流名称前面追加 B2C_1_。 例如,susi 重命名为 B2C_1_susi

步骤 2:注册 Web 应用和 API

在此步骤中,你将创建 Web 和 Web API 应用程序注册,并指定 Web API 的范围。

步骤 2.1:注册 Web API 应用程序

请按照以下步骤创建 Web API 应用注册(应用 ID: 2):

  1. 登录 Azure 门户

  2. 确保正在使用的目录包含 Azure AD B2C 租户。 在门户工具栏中选择“目录 + 订阅”图标。

  3. 在“门户设置 | 目录+订阅”页上的“目录名称”列表中找到你的 Azure AD B2C 目录,然后选择“切换”。

  4. 在 Azure 门户中,搜索并选择“Azure AD B2C”。

  5. 选择“应用注册”,然后选择“新建注册” 。

  6. 对于名称,请输入应用程序的名称(例如 my-api1) 。 保留“重定向 URI”和“支持的帐户类型”的默认值。

  7. 选择“注册”。

  8. 完成应用注册后,选择“概述”。

  9. 记录“应用程序(客户端) ID”值,以便在稍后配置 Web 应用程序时使用。

    Screenshot that demonstrates how to get a web A P I application I D.

步骤 2.2:配置作用域

  1. 选择所创建的 my-api1 应用程序(应用 ID:2)以打开其“概述”页面 。

  2. 在“管理”下,选择“公开 API” 。

  3. 选择“应用程序 ID URI”旁边的“设置”链接。 将默认值 (GUID) 替换为一个唯一名称(例如“tasks-api”),然后选择“保存”。

    Web 应用在请求 Web API 的访问令牌时,应将此 URI 添加为你为 API 定义的每个范围的前缀。

  4. 在“此 API 定义的范围”下选择“添加范围”。

  5. 若要创建一个用于定义对 API 的读取访问权限的范围,请执行以下操作:

    1. 对于“范围名称”,输入“tasks.read” 。
    2. 对于“管理员同意显示名称”,输入“对任务 API 的读取访问权限” 。
    3. 对于“管理员同意说明”,输入“允许对任务 API 进行读取访问” 。
  6. 选择“添加作用域”。

  7. 选择“添加范围”,然后添加一个用于定义对 API 的写入访问权限的范围:

    1. 对于“范围名称”,输入“tasks.write” 。
    2. 对于“管理员同意显示名称”,“对任务 API 的写入访问权限” 。
    3. 对于“管理员同意说明”,输入“允许对任务 API 进行写入访问” 。
  8. 选择“添加作用域”。

步骤 2.3:注册 Web 应用

要创建 SPA 注册,请执行以下操作:

  1. 登录 Azure 门户
  2. 如果有权访问多个租户,请选择顶部菜单中的“设置”图标,切换到“目录 + 订阅”菜单中的 Azure AD B2C 租户。
  3. 搜索并选择“Azure AD B2C”。
  4. 选择“应用注册”,然后选择“新建注册” 。
  5. 输入应用程序的名称(例如“应用 ID:1”)。
  6. 在“支持的帐户类型”下,选择“任何标识提供者或组织目录中的帐户(用于通过用户流对用户进行身份验证)” 。
  7. 在“重定向 URI”下,选择“Web”,然后在 URL 文本框中输入 http://localhost:3000/redirect
  8. 在“权限”下,选中“授予对 OpenID 和脱机访问权限的管理员许可”复选框。
  9. 选择“注册” 。

步骤 2.4:创建客户端机密

  1. 在“Azure AD B2C - 应用注册”页中,选择你创建的应用程序,例如“应用 ID:1”。
  2. 在左侧菜单中“管理”下,选择“证书和机密”。
  3. 选择“新建客户端机密”。
  4. 在“说明”框中输入客户端机密的说明。 例如,clientsecret1
  5. 在“过期时间”下,选择机密持续生效的时间,然后选择“添加”。
  6. 记录密码的,以便在客户端应用程序代码中使用。 退出此页面后,此机密值永不再显示。 在应用程序的代码中将此值用作应用程序机密。

步骤 2.5:向 Web 应用授予 API 权限

若要向应用(应用 ID:1)授予权限,请执行以下步骤:

  1. 选择“应用注册”,然后选择你所创建的应用(应用 ID:1) 。

  2. 在“管理”下选择“API 权限”。

  3. 在“已配置权限”下,选择“添加权限”。

  4. 选择“我的 API”选项卡。

  5. 选择应授予 Web 应用程序访问权限的 API(应用 ID:2)。 例如,输入“my-api1”。

  6. 在“权限”下展开“任务”,然后选择之前定义的范围(例如,tasks.read 和 tasks.write )。

  7. 选择“添加权限”。

  8. 选择“向<租户名称>授予管理员许可”。

  9. 选择 “是”

  10. 选择“刷新”,然后验证两个范围的“状态”下是否均显示“已授予...” 。

  11. 从“配置权限”列表中,选择范围,然后复制范围全名。

    Screenshot of the configured permissions pane, showing that read access permissions are granted.

步骤 3:获取 Web 应用示例代码

此示例演示 Web 应用程序如何使用 Azure AD B2C 来实现用户注册和登录。 然后,该应用将获取访问令牌并调用受保护的 Web API。

若要获取 Web 应用示例代码,可以执行以下操作之一:

  • 下载 ZIP 文件。 解压缩 zip 文件以获取示例 Web 应用。

  • 通过运行以下命令,从 GitHub 克隆该示例代码:

    git clone https://github.com/Azure-Samples/active-directory-b2c-msal-node-sign-in-sign-out-webapp.git
    

步骤 3.1:安装应用依赖项

  1. 打开控制台窗口,切换到包含 Node.js 示例应用的目录。 例如:

        cd active-directory-b2c-msal-node-sign-in-sign-out-webapp/call-protected-api
    
  2. 运行以下命令以安装应用依赖项:

        npm install && npm update
    

步骤 3.2:配置示例 Web 应用

在代码编辑器(例如 Visual Studio Code)中打开 Web 应用。 打开 call-protected-api 文件夹下的 .env 文件。 此文件包含有关 Azure AD B2C 标识提供者的信息。 更新以下应用设置:

密钥
APP_CLIENT_ID 步骤 2.3 中注册的 Web 应用的“应用程序(客户端) ID”。
APP_CLIENT_SECRET 步骤 2.4 中创建的 Web 应用的客户端密码值
SIGN_UP_SIGN_IN_POLICY_AUTHORITY 步骤 1 中创建的用户流经的“登录和注册”用户流机构(例如 https://<your-tenant-name>.b2clogin.cn/<your-tenant-name>.partner.onmschina.cn/<sign-in-sign-up-user-flow-name>)。 请将 <your-tenant-name> 替换为你的租户的名称,将 <sign-in-sign-up-user-flow-name> 替换为你的“登录和注册”用户流的名称,例如 B2C_1_susi。 了解如何获取租户名称
AUTHORITY_DOMAIN Azure AD B2C 机构域,例如 https://<your-tenant-name>.b2clogin.cn。 将 <your-tenant-name> 替换为租户的名称。
APP_REDIRECT_URI 应用程序重定向 URI,Azure AD B2C 会在其中返回身份验证响应(令牌)。 该 URI 与在 Azure 门户中注册应用时设置的“重定向 URI”匹配。 此 URL 需可公开访问。 将该值保留原样。
LOGOUT_ENDPOINT Azure AD B2C 注销终结点,例如 https://<your-tenant-name>.b2clogin.cn/<your-tenant-name>.partner.onmschina.cn/<sign-in-sign-up-user-flow-name>/oauth2/v2.0/logout?post_logout_redirect_uri=http://localhost:3000。 请将 <your-tenant-name> 替换为你的租户的名称,将 <sign-in-sign-up-user-flow-name> 替换为你的“登录和注册”用户流的名称,例如 B2C_1_susi

更新后,最终配置文件应类似于以下示例:

SERVER_PORT=3000
#web apps client ID
APP_CLIENT_ID=<You app client ID here>
#session secret
SESSION_SECRET=sessionSecretHere
#web app client secret
APP_CLIENT_SECRET=<Your app client secret here>
#tenant name
TENANT_NAME=<your-tenant-name>
#B2C sign up and sign in user flow/policy name and authority
SIGN_UP_SIGN_IN_POLICY_AUTHORITY=https://<your-tenant-name>.b2clogin.cn/<your-tenant-name>.partner.onmschina.cn/<sign-in-sign-up-user-flow-name>
AUTHORITY_DOMAIN=https://<your-tenant-name>.b2clogin.cn
#client redorect url
APP_REDIRECT_URI=http://localhost:3000/redirect
LOGOUT_ENDPOINT=https://<your-tenant-name>.b2clogin.cn/<your-tenant-name>.partner.onmschina.cn/<sign-in-sign-up-user-flow-name>/oauth2/v2.0/logout?post_logout_redirect_uri=http://localhost:3000

步骤 4:获取 Web API 示例代码

注册 Web API 并定义其作用域后,请配置 Web API 代码,使其适用于你的 Azure AD B2C 租户。

若要获取 Web API 示例代码,请执行下列操作之一:

步骤 4.1:更新 Web API

  1. 在代码编辑器中打开 config.json 文件。

  2. 使用前面创建的用户流和应用程序注册修改变量值:

    • 对于 tenantName,请使用你的租户名称,例如 fabrikamb2c

    • 对于 clientID,请使用在步骤 2.1 中创建的 Web API 的“应用程序(客户端) ID”。

    • 对于 policyName,请使用在步骤 1 中创建的“登录和注册”用户流的名称,例如 B2C_1_susi

    更新后,代码应如以下示例所示:

    config.json:

{
    "credentials": {
        "tenantName": "fabrikamb2c",
        "clientID": "93733604-cc77-4a3c-a604-87084dd55348"
    },
    "policies": {
        "policyName": "B2C_1_susi"
    },
    "resource": {
        "scope": ["tasks.read"]
    },
    "metadata": {
        "authority": "login.partner.microsoftonline.cn",
        "discovery": ".well-known/openid-configuration",
        "version": "v2.0"
    },
    "settings": {
        "isB2C": true,
        "validateIssuer": true,
        "passReqToCallback": false,
        "loggingLevel": "info"
    }
}

步骤 4.2:安装应用依赖项

  1. 打开控制台窗口,切换到包含 Node.js Web API 示例的目录。 例如:

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

    npm install && npm update
    

步骤 5:运行 Web 应用和 API

现已准备好测试 Web 应用程序在限定范围内对 Web API 的访问。 在本地计算机上同时运行 Node.js Web API 和示例 Web 应用程序。

  1. 在终端中,导航到示例 Web API 并启动 Node.js Web API 服务器。 例如:

    cd active-directory-b2c-javascript-nodejs-webapi
    node index.js
    

    控制台窗口将显示该应用程序所在的端口号。

    Listening on port 5000...
    
  2. 在另一个终端实例中,导航到示例 Web 应用并启动 Node.js Web 应用服务器。 例如:

        cd active-directory-b2c-msal-node-sign-in-sign-out-webapp/call-protected-api
        node index.js
    

    控制台窗口将显示该应用程序所在的端口号。

    Msal Node Auth Code Sample app listening on port !3000
    
  3. 在浏览器中转到 http://localhost:3000。 应会看到带有以下两个按钮的页面:“登录以调用受保护 API”和“或调用匿名 API”。

    Web page for sign in to call protected A P I.

  4. 若要调用匿名 API,请选择“或调用匿名 API”。 该 API 将以包含 date 键的 JSON 对象做出响应,例如:

        {"date":"2022-01-27T14:21:22.681Z"}
    

    匿名 API 是 Web API 中不受保护的终结点。 无需访问令牌即可访问该终结点。

  5. 若要调用受保护的 API 终结点,请选择“登录以调用受保护 API”按钮。 系统会提示你进行登录。

  6. 输入登录凭据,例如电子邮件地址和密码。 如果没有帐户,请选择“立即注册”创建一个帐户。 成功登录或注册后,应会看到带有“调用受保护 API”按钮的以下页面。

    Web page for signed to call protected A P I.

  7. 若要调用受保护 API,请选择“调用受保护 API”按钮。 该 API 将以包含 name 键的 JSON 对象做出响应,该键的值是你帐户的别名,例如:

        {"name": "User 1"} 
    

后续步骤

了解如何使用 Azure AD B2C 在自己的 Web API 中启用身份验证