You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Azure App Service本地开发中使用身份提供商完成身份验证

解决方案:本地开发模拟Azure App Service Entra ID身份验证

针对你的需求,推荐两种可行方案,既能复用云端的身份验证逻辑,又能在本地实现一致的开发体验:

方案一:用MSAL Python实现真实身份验证(推荐)

通过集成MSAL在本地搭建完整的Entra ID登录流程,解析令牌后将用户声明注入到与云端一致的请求头中,业务代码无需修改即可直接使用X-MS-CLIENT-PRINCIPAL-NAME等字段。

步骤说明

  1. 注册Entra ID开发应用:在Entra ID中创建一个应用(可复用云端的应用,或单独创建开发环境应用),获取客户端ID、租户ID、客户端密钥(机密客户端模式),并配置本地重定向URI(如http://localhost:5000/login/callback)。
  2. 集成MSAL中间件:以Flask为例,添加请求前置中间件,在开发环境下通过MSAL完成登录、令牌解析,并注入对应请求头。

代码示例

# 先安装依赖
pip install msal flask
from flask import Flask, redirect, request, session
import msal
import os

app = Flask(__name__)
app.secret_key = os.environ.get("SECRET_KEY", "local-dev-secret")

# Entra ID配置(从环境变量读取,避免硬编码)
CLIENT_ID = os.environ["CLIENT_ID"]
TENANT_ID = os.environ["TENANT_ID"]
AUTHORITY = f"https://login.microsoftonline.com/{TENANT_ID}"
REDIRECT_URI = os.environ.get("REDIRECT_URI", "http://localhost:5000/login/callback")
SCOPE = ["User.Read"]

# 初始化MSAL客户端
msal_client = msal.ConfidentialClientApplication(
    CLIENT_ID,
    authority=AUTHORITY,
    client_credential=os.environ["CLIENT_SECRET"]
)

@app.before_request
def inject_auth_headers():
    # 生产环境直接使用App Service提供的身份验证头
    if os.environ.get("APP_ENV") == "production":
        return
    # 未登录则跳转至Entra ID登录页
    if not session.get("user"):
        return redirect("/login")
    # 将用户声明注入与云端一致的请求头
    user = session["user"]
    request.headers["X-MS-CLIENT-PRINCIPAL-NAME"] = user["username"]
    request.headers["X-MS-CLIENT-PRINCIPAL-ID"] = user["oid"]

@app.route("/login")
def login():
    auth_url = msal_client.get_authorization_request_url(SCOPE, redirect_uri=REDIRECT_URI)
    return redirect(auth_url)

@app.route("/login/callback")
def login_callback():
    code = request.args.get("code")
    token_result = msal_client.acquire_token_by_authorization_code(
        code, scopes=SCOPE, redirect_uri=REDIRECT_URI
    )
    if "error" in token_result:
        return f"登录失败: {token_result['error_description']}", 401
    # 解析ID令牌中的用户声明
    id_claims = token_result["id_token_claims"]
    session["user"] = {
        "username": id_claims["preferred_username"],
        "oid": id_claims["oid"],
        "name": id_claims["name"]
    }
    return redirect("/")

# 业务接口示例:直接读取请求头
@app.route("/api/profile")
def get_profile():
    username = request.headers.get("X-MS-CLIENT-PRINCIPAL-NAME")
    return {"username": username, "message": "访问授权资源成功"}

if __name__ == "__main__":
    app.run(debug=True, port=5000)

方案二:快速模拟身份验证头(适用于本地调试)

如果只是临时调试业务逻辑,无需真实登录流程,可以直接在开发环境注入模拟的用户声明头,通过环境变量控制开关:

@app.before_request
def inject_dev_auth_headers():
    if os.environ.get("APP_ENV") == "development":
        # 模拟用户信息,可通过环境变量切换不同测试用户
        request.headers["X-MS-CLIENT-PRINCIPAL-NAME"] = os.environ.get("DEV_USER_EMAIL", "dev-test@example.com")
        request.headers["X-MS-CLIENT-PRINCIPAL-ID"] = "123e4567-e89b-12d3-a456-426614174000"

关键注意事项

  • 开发环境与生产环境的切换通过APP_ENV环境变量控制,确保生产环境不会触发本地验证逻辑。
  • 若为前后端分离架构,前端需用MSAL.js实现登录,将ID令牌传递给后端,后端解析令牌后注入对应请求头即可。
  • 确保业务代码仅依赖请求头中的声明字段,不耦合环境特定逻辑,保证本地与云端行为一致。

内容的提问来源于stack exchange,提问作者pklaassen

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.25 03:58:17