OAuth2 Code已被兑换错误及Django Auth ADFS用户信息获取问题
解决“OAuth2 Code已被兑换”及无用户信息问题
为什么Bearer Token中没有用户信息
client_credentials授权模式是应用级别的身份验证,获取的token代表你的Django应用本身,而非具体用户,所以token里不会包含用户个人信息。这种模式适合不需要用户上下文的后台操作,不适合需要用户身份的场景。
解决“OAuth2 Code已被兑换”的方案
因为Django Auth ADFS已经自动完成了code兑换流程,重复使用同一个code会触发微软的防重复兑换机制。你可以通过以下几种方式绕过这个限制:
1. 从Django Auth ADFS获取已兑换的用户token
Django Auth ADFS在完成认证后,会将用户的access token存储在用户会话或相关模型中。你可以直接从库提供的接口获取:
# 从request对象中获取已存储的access token def get_user_access_token(request): if hasattr(request, 'adfs_access_token'): return request.adfs_access_token # 或者从session中读取(取决于库的配置) return request.session.get('adfs_access_token')
拿到这个token后,直接用它调用Microsoft Graph API就能获取用户信息。
2. 配置Django Auth ADFS请求额外的token或权限
修改Django Auth ADFS的配置,让它在认证过程中请求offline_access scope,这样会同时返回refresh token。之后你可以用refresh token去获取新的access token,无需重复使用authorization code:
# settings.py中的ADFS配置 ADFS = { 'CLIENT_ID': '你的客户端ID', 'CLIENT_SECRET': '你的客户端密钥', 'SCOPE': ['openid', 'email', 'profile', 'https://graph.microsoft.com/.default', 'offline_access'], # 其他配置... }
获取refresh token后,调用token端点刷新access token:
def refresh_access_token(refresh_token): token_url = "https://login.microsoftonline.com/你的租户ID/oauth2/v2.0/token" headers = {'Content-Type': 'application/x-www-form-urlencoded'} token_data = { 'grant_type': 'refresh_token', 'refresh_token': refresh_token, 'client_id': '你的客户端ID', 'client_secret': '你的客户端密钥', 'scope': 'https://graph.microsoft.com/.default' } response = requests.post(token_url, headers=headers, data=token_data) return response.json().get('access_token')
3. 让Django Auth ADFS直接返回用户信息
配置Django Auth ADFS的USERINFO_ENDPOINT,让它在认证时自动获取并存储用户信息,这样你无需再调用Graph API:
# settings.py中的ADFS配置 ADFS = { # 其他配置... 'USERINFO_ENDPOINT': 'https://login.microsoftonline.com/你的租户ID/openid/userinfo', 'CLAIM_MAPPING': { 'first_name': 'given_name', 'last_name': 'family_name', 'email': 'email', }, }
之后可以直接从request.user对象中获取用户信息。
内容的提问来源于stack exchange,提问作者Spike Speigel
相关产品推荐
相关产品推荐

