Python连接个人OneDrive调用Graph API返回401未授权如何解决?
问题根源与修复方案
1. 核心错误:授权流选择错误
你当前使用的acquire_token_for_client属于客户端凭据流,仅支持Azure AD工作/学校账户,完全不兼容个人微软账户(包括365家庭版订阅关联的个人账户),所以哪怕成功获取到access token也是无效的,调用API必然返回401。
个人本地命令行应用场景优先选择设备码流,无需配置重定向URI,适配命令行交互场景。
2. 权限配置错误
你在Azure门户中如果勾选的是「应用权限」,对个人场景完全无效,个人微软账户仅支持「委托权限」。你需要删除已配置的所有应用权限,仅保留委托权限下的User.Read、Files.Read、Files.Read.All即可。
3. 端点配置错误
你当前调用的https://graph.microsoft.com/v1.0/users是租户用户查询接口,个人账户没有对应租户,该接口无法使用。如果你要读取自己的OneDrive根目录文件,正确端点为https://graph.microsoft.com/v1.0/me/drive/root/children,可根据你需要提取的文件路径调整接口路径。
4. 修复后代码示例
import msal import requests import json config = { "authority": "https://login.microsoftonline.com/consumers", "client_id": "<你的客户端ID>", # 个人场景使用委托权限,直接列出所需权限即可,无需使用.default "scope": ["User.Read", "Files.Read.All"], "endpoint": "https://graph.microsoft.com/v1.0/me/drive/root/children" } # 个人本地应用属于公共客户端,不需要使用机密客户端,也不需要应用密钥 app = msal.PublicClientApplication( config["client_id"], authority=config["authority"] ) result = None # 优先从缓存读取令牌 accounts = app.get_accounts() if accounts: result = app.acquire_token_silent(config["scope"], account=accounts[0]) if not result: # 初始化设备码流,控制台会输出登录地址和验证码,用你的微软账户登录授权即可 flow = app.initiate_device_flow(scopes=config["scope"]) if "user_code" not in flow: raise ValueError(f"设备码流创建失败: {flow.get('error')}") print(flow["message"]) result = app.acquire_token_by_device_flow(flow) if "access_token" in result: graph_data = requests.get( config["endpoint"], headers={'Authorization': 'Bearer ' + result['access_token']}, ).json() print("Graph API调用结果:") print(json.dumps(graph_data, indent=2)) else: print(result.get("error")) print(result.get("error_description")) print(result.get("correlation_id"))
额外注意事项
- 你之前创建的应用密钥(secret)完全不需要使用,个人公共客户端不需要secret,你可以删除Azure中已创建的secret避免泄露风险
- 应用注册时「支持的账户类型」必须选择「任何组织目录中的账户和个人 Microsoft 帐户(例如 Skype、Xbox)」,如果选择仅组织账户也会触发授权错误
- 设备码流不需要配置重定向URI,你不需要额外做相关配置
内容的提问来源于stack exchange,提问作者Rowie
相关产品推荐
相关产品推荐

