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

使用Flask-Dance对接Azure AD时OAuth认证失败问题排查

解决Flask-Dance + Azure AD OAuth的AADSTS70001错误

这个AADSTS70001错误的核心原因很明确:Azure AD找不到你的应用标识符——说白了就是代码里的CLIENT_ID被解析成了None,导致认证请求里根本没携带正确的应用ID。我帮你梳理几个关键排查和修复步骤:


1. 先确认环境变量是否正确加载

你用os.environ.get()读取CLIENT_ID和CLIENT_SECRET,但如果这两个环境变量没设置,就会返回None,直接触发这个错误。

  • 本地调试时,可以先临时在代码里加个检查,提前发现问题:
    if not CLIENT_ID or not CLIENT_SECRET:
        raise ValueError("请先设置CLIENT_ID和CLIENT_SECRET环境变量!")
    
  • 设置环境变量的方式:
    • Windows:set CLIENT_ID=你的Azure应用客户端ID
    • Linux/macOS:export CLIENT_ID=你的Azure应用客户端ID
      (注意运行应用前要先执行这条命令,或者把环境变量配置到系统/项目的.env文件里)

2. 核对Azure AD应用注册的配置

  • 确保你复制的应用程序(客户端)ID和代码里的CLIENT_ID完全一致,别抄错字符或者大小写。
  • 检查Azure AD应用的重定向URI:Flask-Dance的Azure蓝图默认用/login/azure/authorized作为回调地址,你需要在Azure AD应用注册的「身份验证」页面添加这个URI(比如本地调试用http://localhost:5010/login/azure/authorized)。
  • 替换tenant参数:代码里的"MyTenant"要换成你的Azure AD租户ID(一串GUID)或者租户域名(比如yourcompany.onmicrosoft.com),否则Azure AD不知道该在哪个租户里找你的应用。

3. 修正代码里的小问题

另外你的login_required装饰器里,token过期判断逻辑有点问题——expires_in是剩余有效秒数,应该判断是否<=0,而不是<0。

这里给你整理了修复后的完整代码:

from dash import Dash, html
from werkzeug.middleware.proxy_fix import ProxyFix
from flask import Flask, redirect, url_for
from flask_dance.contrib.azure import azure, make_azure_blueprint
import os


# 先校验环境变量
CLIENT_ID = os.environ.get("CLIENT_ID")
CLIENT_SECRET = os.environ.get("CLIENT_SECRET")

if not CLIENT_ID or not CLIENT_SECRET:
    raise ValueError("请确保已设置CLIENT_ID和CLIENT_SECRET环境变量")

def login_required(func):
    """Require a login for the given view function."""
    def check_authorization(*args, **kwargs):
        # 修正token过期判断逻辑
        if not azure.authorized or (azure.token.get("expires_in", 0) <= 0):
            return redirect(url_for("azure.login"))
        else:
            return func(*args, **kwargs)
    return check_authorization

blueprint = make_azure_blueprint(
    client_id=CLIENT_ID,
    client_secret=CLIENT_SECRET,
    tenant="你的租户ID或域名", # 替换成实际值
    scope=["user.read"],
    redirect_to="/", # 登录成功后跳回Dash主页
)


app = Flask(__name__)
app.config["SECRET_KEY"] = os.environ.get("SECRET_KEY", "dev-secret-key") # 生产环境用环境变量存密钥
app.register_blueprint(blueprint, url_prefix="/login")

dash_app = Dash(__name__, server=app)

app.wsgi_app = ProxyFix(app.wsgi_app, x_proto=1, x_host=1)

# 保护所有非Azure认证相关的视图
for view_func_name in app.view_functions:
    if not view_func_name.startswith("azure"):
        app.view_functions[view_func_name] = login_required(app.view_functions[view_func_name])

dash_app.layout = html.Div(children=[
  html.H1(children='Hello Dash'),
  html.Div(children="You are logged in!")
])

if __name__ == '__main__':
    dash_app.run_server(debug=True, port=5010, host="localhost")

额外注意事项

  • 生产环境绝对不能硬编码CLIENT_ID、CLIENT_SECRET和SECRET_KEY,一定要用环境变量或者安全配置工具管理。
  • 如果应用部署在反向代理(比如Nginx)后面,要确保ProxyFix的参数和代理配置匹配,否则Flask会生成错误的重定向URI。
  • 调试模式只在本地用,上线前务必关闭。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 16:50:16