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

PHP网站调用Microsoft Graph API上传OneDrive遭403拒绝的排查方案

问题:PHP上传文件到OneDrive时403权限错误,令牌仅含User.Read权限

我有一个供客户查看发票并上传设计资产的网站,想用PHP表单把文件传到OneDrive,不存储在Web服务器上。已经在Microsoft Azure创建应用,配置了Application (client) ID、Directory (tenant) ID等信息,使用客户端密钥及账号密码获取访问令牌,相关代码如下:

if (isset($_FILES['uploads'])) {
    $guzzle = new \GuzzleHttp\Client();
    $tenantId = 'xxxxxx';
    $clientId = 'xxxxxx';
    $clientSecret = 'xxxxxx';
    $url = 'https://login.microsoftonline.com/' . $tenantId . '/oauth2/token';
    $user_token = json_decode($guzzle->post($url, [
        'form_params' => [
            'client_id' => $clientId,
            'client_secret' => $clientSecret,
            'resource' => 'https://graph.microsoft.com/',
            'grant_type' => 'password',
            'username' => 'xxxxxx@companydomain.com', 
            'password' => 'xxxxxx'
        ],
    ])->getBody()->getContents());
    $user_accessToken = $user_token->access_token;

    $graph = new Graph();
    $graph->setAccessToken($user_accessToken);

    foreach ($_FILES['uploads']['name'] as $key => $name) {
        try {
            $graph->createRequest(
                "PUT", "/drive/root:/Documents/".$_FILES['uploads']['name'][$key].":/content"
            )->upload(
                $_FILES['uploads']['tmp_name'][$key]
            );
        } catch (Exception $e) {
            var_dump($e);
        }
    }
}

尝试上传文件时抛出异常:

Client error: PUT https://graph.microsoft.com/v1.0/drive/root:/Documents/Screen%20Shot%202022-10-30%20at%204.03.44%20PM.png:/content resulted in a 403 Forbidden response

Azure API权限中已授予Files.Read.All、Files.ReadWrite.All和User.Read权限,但检查访问令牌时仅看到"scp": "User.Read",令牌未获取到正确权限,请问如何解决?


解决方案

1. 确认权限已完成管理员同意

Azure中添加的Files.Read.All、Files.ReadWrite.All这类高权限,必须点击API权限页面顶部的授予管理员同意按钮。未完成此操作的话,即使配置了权限,令牌也不会包含这些权限。

2. 在令牌请求中明确指定权限范围

使用password授权类型时,需要在请求的form_params里添加scope参数,明确声明所需权限:

'form_params' => [
    'client_id' => $clientId,
    'client_secret' => $clientSecret,
    'resource' => 'https://graph.microsoft.com/',
    'grant_type' => 'password',
    'username' => 'xxxxxx@companydomain.com', 
    'password' => 'xxxxxx',
    'scope' => 'Files.ReadWrite.All User.Read' // 新增该行指定权限范围
]

注:resource是旧版端点参数,搭配scope可确保请求的权限被纳入令牌。

3. 检查权限类型是否匹配授权模式

当前使用的是password授权(委派模式,以用户身份操作),需确认添加的是委派权限而非应用权限:

  • 上传到用户个人OneDrive,选择委派权限的Files.ReadWrite.All;
  • 上传到应用专属存储(如SharePoint文档库),才用应用权限。

4. 重新验证令牌内容

重新获取令牌后,再次检查scp字段是否包含Files.ReadWrite.All。若仍未出现,可尝试重新生成客户端密钥,或清除应用缓存后再次请求令牌。

5. 确认OneDrive目标路径权限

即使令牌权限正确,也要确保目标文件夹/Documents/对该用户有写入权限,比如企业OneDrive可能存在文件夹权限限制,需验证用户可访问并写入该路径。


内容的提问来源于stack exchange,提问作者Sam Nabi

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 04:05:28