本教程指导你保护 Python Flask Web 应用。
在本教程中,你将:
- 创建 Python Flask 项目
- 安装所需的依赖项
- 将 Flask Web 应用配置为使用Microsoft标识平台进行身份验证
- 在 Flask Web 应用中测试登录和注销体验
- 工作人员租户。 可以使用 默认目录 或设置新租户。
- 在 Microsoft Entra 管理中心注册一个新应用,并配置为仅适用于此组织目录中的帐户。 有关更多详细信息 ,请参阅注册应用程序 。 在应用程序 概述 页中记录以下值供以后使用:
- 应用程序(客户端)ID
- 目录(租户)ID
- 将客户端密码添加到应用注册。 不要 在生产应用中使用客户端机密。 请改用证书或联合凭据。 有关详细信息,请参阅 向应用程序添加凭据。
- Python 3+。
- Visual Studio Code 或其他代码编辑器。
创建一个文件夹来托管 Flask 应用程序,例如 flask-web-app。
打开控制台窗口,并使用命令切换到你的 Flask web 应用程序文件夹所在的目录
cd flask-web-app
设置虚拟环境
根据作系统,运行以下命令来设置虚拟环境并激活它:
对于 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
在根文件夹中创建一个 .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
.
- 用
创建 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 应用终结点并将业务逻辑添加到应用程序。
在根文件夹中创建名为 app.py 的文件。
在 app.py 文件的顶部导入所需的依赖项。
import os import requests from flask import Flask, render_template from identity.flask import Auth import app_config
初始化 Flask 应用并将其配置为使用 在 app_config.py 文件中指定的会话存储类型。
app = Flask(__name__) app.config.from_object(app_config)
初始化应用客户端。 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"] )
将所需的终结点添加到 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>
在终端中,运行以下命令:
python3 -m flask run --debug --host=localhost --port=3000
可以使用所选端口。 此端口应类似于之前注册的重定向 URI 的端口。
打开浏览器,然后转到
http://localhost:3000
。 你会看到一个登录页。按照以下步骤使用 Microsoft 帐户登录。 系统会要求你提供登录的电子邮件地址和密码。
如果应用程序需要任何权限,将会显示同意屏幕。 应用程序将请求权限,以维持对你允许访问的数据的访问权限,并将你登录。 选择 “接受”。 如果未定义作用域,则不会显示此屏幕。
登录或注册后,会重定向回 Web 应用。 你会看到一个类似于以下屏幕截图的页面:
选择 注销 以注销应用。 系统会提示你选择要从中注销的帐户。 选择用于登录的帐户。
工作人员租户不支持自定义 URL 域。
ms_identity_python抽象化 MSAL 库的详细信息。 有关详细信息,请参阅 MSAL Python 文档。 此参考资料可帮助你了解如何使用 MSAL Python 初始化应用和获取令牌。