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

Django REST验证Azure JWT令牌无法提取请求头令牌问题

Django REST 框架下 Azure AD JWT 令牌验证实现方案

一、令牌传入的正确写法

官方给出的示例是脱离Web服务上下文的最小功能演示代码,本身不处理HTTP请求逻辑,所以识别不到request对象是正常的。你只需要在Django的视图/中间件/认证类这些能拿到请求对象的位置,先处理请求头再传值即可。
注意前端按OAuth2.0规范传的Authorization头格式为Bearer <实际JWT字符串>,不能直接把整个头的值传入校验方法,必须先剥离Bearer 前缀。
可参考下面的视图实现:

from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status
from azure_ad_verify_token import verify_jwt

# 配置建议统一放到settings.py维护,不要硬编码
AZURE_AD_APP_ID = "你的Azure应用客户端ID"
AZURE_AD_ISSUER = "你的Azure租户令牌签发地址"
AZURE_AD_JWKS_URI = "你的Azure JWKS公钥发现地址"

class AzureAuthProtectedView(APIView):
    def get(self, request):
        # 安全提取授权头,避免KeyError
        auth_header = request.headers.get("Authorization", "")
        if not auth_header.startswith("Bearer "):
            return Response(
                {"detail": "授权头格式非法,需遵循Bearer <token>格式"},
                status=status.HTTP_401_UNAUTHORIZED
            )
        # 截取有效令牌部分
        token = auth_header.split(maxsplit=1)[1].strip()

        try:
            # 传入处理后的令牌完成校验
            token_payload = verify_jwt(
                token=token,
                valid_audiences=[AZURE_AD_APP_ID],
                issuer=AZURE_AD_ISSUER,
                jwks_uri=AZURE_AD_JWKS_URI,
                verify=True,
            )
        except Exception as e:
            return Response(
                {"detail": f"令牌校验失败:{str(e)}"},
                status=status.HTTP_401_UNAUTHORIZED
            )

        # 校验通过后可根据payload里的用户信息做登录、权限判断逻辑
        return Response({"user_claims": token_payload}, status=status.HTTP_200_OK)

二、实现正确性说明与易遗漏配置点

  • 整体流程是正确的:React前端通过MSAL完成授权拿到access token、请求时携带Authorization头、后端提取令牌校验,完全符合OpenID Connect的Bearer令牌认证规范。
  • 几个容易踩的遗漏点:
    • 必须处理Bearer前缀:直接把整个Authorization头的值传入校验方法,会因为令牌格式不合法直接报错,这是最常见的问题。
    • 三个核心配置必须和Azure门户的应用注册配置完全匹配:
      • valid_audiences默认填应用客户端ID即可,如果你的服务暴露了自定义API scope,需要把对应的API应用ID也加入列表
      • issuer地址要和租户类型、令牌版本匹配,B2C租户、普通全球版租户、多租户应用的签发地址格式有差异,填错会直接校验失败
      • jwks_uri要和你使用的用户流(B2C场景)、令牌版本(v1.0/v2.0)对应,不同端点的公钥不通用
    • 必须加异常捕获:令牌过期、签名篡改、aud/iss不匹配时verify_jwt会直接抛出异常,不做捕获的话接口会返回500错误,而不是正确的401状态码。
    • 生产环境建议把校验逻辑封装成DRF自定义认证类,全局配置后不需要在每个视图里重复写提取、校验逻辑,减少冗余代码。
    • JWKS公钥默认会有缓存,不用每次请求都拉取,azure-ad-verify-token库本身已经做了这层处理,不需要额外开发。

三、Python生态常用的JWT/Azure AD验证库推荐

  • PyJWT:生态最通用的JWT基础处理库,灵活度最高,需要自己实现JWKS拉取、公钥缓存、声明校验逻辑,适合有自定义校验规则的场景。
  • msal:微软官方推出的Python身份认证库,除了JWT校验,还支持服务端令牌获取、分布式令牌缓存、证书认证等全流程能力,和Azure生态适配度最高。
  • authlib:兼容OAuth2.0、OpenID Connect全协议的认证库,内置JWT校验、JWKS自动拉取缓存能力,同时支持多家身份提供商,适合做多源登录的系统。
  • django-auth-adfs:专门针对Django生态封装的Azure AD/AD FS集成库,内置DRF认证后端、用户自动映射、组权限同步等能力,Django技术栈使用可以大幅减少重复代码。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 20:36:10