在使用 Azure AD B2C 调用 Web API 的示例 Web 应用中配置身份验证

重要

自 2025 年 5 月 1 日起,Azure AD B2C 将不再可供新客户购买。 在我们的常见问题解答中了解详细信息

本文使用调用 Web API 的示例 ASP.NET Web 应用程序来说明如何将 Azure Active Directory B2C (Azure AD B2C) 身份验证添加到 Web 应用程序。

重要

本文中引用的示例 ASP.NET Web 应用用于使用持有者令牌调用 Web API。 对于不调用 Web API 的 Web 应用,请参阅 使用 Azure AD B2C 在示例 Web 应用程序中配置身份验证

概述

OpenID Connect (OIDC) 是在 OAuth 2.0 上构建的身份验证协议。 可以使用 OIDC 安全地将用户登录到应用程序。 此 Web 应用示例使用 Microsoft标识 Web。 Microsoft标识 Web 是一组 ASP.NET 核心库,可简化向可调用安全 Web API 的 Web 应用添加身份验证和授权支持。

登录流涉及以下步骤:

  1. 用户前往 Web 应用,并选择“登录”。

  2. 应用发起身份验证请求,并将用户重定向到 Azure AD B2C。

  3. 用户注册或登录并重置密码。 或者,用户也可以使用社交帐户登录。

  4. 用户成功登录后,Azure AD B2C 向应用返回一个授权代码。

  5. 然后,该应用执行以下作:

    a。 将此授权代码交换到 ID 令牌、访问令牌和刷新令牌。
    b. 它读取 ID 令牌声明,并保留应用程序授权 Cookie。
    选项c. 它将刷新令牌存储在内存中缓存中供以后使用。

应用注册概述

若要让应用能够使用 Azure AD B2C 登录并调用 Web API,你需要在 Azure AD B2C 目录中注册两个应用程序。

  • Web 应用注册能让你的应用使用 Azure AD B2C 登录。 在注册过程中,你需要指定重定向 URI。 重定向 URI 是用户在使用 Azure AD B2C 完成身份验证后,Azure AD B2C 将用户重定向到的终结点。 此应用注册过程会生成应用程序 ID(也称为“客户端 ID”),将其作为该应用的唯一标识。 你还将创建一个客户端密码,你的应用可使用该密码安全地获取令牌。

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

下图演示了应用体系结构和注册:

关系图:使用 Web API 调用注册和令牌的 Web 应用。

调用 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 会生成一个令牌,然后将用户重定向回应用程序。

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

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

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

步骤 2:注册 Web 应用程序

在此步骤中,你将创建 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 应用程序时使用。

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

步骤 2.2:配置 Web API 应用范围

  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 应用

若要创建 Web 应用注册,请执行以下作:

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

  2. “名称”下,输入应用程序的名称(例如 webapp1)。

  3. 在“支持的帐户类型”下,选择“任何标识提供者或组织目录中的帐户(用于通过用户流对用户进行身份验证)”

  4. 在“重定向 URI”下,选择“Web”,然后在 URL 框中输入

  5. 在“权限”下,选中“授予对 OpenID 和脱机访问权限的管理员许可”复选框。

  6. 选择“注册”。

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

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

    屏幕截图:用于记录 Web 应用程序 ID 的 Web 应用概述页。

步骤 2.4:创建 Web 应用客户端密码

为已注册的 Web 应用程序创建客户端密码。 Web 应用程序在请求令牌时使用客户端密码来证明其标识。

  1. 在“管理”下,选择“证书和机密”。
  2. 选择 新客户端密码
  3. 在“说明”框中输入客户端机密的说明(例如 clientsecret1)。
  4. 在“过期时间”下,选择机密持续生效的时间,然后选择“添加”。
  5. 记下机密的“值”。 在稍后的步骤中将使用此值进行配置。

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

若要向应用(应用 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:获取 Web 应用示例

下载 zip 文件,或运行以下 Bash 命令从 GitHub 克隆示例 Web 应用程序。

git clone https://github.com/Azure-Samples/active-directory-aspnetcore-webapp-openidconnect-v2

将示例文件提取到文件夹,该文件夹路径的总字符长度须不得超过 260 个字符。

步骤 4:配置示例 Web API

在示例文件夹中,在 4-WebApp-your-API/4-2-B2C/TodoListService 文件夹中,使用 Visual Studio 或 Visual Studio Code 打开 TodoListService.csproj 项目。

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

部分 密钥 价值
AzureAdB2C 实例 Azure AD B2C 租户名称的第一个部分。 例如,https://contoso.b2clogin.com
AzureAdB2C 域名 Azure AD B2C 租户完整 租户名称。 例如,contoso.onmicrosoft.com
AzureAdB2C ClientId 步骤 2.1 中的 Web API 应用 ID。
AzureAdB2C SignUpSignInPolicyId 步骤 1 中创建的用户流或自定义策略。

最终配置文件应类似于以下 JSON 文件:

{
  "AzureAdB2C": {
    "Instance": "https://contoso.b2clogin.com",
    "Domain": "contoso.onmicrosoft.com",
    "ClientId": "<web-api-app-application-id>",
    "SignedOutCallbackPath": "/signout/<your-sign-up-in-policy>",
    "SignUpSignInPolicyId": "<your-sign-up-in-policy>"
  },
  // More settings here
}

步骤 4.1:设置权限策略

Web API 验证用户是否使用持有者令牌进行身份验证,持有者令牌具有已配置的接受范围。 如果持有者令牌没有任何这些接受的范围,Web API 将返回 HTTP 状态代码 403(禁止),并向响应正文写入一条消息,告知令牌中需要哪些范围。

若要配置接受的范围,请打开 Controller/TodoListController.cs 该类,并设置范围名称,而不使用完整的 URI。

[RequiredScope("tasks.read")]

步骤 4.2:运行示例 Web API 应用

若要允许 Web 应用调用 Web API 示例,请执行以下作来运行 Web API:

  1. 如果请求执行此作,请还原依赖项。
  2. 生成并运行该项目。
  3. 生成项目后,Visual Studio 或 Visual Studio Code 会在浏览器中使用以下地址启动 Web API: https://localhost:44332.

步骤 5:配置示例 Web 应用

在示例文件夹中的文件夹下 4-WebApp-your-API/4-2-B2C/Client ,使用 Visual Studio 或 Visual Studio Code 打开 TodoListClient.csproj 项目。

在项目根文件夹下,打开 appsettings.json 该文件。 此文件包含有关 Azure AD B2C 标识提供者的信息。 Web 应用使用此信息与 Azure AD B2C 建立信任关系、允许用户登录和注销、获取令牌和验证令牌。 更新应用设置的以下属性:

部分 密钥 价值
AzureAdB2C 实例 Azure AD B2C 租户名称的第一部分(例如 https://contoso.b2clogin.com)。
AzureAdB2C 域名 Azure AD B2C 租户的完整租户名称(例如 contoso.onmicrosoft.com)。
AzureAdB2C ClientId 步骤 2.3 中的 Web 应用程序 ID。
AzureAdB2C ClientSecret 步骤 2.4 中的 Web 应用程序机密。
AzureAdB2C SignUpSignInPolicyId 步骤 1 中创建的用户流或自定义策略。
TodoList TodoListScope 步骤 2.5 中创建的 Web API 范围。
TodoList TodoListBaseAddress Web API 的基本 URI(例如 https://localhost:44332)。

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

{
  "AzureAdB2C": {
    "Instance": "https://contoso.b2clogin.com",
    "Domain": "contoso.onmicrosoft.com",
    "ClientId": "<web-app-application-id>",
    "ClientSecret": "<web-app-application-secret>",  
    "SignedOutCallbackPath": "/signout/<your-sign-up-in-policy>",
    "SignUpSignInPolicyId": "<your-sign-up-in-policy>"
  },
  "TodoList": {
    "TodoListScope": "https://contoso.onmicrosoft.com/api/demo.read",
    "TodoListBaseAddress": "https://localhost:44332"
  }
}

步骤 6:运行示例 Web 应用

  1. 生成并运行该项目。
  2. 导航至 https://localhost:5000
  3. 完成注册或登录过程。

身份验证成功后,将在导航栏中看到显示名称。 若要查看 Azure AD B2C 令牌返回到应用的声明,请选择 TodoList

Web 应用令牌声明的屏幕截图。

部署应用程序

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

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

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

Web 应用的令牌缓存

Web 应用示例使用内存中令牌缓存序列化。 此实现在示例中非常出色。 在生产应用程序中,如果重新启动 Web 应用时令牌缓存丢失,则这在生产应用程序中也不错。

对于生产环境,建议使用分布式内存缓存。 例如,Redis 缓存、NCache 或 SQL Server 缓存。 有关分布式内存缓存实现的详细信息,请参阅 令牌缓存序列化

后续步骤