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

Express.js通过Azure传文件至SharePoint遇Unsupported app only token错误

解决SharePoint上传时"Unsupported app only token"错误

问题概述

使用Express.js通过Azure AD的client credentials流获取令牌,调用SharePoint REST API上传文件时,持续收到Unsupported app only token错误。

核心原因

该错误通常由以下情况导致:

  • Azure AD应用权限未正确配置(缺少应用权限或未完成管理员同意)
  • 令牌请求的scope/resource与目标API不匹配
  • 经典SharePoint REST API的URL格式存在语法错误
  • 目标API对应用级令牌支持有限(部分旧API仅支持委托令牌)

分步解决方案

1. 检查Azure AD应用权限配置

  • 登录Azure门户,进入目标应用注册的API权限页面
  • 删除无关的委托权限,添加SharePoint Online的应用权限(注意是「应用权限」而非「委托权限」),推荐选择Sites.ReadWrite.All或Sites.Manage.All
  • 点击授予管理员同意,确保权限状态显示为「已授予」(client credentials流必须依赖管理员批准的应用权限)

2. 修正令牌请求的Scope

若使用经典SharePoint REST API,token请求的scope必须指向你的SharePoint租户URL,格式为https://<你的租户>.sharepoint.com/.default,修正后的代码示例:

async function getAccessToken() {
    const tenantId = "你的租户ID";
    const clientId = "你的客户端ID";
    const clientSecret = "你的客户端密钥";
    const sharePointTenantUrl = "https://contoso.sharepoint.com"; // 替换为实际租户URL

    const tokenEndpoint = `https://login.microsoftonline.com/${tenantId}/oauth2/v2.0/token`;
  
    const requestBody = new URLSearchParams({
      grant_type: "client_credentials",
      client_id: clientId,
      client_secret: clientSecret,
      scope: `${sharePointTenantUrl}/.default` // 修正此处的scope值
    });
  
    try {
        const response = await axios.post(tokenEndpoint, requestBody, {
            headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
          });
          
          return response.data.access_token;
    } catch (error) {
      console.error('Error obtaining token:', error.response.data);
      throw new Error('Failed to obtain access token');
    }
}

3. 修复SharePoint REST API的URL格式

原代码中folderPath和fileName未用单引号包裹,会导致URL语法错误,修正上传代码的URL部分:

async function uploadFileToSharePoint(filePath, fileName, folderPath) {
    const accessToken = await getAccessToken();
    const file = fs.readFileSync(filePath);

    try {
        // 修正URL参数的单引号包裹方式
        const uploadUrl = `${siteUrl}/_api/web/GetFolderByServerRelativeUrl('${folderPath}')/Files/add(url='${fileName}',overwrite=true)`;
        const response = await axios.put(
            uploadUrl,
            file,
            {
                headers: {
                    'Authorization': `Bearer ${accessToken}`,
                    'Accept': 'application/json;odata=verbose',
                    'Content-Type': 'application/octet-stream'
                }
            }
        );

        return response.data.d;
    } catch (error) {
        console.error('Error uploading to SharePoint:', error.response ? error.response.data : error.message);
        throw new Error('File upload to SharePoint failed.');
    }
}

4. (推荐)改用Microsoft Graph API上传

经典SharePoint REST API对应用级令牌的支持有限,改用Microsoft Graph API更稳定可靠:

步骤1:更新令牌请求的Scope

将scope改为https://graph.microsoft.com/.default,并在Azure AD应用中添加Files.ReadWrite.All或Sites.ReadWrite.All的应用权限,完成管理员同意。

步骤2:上传代码示例

async function uploadFileToSharePoint(filePath, fileName, siteId, folderPath) {
    const accessToken = await getAccessToken();
    const file = fs.readFileSync(filePath);

    try {
        const response = await axios.put(
            `https://graph.microsoft.com/v1.0/sites/${siteId}/drive/items/${folderPath}:/${fileName}:/content`,
            file,
            {
                headers: {
                    'Authorization': `Bearer ${accessToken}`,
                    'Content-Type': 'application/octet-stream'
                }
            }
        );
        return response.data;
    } catch (error) {
        console.error('Error uploading via Graph:', error.response ? error.response.data : error.message);
        throw new Error('File upload failed');
    }
}
  • siteId可使用站点URL(如contoso.sharepoint.com/sites/MySite)或<租户ID>,<站点集合ID>,<站点ID>格式
  • folderPath可直接使用文件夹路径(如/Documents/Uploads)

5. 验证令牌有效性

使用jwt.ms解码access token,检查:

  • aud字段是否匹配目标资源(SharePoint租户URL或https://graph.microsoft.com)
  • roles字段是否包含已授予的应用权限(如Sites.ReadWrite.All)
  • 若roles为空,说明权限未正确生效,需重新执行管理员同意步骤

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.17 18:54:54