Compartir a través de

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

本文使用一个示例 Python Web 应用程序来说明如何向 Web 应用程序添加 Azure Active Directory B2C (Azure AD B2C) 身份验证。

概述

OpenID Connect (OIDC) 是在 OAuth 2.0 上构建的身份验证协议。 可以使用 OIDC 安全地将用户登录到应用程序。 此 Web 应用示例使用适用于 Python 的标识包来简化向 Python Web 应用添加身份验证和授权支持的过程。

登录流涉及以下步骤:

  1. 用户前往 Web 应用,并选择“登录”。
  2. 应用发起身份验证请求,并将用户重定向到 Azure AD B2C。
  3. 用户注册或登录重置密码,或使用社交帐户登录。
  4. 用户成功登录后,Azure AD B2C 向应用返回 ID 令牌。
  5. 应用使用 ID 令牌交换授权代码、验证 ID 令牌、读取声明,然后向用户返回安全页。

先决条件

步骤 1:配置用户流

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

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

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

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

步骤 2:注册 Web 应用

若要让应用程序使用 Azure AD B2C 登录,请在 Azure AD B2C 目录中注册应用。 注册应用会在应用与 Azure AD B2C 之间建立信任关系。

在应用注册过程中,要指定重定向 URI。 重定向 URI 是用户通过 Azure AD B2C 完成身份验证之后 Azure AD B2C 将用户重定向到的终结点。 此应用注册过程会生成应用程序 ID(也称为“客户端 ID”),作为该应用的唯一标识。 注册应用后,Azure AD B2C 将使用应用程序 ID 和重定向 URI 来创建身份验证请求。

步骤 2.1:注册应用

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

  1. 登录 Azure 门户

  2. 如果有权访问多个租户,请选择顶部菜单中的“设置”图标,从“目录 + 订阅”菜单中切换到你的 Azure AD B2C 租户。

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

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

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

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

  7. 在“重定向 URI”下,选择“Web”,然后在 URL 框中输入 http://localhost:5000/getAToken

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

  9. 选择“注册” 。

  10. 选择“概述”。

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

    用于记录 Web 应用 ID 的 Web 应用“概述”页的屏幕截图。

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

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

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

步骤 3:获取 Web 应用示例

下载 zip 文件,或从 GitHub 克隆示例 Web 应用。

git clone https://github.com/Azure-Samples/ms-identity-python-webapp.git

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

步骤 4:配置示例 Web 应用

在项目的根目录中,执行以下步骤:

  1. 使用 .env.sample 作为指导,在项目的根文件夹中创建 .env 文件。

    FLASK_DEBUG=True
    B2C_TENANT_NAME=<tenant name>
    CLIENT_ID=<client id>
    CLIENT_SECRET=<client secret>
    SIGNUPSIGNIN_USER_FLOW=B2C_1_signupsignin1
    EDITPROFILE_USER_FLOW=B2C_1_profile_editing
    RESETPASSWORD_USER_FLOW=B2C_1_reset_password
    
    B2C_TENANT_NAME Azure AD B2C 租户名称的第一部分(例如 contoso)。
    CLIENT_ID 步骤 2.1 中的 Web API 应用 ID。
    CLIENT_SECRET 步骤 2.2 中创建的客户端密码值。
    *_USER_FLOW 步骤 1 中创建的用户流。

    环境变量在 app_config.py 中引用,并保存在单独的 .env 文件中,以使其不受源代码管理。 提供的 .gitignore 文件会阻止签入 .env 文件。

步骤 5:运行示例 Web 应用

  1. 在控制台或终端中,切换到包含示例的目录。 例如:

    cd ms-identity-python-webapp
    
  2. 运行以下命令,来从 PyPi 安装所需的包,并在本地计算机上运行 Web 应用:

    python -m pip install -r requirements.txt
    python -m flask run --host localhost --port 5000
    

    控制台窗口显示本地运行的应用程序的端口号:

     * Debug mode: on
       WARNING: This is a development server. Do not use it in a production deployment.
       Use a production WSGI server instead.
     * Running on `http://localhost:5000/` (Press CTRL+C to quit)
    
  3. 若要查看在本地计算机上运行的 Web 应用程序,请转到 http://localhost:5000

  4. 选择“登录”。

    显示登录流的屏幕截图。

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

  6. 身份验证成功后,你会看到显示名称,如下所示:

    显示 Web 应用令牌的显示名称声明的屏幕截图。

步骤 6:调用 Web API

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

  • 步骤 2 中已创建的 Web 应用程序 (Python) 注册。 通过此应用注册,你的应用可使用 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 应用。

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

Authorization: Bearer <access token>

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

步骤 6.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 的屏幕截图。

步骤 6.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. 选择“添加作用域”。

步骤 6.3:授予 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. 从“配置权限”列表中,选择范围,然后复制范围全名。

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

步骤 6.4:配置 Web API

此示例获取一个访问令牌,它具有 Web 应用可对 Web API 使用的相关范围。 此示例本身不充当 Web API。 相反,必须使用现有的 Web API 或新建一个。 有关在 B2C 租户中创建 Web API 的教程,请参阅使用 Azure AD B2C 在自己的 Web API 中启用身份验证

步骤 6.5:使用 Web API 配置示例应用

打开 app_config.py 文件。 此文件包含有关 Azure AD B2C 标识提供者的信息。 更新应用设置的以下属性:

ENDPOINT Web API 的 URI(例如 https://localhost:6000/hello)。
SCOPE 你创建的 Web API 范围(例如 ["https://contoso.partner.onmschina.cn/tasks-api/tasks.read", https://contoso.partner.onmschina.cn/tasks-api/tasks.write"])。

步骤 6.6:运行示例应用

  1. 在控制台或终端中,切换到包含示例的目录。

  2. 如果应用仍未运行,请使用步骤 5 中的命令重启。

  3. 选择“调用下游 API”。

    显示如何调用 Web API 的屏幕截图。

步骤 7:部署应用程序

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

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

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