使用Azure Access Token与SimpleJWT访问Django REST API求助
解决方案:Azure AD + Django SimpleJWT 双重认证配置
Postman 授权配置
由于HTTP标准的Authorization头仅支持单个Bearer Token,无法同时承载两个令牌,可通过以下两种方式传递双Token:
- 方式1:自定义Header拆分令牌
- 将Azure Access Token放在
Authorization头,格式为Bearer <Azure-Token> - 将Django JWT Token放在自定义Header(如
X-Django-Token),格式为Bearer <Django-JWT>或直接填入Token值(取决于Django验证逻辑) - 在Postman的「Headers」标签页手动添加两个头部,或通过环境变量自动填充令牌值
- 将Azure Access Token放在
- 方式2:利用App Service前置认证
若Azure App Service已配置Azure AD身份验证(即App Service先验证Azure Token再转发请求到Django):- 仅在Postman的「Authorization」中选择「Bearer Token」,填入Azure Access Token
- 将Django JWT Token放在自定义Header(如
X-JWT-Token)中传递
Django SimpleJWT 设置调整
1. 自定义认证后端,同时验证双Token
编写继承自SimpleJWT的自定义认证后端,同时校验Azure AD Token和Django JWT的有效性:
# myapp/backends.py from django.contrib.auth.backends import BaseBackend from rest_framework_simplejwt.authentication import JWTAuthentication import jwt from django.conf import settings from django.contrib.auth.models import User class AzureADAndJWTBackend(BaseBackend): def authenticate(self, request, **kwargs): # 验证Django JWT Token jwt_auth = JWTAuthentication() try: user, token = jwt_auth.authenticate(request) except Exception: return None # 验证Azure AD Token(从自定义Header获取) azure_token_header = request.headers.get('X-Azure-Token') if not azure_token_header: return None azure_token = azure_token_header.replace('Bearer ', '') try: # 用Azure公钥验证签名,此处示例简化处理,生产环境需配置公钥 decoded = jwt.decode( azure_token, options={"verify_signature": False}, audience=settings.AZURE_AD_AUDIENCE, issuer=settings.AZURE_AD_ISSUER ) # 额外校验租户ID if decoded.get('tid') != settings.AZURE_AD_TENANT_ID: return None except jwt.InvalidTokenError: return None return user def get_user(self, user_id): try: return User.objects.get(pk=user_id) except User.DoesNotExist: return None
在settings.py中配置认证后端及Azure AD参数:
# settings.py REST_FRAMEWORK = { 'DEFAULT_AUTHENTICATION_CLASSES': [ 'myapp.backends.AzureADAndJWTBackend', 'rest_framework_simplejwt.authentication.JWTAuthentication', ], } # Azure AD配置 AZURE_AD_TENANT_ID = '你的租户ID' AZURE_AD_AUDIENCE = '你的应用受众ID' AZURE_AD_ISSUER = f'https://login.microsoftonline.com/{AZURE_AD_TENANT_ID}/v2.0'
2. 调整SimpleJWT令牌获取位置(可选)
若希望保留Authorization头给Azure Token,让SimpleJWT从自定义Header读取自身令牌:
# myapp/authentication.py from rest_framework_simplejwt.authentication import JWTAuthentication class CustomJWTAuthentication(JWTAuthentication): def get_header(self, request): # 优先从自定义Header获取JWT header = request.META.get('HTTP_X_JWT_TOKEN') if header: return header return super().get_header(request)
更新settings.py中的认证类:
REST_FRAMEWORK = { 'DEFAULT_AUTHENTICATION_CLASSES': [ 'myapp.authentication.CustomJWTAuthentication', ], }
3. App Service前置认证优化(推荐)
若已在Azure Portal为App Service启用Azure AD身份验证:
- App Service会自动拦截并验证Azure Access Token,仅合法请求会转发至Django
- Django无需再处理Azure Token验证,只需专注校验自定义Header中的Django JWT即可
注意事项
- 禁止在单个
Authorization头中放置两个令牌,会导致服务器解析失败 - 生产环境验证Azure Token时,必须使用Azure官方公钥进行签名校验,避免伪造令牌
- 所有API请求必须使用HTTPS,防止令牌被窃取
内容的提问来源于stack exchange,提问作者Sajal Tiwari
相关产品推荐
相关产品推荐

