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

React+Flask应用中AzureAD令牌验证方法求助

Flask后端验证Azure AD令牌的实现方案

核心逻辑概述

你猜的没错,Flask需要验证Azure AD颁发的JWT令牌合法性,核心步骤是:

  • 从微软公开端点拉取Azure AD的公钥,用于验证令牌签名
  • 解析令牌并校验关键字段(签名、过期时间、受众、颁发者等)
  • 给需要保护的API路由添加验证中间件,确保只有合法用户能访问

具体实现步骤

1. 安装依赖

使用Python的JWT验证库简化开发:

pip install pyjwt requests flask-jwt-extended

2. 配置Azure AD参数

从Azure门户的应用注册页面获取以下参数,添加到Flask配置中:

app.config["AZURE_AD_TENANT_ID"] = "你的租户ID"
app.config["AZURE_AD_CLIENT_ID"] = "Flask应用的客户端ID"
app.config["AZURE_AD_ISSUER"] = f"https://login.microsoftonline.com/{app.config['AZURE_AD_TENANT_ID']}/v2.0"
app.config["AZURE_AD_JWKS_URL"] = f"https://login.microsoftonline.com/{app.config['AZURE_AD_TENANT_ID']}/discovery/v2.0/keys"

3. 实现令牌验证逻辑

自定义验证回调,完成签名、字段校验:

import jwt
import requests
from flask import request, abort
from flask_jwt_extended import JWTManager

jwt = JWTManager(app)

# 缓存Azure AD公钥,避免重复请求
def get_azure_ad_public_keys():
    response = requests.get(app.config["AZURE_AD_JWKS_URL"])
    response.raise_for_status()
    return response.json()["keys"]

# 自定义令牌验证逻辑
@jwt.verify_token_loader
def verify_azure_ad_token(jwt_header, jwt_payload):
    # 校验颁发者
    if jwt_payload["iss"] != app.config["AZURE_AD_ISSUER"]:
        abort(401, description="无效的颁发者")
    # 校验受众(必须匹配Flask应用的客户端ID)
    if app.config["AZURE_AD_CLIENT_ID"] not in jwt_payload["aud"]:
        abort(401, description="无效的受众")
    # 校验令牌签名
    public_keys = get_azure_ad_public_keys()
    token = request.headers.get("Authorization").split(" ")[1]  # 注意修正请求头拼写:Authenticaton → Authorization
    for key in public_keys:
        try:
            rsa_key = jwt.algorithms.RSAAlgorithm.from_jwk(key)
            jwt.decode(
                token,
                rsa_key,
                algorithms=["RS256"],
                issuer=app.config["AZURE_AD_ISSUER"],
                audience=app.config["AZURE_AD_CLIENT_ID"]
            )
            return jwt_payload
        except jwt.InvalidSignatureError:
            continue
    abort(401, description="令牌签名验证失败")

4. 保护API路由

给需要认证的路由添加@jwt_required()装饰器:

@app.route("/api/protected", methods=["GET"])
@jwt_required()
def protected_route():
    return {"message": "已通过认证,可访问该资源"}

关键注意事项

  • 请求头拼写修正:你代码里写的Authenticaton是错误的,正确应为Authorization,否则后端无法正确获取令牌
  • 受众匹配:前端请求令牌时,需确保scope包含Flask应用的客户端ID,否则令牌的aud字段不匹配会导致验证失败
  • 公钥缓存:建议给get_azure_ad_public_keys函数添加缓存(比如functools.lru_cache),减少重复请求微软端点的次数
  • 过期校验:pyjwt默认会自动验证令牌的exp字段,无需额外处理

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 09:55:18