如何正确获取MS Graph访问令牌?Azure应用令牌调用Office 365报400
解决MS Graph访问令牌获取及调用400错误的问题
你的代码采用**客户端凭据(client_credentials)**模式,令牌无法正常调用邮件API,大概率是以下几个原因导致:
1. 应用权限未正确配置并完成管理员授权
客户端凭据模式要求应用必须配置MS Graph应用权限,且必须由租户管理员完成授权:
- 登录Azure门户,找到你的应用注册
- 进入「API权限」页面,点击「添加权限」→ 选择「Microsoft Graph」→ 选择「应用权限」
- 添加对应邮件权限(如
Mail.Read、Mail.Send,根据实际需求选择) - 点击「授予管理员同意」(这一步必须完成,否则令牌不会包含所需权限)
2. 调用了错误的API端点
你提到的「调用Office 365」可能是使用了旧版Exchange API端点,客户端凭据模式的令牌仅适用于MS Graph官方端点,正确的邮件API端点格式示例:
https://graph.microsoft.com/v1.0/users/{用户ID或邮箱}/messages
3. 验证令牌权限
用JWT解码工具解码你获取的令牌,检查roles字段:
- 如果
roles为空或没有对应的邮件权限,说明权限配置或授权步骤未完成 - 对比MS Graph开发者页面的令牌,后者大概率是**委托权限(delegated)**模式(带有
scp字段),这种模式依赖用户上下文,和客户端凭据模式的权限逻辑完全不同
修正后的完整流程示例
1. 获取令牌(确认参数正确即可复用你的代码)
import requests tenant_id = "xxxxx" CLIENT_ID = "你的应用ID" CLIENT_SECRET = "你的应用密钥" TOKEN_ENDPOINT = f'https://login.microsoftonline.com/{tenant_id}/oauth2/v2.0/token' def get_access_token(): payload = { 'client_id': CLIENT_ID, 'client_secret': CLIENT_SECRET, 'grant_type': 'client_credentials', 'scope': 'https://graph.microsoft.com/.default' } response = requests.post(TOKEN_ENDPOINT, data=payload) if response.status_code == 200: return response.json()['access_token'] else: print('获取令牌失败:') print(response.status_code) print(response.text) return None
2. 调用MS Graph邮件API
def get_user_mail(token, user_email): api_url = f"https://graph.microsoft.com/v1.0/users/{user_email}/messages?$top=10" headers = { "Authorization": f"Bearer {token}" } response = requests.get(api_url, headers=headers) if response.status_code == 200: return response.json() else: print('API调用失败:') print(response.status_code) print(response.text) return None # 调用示例 token = get_access_token() if token: messages = get_user_mail(token, "user@yourdomain.com") print(messages)
额外说明
如果你需要以特定用户的身份访问邮件(而非应用身份访问租户内所有用户邮件),则需要使用授权码模式(Authorization Code Flow),这种模式下回调URL为必填项,流程比客户端凭据模式复杂,但能获取带有用户上下文的令牌。
内容的提问来源于stack exchange,提问作者MTplus
相关产品推荐
相关产品推荐

