You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Python上传文件至OneDrive失败,报400错误求助

解决OneDrive上传时的BadRequest错误

错误原因分析

你遇到的/me request is only valid with delegated authentication flow错误,核心问题是认证方式不匹配:

  • 你用的是acquire_token_with_client_credentials(客户端凭据流),这是服务到服务的认证模式,没有关联具体用户账户,因此API路径里的/me(代表当前登录用户)无法被识别。
  • 只有委托权限流(比如授权码流)会绑定用户上下文,才能使用/me路径。

解决方案1:上传到指定用户的OneDrive(OneDrive for Business场景)

如果目标是上传到租户内特定用户的OneDrive,直接指定用户ID或邮箱(UPN)即可,无需使用/me:

修改API请求路径:

# 替换{user-id}为目标用户的ID,或用户邮箱(如user@contoso.com)
url = "https://graph.microsoft.com/v1.0/users/{user-id}/drive/root/children/Texto.txt/content"

完整修改后的代码示例:

import adal
import json
import requests

AUTHORITY_URL = 'https://login.microsoftonline.com/{}'.format('TENANT-ID')
CLIENT_ID = 'Client ID'
CLIENT_SECRET = 'Client Secret'  
RESOURCE = 'https://graph.microsoft.com/'

# 获取token(这部分保留)
context = adal.AuthenticationContext(AUTHORITY_URL)
token = context.acquire_token_with_client_credentials(RESOURCE, CLIENT_ID, CLIENT_SECRET)

# 修改URL,指定具体用户
user_id = "目标用户的ID或邮箱"
url = f"https://graph.microsoft.com/v1.0/users/{user_id}/drive/root/children/Texto.txt/content"

file_path = "Texto.txt"
headers = {"Authorization": "Bearer " + token["accessToken"]}

with open(file_path, "rb") as f:
    content = f.read()

response = requests.put(url, data=content, headers=headers)
print(response.text)

注意:这种方式需要你的应用注册时添加应用权限(而非委托权限),比如Files.ReadWrite.All,并且需要租户管理员同意该权限。


解决方案2:使用委托权限流(个人OneDrive或需模拟用户操作场景)

如果是上传到个人OneDrive,或必须以用户身份操作,客户端凭据流不适用,需改用授权码流(委托权限)。另外ADAL已被微软弃用,建议改用MSAL库:

  1. 先安装MSAL:
pip install msal
  1. 示例代码(设备码流,适合无UI环境):
import msal
import requests

CLIENT_ID = "你的客户端ID"
CLIENT_SECRET = "你的客户端密钥"
TENANT_ID = "common"  # 个人OneDrive用common,租户场景填租户ID
AUTHORITY = f"https://login.microsoftonline.com/{TENANT_ID}"
SCOPE = ["https://graph.microsoft.com/Files.ReadWrite"]

# 初始化MSAL客户端
app = msal.ConfidentialClientApplication(
    CLIENT_ID, authority=AUTHORITY, client_credential=CLIENT_SECRET
)

# 设备码流获取token
result = app.acquire_token_by_device_flow(scopes=SCOPE)
if "access_token" in result:
    access_token = result["access_token"]
    # 此时可使用/me路径
    url = "https://graph.microsoft.com/v1.0/me/drive/root/children/Texto.txt/content"
    file_path = "Texto.txt"
    headers = {"Authorization": f"Bearer {access_token}"}
    
    with open(file_path, "rb") as f:
        content = f.read()
    
    response = requests.put(url, data=content, headers=headers)
    print(response.text)
else:
    print(result.get("error"), result.get("error_description"))

说明:

  • 设备码流运行时会输出链接和验证码,用户通过浏览器打开链接输入验证码即可完成授权,适合无界面服务器环境。
  • 应用注册时需添加委托权限(如Files.ReadWrite),个人OneDrive场景无需管理员同意,用户自行授权即可。

权限配置提醒

无论采用哪种方案,都要确保Azure AD应用注册中添加了对应权限:

  • 客户端凭据流:添加应用权限,并请求租户管理员同意
  • 委托权限流:添加委托权限,由用户自行同意

内容的提问来源于stack exchange,提问作者Adrian Noli

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.05 13:20:39