使用 Azure Active Directory B2C 在示例 Angular 单页应用程序中配置身份验证

本文使用一个示例 Angular 单页应用程序 (SPA),说明了如何向 Angular 应用添加 Azure Active Directory B2C (Azure AD B2C) 身份验证。

概述

OpenID Connect (OIDC) 是基于 OAuth 2.0 构建的身份验证协议,可用于将用户安全登录到应用程序。 此 Angular 示例使用 MSAL AngularMSAL Browser。 MSAL 是 Microsoft 提供的一个库,可简化向 Angular SPA 添加身份验证和授权支持的过程。

登录流

登录流涉及以下步骤:

  1. 用户打开应用并选择“登录”。
  2. 应用启动身份验证请求,并将用户重定向到 Azure AD B2C。
  3. 用户注册或登录重置密码,或使用社交帐户登录。
  4. 成功登录后,Azure AD B2C 向应用返回一个授权代码。 应用执行以下操作:
    1. 使用授权代码来交换 ID 令牌、访问令牌和刷新令牌。
    2. 读取 ID 令牌声明。
    3. 将访问令牌和刷新令牌存储在内存中的缓存中供以后使用。 访问令牌允许用户调用受保护的资源,例如 Web API。 刷新令牌用于获取新的访问令牌。

应用注册

若要让应用能够使用 Azure AD B2C 登录并调用 Web API,你必须在 Azure AD B2C 租户中注册两个应用程序:

  • 注册单页应用程序 (Angular) 后,你的应用就能够使用 Azure AD B2C 进行登录。 在应用注册过程中,请指定重定向 URI。 重定向 URI 是用户使用 Azure AD B2C 进行身份验证后重定向到的终结点。 此应用注册过程会生成应用程序 ID(也称为“客户端 ID”),作为该应用的唯一标识 。 本文使用示例“应用 ID:1”。

  • 注册 Web API 后,你的应用就能够调用受保护的 Web API。 注册将公开 Web API 权限(范围)。 应用注册过程会生成一个应用程序 ID,作为 Web API 的唯一标识。 本文使用示例“应用 ID:2”。 向应用(应用 ID:1)授予对 Web API 作用域(应用 ID:2)的权限 。

以下关系图描述了应用注册和应用体系结构。

描述具有 Web API、注册和令牌的单页应用程序的关系图。

调用 Web API

身份验证完成后,用户将与应用交互,应用会调用受保护的 Web API。 Web API 使用持有者令牌身份验证。 持有者令牌是应用从 Azure AD B2C 获取的访问令牌。 应用在 HTTPS 请求的授权标头中传递令牌。

Authorization: Bearer <access token>

如果访问令牌范围与 Web API 范围不一致,身份验证库将获取具有正确范围的新访问令牌。

注销流

注销流程涉及以下步骤:

  1. 用户从应用中注销。
  2. 应用清除其会话对象,并且身份验证库清除其令牌缓存。
  3. 应用将用户定向到 Azure AD B2C 注销终结点,以终止 Azure AD B2C 会话。
  4. 用户被重定向回应用。

先决条件

在按照本文中的步骤操作之前,请确保计算机正在运行:

步骤 1:配置用户流

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

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

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

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

步骤 2:注册 Angular SPA 和 API

在此步骤中,你将为 Angular SPA 和 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 应用程序时使用。

    演示如何获取 Web API 应用程序 ID 的屏幕截图。

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 注册 Angular 应用

按照以下步骤创建 Angular 应用注册:

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

2.5 授予权限

若要向应用(应用 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. 从“配置权限”列表中,选择范围,然后复制范围全名。

    已配置权限窗格的屏幕截图,其中显示授予了读取访问权限。

步骤 3:获取 Angular 示例代码

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

下载示例的 .zip 文件,或使用以下命令从 GitHub 存储库克隆示例:

git clone https://github.com/Azure-Samples/ms-identity-javascript-angular-tutorial.git

3.1 配置 Angular 示例

获取 SPA 示例后,请使用 Azure AD B2C 和 Web API 值更新代码。 在示例文件夹的 src/app 文件夹下,打开 auth-config.ts 文件。 使用相应的值更新键:

部分 密钥
b2cPolicies 姓名 你在步骤 1 中创建的用户流或自定义策略。
b2cPolicies authorities your-tenant-name 替换为你的 Azure AD B2C 租户名称。 例如,使用 contoso.partner.onmschina.cn。 然后,将策略名称替换为你在步骤 1 中创建的用户流或自定义策略。 例如:https://<your-tenant-name>.b2clogin.cn/<your-tenant-name>.partner.onmschina.cn/<your-sign-in-sign-up-policy>
b2cPolicies authorityDomain 你的 Azure AD B2C 租户名称。 例如:contoso.partner.onmschina.cn
配置 clientId 步骤 2.3 中的 Angular 应用程序 ID。
protectedResources endpoint Web API 的 URL:http://localhost:5000/api/todolist
protectedResources 范围 你在步骤 2.2 中创建的 Web API 作用域。 例如:b2cScopes: ["https://<your-tenant-name>.partner.onmschina.cn/tasks-api/tasks.read"]

生成的 src/app/auth-config.ts 代码应类似于以下示例:

export const b2cPolicies = {
     names: {
         signUpSignIn: "b2c_1_susi_reset_v2",
         editProfile: "b2c_1_edit_profile_v2"
     },
     authorities: {
         signUpSignIn: {
             authority: "https://your-tenant-name.b2clogin.cn/your-tenant-name.partner.onmschina.cn/b2c_1_susi_reset_v2",
         },
         editProfile: {
             authority: "https://your-tenant-name.b2clogin.cn/your-tenant-name.partner.onmschina.cn/b2c_1_edit_profile_v2"
         }
     },
     authorityDomain: "your-tenant-name.b2clogin.cn"
 };
 
 
export const msalConfig: Configuration = {
     auth: {
         clientId: '<your-MyApp-application-ID>',
         authority: b2cPolicies.authorities.signUpSignIn.authority,
         knownAuthorities: [b2cPolicies.authorityDomain],
         redirectUri: '/', 
     },
    // More configuration here
 }

export const protectedResources = {
  todoListApi: {
    endpoint: "http://localhost:5000/api/todolist",
    scopes: ["https://your-tenant-namee.partner.onmschina.cn/api/tasks.read"],
  },
}

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

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

下载 *.zip 存档,或者从 GitHub 克隆示例 Web API 项目。 还可以使用以下命令直接浏览到 GitHub 上的 Azure-Samples/active-directory-b2c-javascript-nodejs-webapi 项目:

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

4.1 配置 Web API

在示例文件夹中,打开 config.json 文件。 此文件包含有关 Azure AD B2C 标识提供者的信息。 Web API 应用使用此信息来验证访问令牌,该访问令牌由 Web 应用当作持有者令牌传递。 更新应用设置的以下属性:

部分 密钥
凭据 tenantName Azure AD B2C 租户名称的第一个部分。 例如:contoso
凭据 clientID 步骤 2.1 中的 Web API 应用程序 ID。 在上图中,它是使用“应用 ID:2”的应用程序。
凭据 颁发者 (可选)令牌颁发者 iss 声明值。 Azure AD B2C 默认返回采用以下格式的令牌:https://<your-tenant-name>.b2clogin.cn/<your-tenant-ID>/v2.0/。 请将 <your-tenant-name> 替换为你的 Azure AD B2C 租户名称的第一部分。 将 <your-tenant-ID> 替换为你的 Azure AD B2C 租户 ID
策略 policyName 你在步骤 1 中创建的用户流或自定义策略。 如果你的应用程序使用多个用户流或自定义策略,请仅指定一个。 例如,使用注册或登录用户流。
resource scope 步骤 2.5 中的 Web API 应用程序注册的作用域。

你的最终配置文件应类似于下面的 JSON:

{
    "credentials": {
        "tenantName": "<your-tenant-namee>",
        "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"] 
    },
    // More settings here
} 

步骤 5:运行 Angular SPA 和 Web API

你现在可以测试 Angular 对 API 在作用域内的访问权限了。 在此步骤中,请在本地计算机上运行 Web API 和示例 Angular 应用程序。 然后,登录到 Angular 应用程序,并选择“TodoList”按钮来启动对受保护 API 的请求。

运行 Web API

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

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

    npm install && npm update
    node index.js
    

    控制台窗口将显示托管该应用程序的端口号:

    Listening on port 5000...
    

运行 Angular 应用程序

  1. 打开另一个控制台窗口,切换到包含 Angular 示例的目录。 例如:

    cd ms-identity-javascript-angular-tutorial-main/3-Authorization-II/2-call-api-b2c/SPA
    
  2. 运行以下命令:

    npm install && npm update
    npm start
    

    控制台窗口将显示托管该应用程序的端口号:

    Listening on port 4200...
    
  3. 在浏览器中转到 http://localhost:4200,查看此应用程序。

  4. 选择“登录名”。

    屏幕截图显示了带有登录链接的 Angular 示例应用。

  5. 完成注册或登录过程。

  6. 成功登录后,你应该会看到你的个人资料。 从菜单中选择“待办事项列表”。

    屏幕截图显示了 Angular 示例应用,其中包含用户个人资料以及对待办事项列表的调用。

  7. 选择“添加”向列表添加新项,或者使用图标删除或编辑项。

    屏幕截图显示了 Angular 示例应用对待办事项列表的调用。

部署应用程序

在生产应用程序中,应用注册的重定向 URI 通常是运行应用的可公开访问的终结点,比如 https://contoso.com

可以随时在注册的应用程序中添加和修改重定向 URI。 重定向 URI 存在以下限制:

  • 回复 URL 必须以方案 https 开头。
  • 回复 URL 区分大小写。 其大小写必须与正在运行的应用程序的 URL 路径的大小写匹配。

后续步骤