调用Microsoft Graph API下载OneDrive文件时遇/me请求认证错误
问题解决思路
错误原因
你使用的是应用权限(客户端凭证流)获取token,但调用的/me端点仅支持委托权限(用户授权流)。/me代表当前登录的用户上下文,而应用权限是服务对服务的认证方式,没有绑定具体用户,因此无法识别/me指向的对象。
解决方案
方案1:改用委托权限认证(适合访问特定用户OneDrive场景)
如果你的API需要访问某个具体用户的OneDrive,需切换到委托权限流(如授权码流、用户名密码流),让token关联到具体用户:
- 在Azure AD应用注册中添加委托类型的权限(比如
Files.Read.All),并完成用户/管理员同意。 - 修改获取token的代码(以授权码流为例,需先引导用户登录获取授权码):
from requests_oauthlib import OAuth2Session client_id = '你的客户端ID' redirect_uri = '你的回调地址' scope = ['https://graph.microsoft.com/Files.Read.All'] # 第一步:生成授权URL,引导用户登录授权 oauth = OAuth2Session(client_id, redirect_uri=redirect_uri, scope=scope) authorization_url, state = oauth.authorization_url('https://login.microsoftonline.com/common/oauth2/v2.0/authorize') # 用户访问authorization_url后,会返回授权码code code = '用户授权后回调返回的code' # 第二步:用授权码换取token token = oauth.fetch_token( 'https://login.microsoftonline.com/common/oauth2/v2.0/token', client_secret='你的客户端密钥', code=code )
- 保持原API调用中的
/me端点不变,此时token带有用户上下文,请求会正常执行。
方案2:保持应用权限,修改API端点(适合批量访问租户内用户OneDrive场景)
如果你的API需要以服务身份访问租户内任意用户的OneDrive,需将/me替换为具体用户标识(用户ID或用户主体名称UPN):
- 在Azure AD应用注册中添加应用类型的权限(比如
Files.Read.All),并由管理员完成同意。 - 修改API调用的端点:
file_url = 'onedrive file url' target_user = '目标用户的ID或UPN(如user@yourdomain.com)' # 获取文件元数据的端点 url = f'https://graph.microsoft.com/v1.0/users/{target_user}/drive/root:/Documents/{file_url}:/' headers = { 'Authorization': f'Bearer {access_token}' } response = requests.get(url, headers=headers) if response.status_code == 200: file_id = response.json()['id'] file_name = response.json()['name'] # 下载文件的端点 download_url = f'https://graph.microsoft.com/v1.0/users/{target_user}/drive/items/{file_id}/content' download_response = requests.get(download_url, headers=headers) if download_response.status_code == 200: with open(file_name, 'wb') as f: f.write(download_response.content) print(f'{file_name} 已下载完成')
注意事项
- 确保Azure AD应用注册的权限类型与认证流匹配:应用权限需管理员同意,委托权限需用户或管理员同意。
- 若使用用户名密码流(仅适合内部应用),需确保用户未启用MFA,否则会认证失败。
内容的提问来源于stack exchange,提问作者David
相关产品推荐
相关产品推荐

