教程:使用 Microsoft 标识平台将用户登录到 Python Flask Web 应用

本教程指导你保护 Python Flask Web 应用。

在本教程中,你将:

  • 创建 Python Flask 项目
  • 安装所需的依赖项
  • 将 Flask Web 应用配置为使用Microsoft标识平台进行身份验证
  • 在 Flask Web 应用中测试登录和注销体验

先决条件

  • 工作人员租户。 可以使用 默认目录 或设置新租户。
  • 在 Microsoft Entra 管理中心注册一个新应用,并配置为仅适用于此组织目录中的帐户。 有关更多详细信息 ,请参阅注册应用程序 。 在应用程序 概述 页中记录以下值供以后使用:
    • 应用程序(客户端)ID
    • 目录(租户)ID
  • 将客户端密码添加到应用注册。 不要 在生产应用中使用客户端机密。 请改用证书或联合凭据。 有关详细信息,请参阅 向应用程序添加凭据。

创建 Flask 项目

  1. 创建一个文件夹来托管 Flask 应用程序,例如 flask-web-app。

  2. 打开控制台窗口,并使用命令切换到你的 Flask web 应用程序文件夹所在的目录

    cd flask-web-app
    
  3. 设置虚拟环境

    根据作系统,运行以下命令来设置虚拟环境并激活它:

    对于 Windows 操作系统:

    py -m venv .venv
    .venv\scripts\activate
    

    对于 macOS 或 Linux 操作系统:

    python3 -m venv .venv
    source .venv/bin/activate
    

安装应用依赖项

若要安装应用依赖项,请运行以下命令:

pip install flask
pip install python-dotenv
pip install requests
pip install "ms_identity_python[flask] @ git+https://github.com/azure-samples/ms-identity-python@0.9"

安装 ms_identity_python 库会自动安装用于 Python 的Microsoft身份验证库(MSAL)作为其依赖项。 MSAL Python 是一个库,可用于对用户进行身份验证和管理其访问令牌。

安装所需的库后,运行以下命令更新要求文件:

pip freeze > requirements.txt

配置用于身份验证的应用程序

使用 Microsoft 标识平台登录用户的 Web 应用程序通过配置文件 .env 进行配置。 在 Python Flask 中,它必须指定以下值:

环境变量 Description
AUTHORITY 注册应用程序的云实例的 URL。 格式:https://{Instance}/{TenantId}。 使用以下实例值之一:
- https://login.microsoftonline.com/ (Azure 公有云)
- https://login.partner.microsoftonline.cn/ (由世纪互联运营的Microsoft Entra 中国)
TENANT_ID 注册应用所在租户的标识符。 首选应用注册中的租户 ID,或使用以下项之一:
- organizations:在任何工作或学校帐户中登录用户
- common:用任何工作或学校帐户登录用户
CLIENT_ID 从应用注册获取的应用程序(客户端)的标识符。
CLIENT_SECRET 从 Microsoft Entra 管理中心 中添加凭据 获取的机密值。
REDIRECT_URI Microsoft标识平台在身份验证后发送安全令牌的 URI。

更新配置文件

  1. 在根文件夹中创建 一个 .env 文件,以安全地存储应用的配置。 .env 文件应包含以下环境变量:

    CLIENT_ID="<Enter_your_client_id>"
    CLIENT_SECRET="<Enter_your_client_secret>"
    AUTHORITY="https://login.partner.microsoftonline.cn/<Enter_tenant_id>"
    REDIRECT_URI="<Enter_redirect_uri>"
    

    将占位符替换为以下值:

    • 用<Enter_your_client_id>替换,这是您注册的客户端应用的ID。
    • 将 <Enter_tenant_id> 替换为注册 Web 应用的目录(租户)ID。
    • 将 <Enter_your_client_secret> 替换为您创建的 Web 应用的 客户端机密 值。 在本教程中,我们使用机密进行演示。 在生产环境中,使用更安全的方法,例如 证书或联合标识凭据。
    • 将 <Enter_redirect_uri> 替换为之前注册的重定向 URI。 本教程将重定向 URI 路径设置为 http://localhost:3000/getAToken.
  2. 创建 app_config.py 文件以读取环境变量并添加所需的其他配置。

    import os
    
    AUTHORITY = os.getenv("AUTHORITY")
    CLIENT_ID = os.getenv("CLIENT_ID")
    CLIENT_SECRET = os.getenv("CLIENT_SECRET")
    REDIRECT_URI = os.getenv("REDIRECT_URI")
    SESSION_TYPE = "filesystem" # Tells the Flask-session extension to store sessions in the filesystem. Don't use in production apps.
    

配置应用终结点

在此阶段,将创建 Web 应用终结点并将业务逻辑添加到应用程序。

  1. 在根文件夹中创建名为 app.py 的文件。

  2. 在 app.py 文件的顶部导入所需的依赖项。

    import os
    import requests
    from flask import Flask, render_template
    from identity.flask import Auth
    import app_config
    
  3. 初始化 Flask 应用并将其配置为使用 在 app_config.py 文件中指定的会话存储类型。

    app = Flask(__name__)
    app.config.from_object(app_config)
    
  4. 初始化应用客户端。 Flask Web 应用是机密客户端。 我们传递客户端机密,因为机密客户端可以安全地存储它。 在底层,身份库调用 MSAL 库的ConfidentialClientApplication类。

    auth = Auth(
        app,
        authority=app.config["AUTHORITY"],
        client_id=app.config["CLIENT_ID"],
        client_credential=app.config["CLIENT_SECRET"],
        redirect_uri=app.config["REDIRECT_URI"]
    )
    
  5. 将所需的终结点添加到 Flask 应用。 Web 应用使用授权代码流登录用户。 ms_identity_python MSAL 包装器库有助于与 MSAL 库交互,从而更轻松地将登录和注销添加到应用。 我们添加索引页,并使用login_required库提供的修饰器对其进行保护。 login_required修饰器可确保只有经过身份验证的用户才能访问索引页。

    @app.route("/")
    @auth.login_required
    def index(*, context):
        return render_template(
            'index.html',
            user=context['user'],
            title="Flask Web App Sample",
        )
    

    保证用户会出现,因为我们使用 @login_required装饰了此视图。

创建应用模板

在根文件夹中创建名为 模板 的文件夹。 在模板文件夹中,创建名为 index.html的文件。 这是应用的主页。 将以下代码添加到 index.html 文件:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>{{ title }}</title>
</head>
<body>
    <h1>{{ title }}</h1>
    <h2>Welcome {{ user.get("name") }}!</h2>

    <img src="https://github.com/Azure-Samples/ms-identity-python-webapp-django/raw/main/static/topology.png" alt="Topology">

    <ul>
    {% if api_endpoint %}
        <!-- If an API endpoint is declared and scopes defined, this link will show. We set this in the call an API tutorial. For this tutorial, we do not define this endpoint. -->
        <li><a href='/call_api'>Call an API</a></li>
    {% endif %}

    <li><a href="{{ url_for('identity.logout') }}">Logout</a></li>
    </ul>

    <hr>
    <footer style="text-align: right">{{ title }}</footer>
</body>
</html>

运行并测试示例 Web 应用

  1. 在终端中,运行以下命令:

    python3 -m flask run --debug --host=localhost --port=3000
    

    可以使用所选端口。 此端口应类似于之前注册的重定向 URI 的端口。

  2. 打开浏览器,然后转到 http://localhost:3000。 你会看到一个登录页。

  3. 按照以下步骤使用 Microsoft 帐户登录。 系统会要求你提供登录的电子邮件地址和密码。

  4. 如果应用程序需要任何权限,将会显示同意屏幕。 应用程序将请求权限,以维持对你允许访问的数据的访问权限,并将你登录。 选择 “接受”。 如果未定义作用域,则不会显示此屏幕。

登录或注册后,会重定向回 Web 应用。 你会看到一个类似于以下屏幕截图的页面:

成功身份验证后 flask Web 应用示例的屏幕截图。

选择 注销 以注销应用。 系统会提示你选择要从中注销的帐户。 选择用于登录的帐户。

使用自定义 URL 域(可选)

工作人员租户不支持自定义 URL 域。

参考资料

ms_identity_python抽象化 MSAL 库的详细信息。 有关详细信息,请参阅 MSAL Python 文档。 此参考资料可帮助你了解如何使用 MSAL Python 初始化应用和获取令牌。

后续步骤