通过Graph API访问特定onedrive目录

我朋友想用我的Onedrive存储图片用于网页展示,为了安全考虑,其Entra应用只能访问特定目录下的图片文件,避免其他目录下的文件泄露。考虑到微软的文档写的那叫一个混乱,研究了一段时间,终于弄明白了,以下是实现步骤。

创建 Entra 应用

打开Microsoft Entra,登录后,点击“EntraID-应用注册”,创建一个应用,无需填写重定向 URI。在重新创建应用后,记录下应用程序(客户端) ID与目录(租户) ID。

接下来进行赋权,打开应用下的“API 权限”,选择”新建权限-Graph API-应用程序权限“,添加“Files.SelectedOperations.Selected”权限。由于该权限默认没有任何文件访问权,但我们在后续的步骤中需要知道onedrive的Drive ID与Item Id,这需要应用可以访问用户文件夹的权限,因此在该步骤需要添加“Files.Read.All”权限,所有步骤完成之后将权限撤回即可。

最后,获得应用的访问令牌(Client Secret)。点击”证书和密码“,创建一个客户端密码,记录下值。

获得 Access Token

请注意Access Token是临时的,由系统自动生成,不是上述所提到的Client Secret,但申请Access Token时需要提供Client Secret。

打开cmd,输入并执行以下命令,获得Access Token:

curl -X POST "https://login.microsoftonline.com/TENANT_ID/oauth2/v2.0/token" -H "Content-Type: application/x-www-form-urlencoded" -d "client_id=CLIENT_ID&client_secret=CLIENT_SECRET&grant_type=client_credentials&scope=https://graph.microsoft.com/.default"

其中,TENANT_ID为租户ID,CLIENT_ID为客户端ID,CLIENT_SECRET为客户端密码。

成功,返回的JSON字符串中包含access_token字段,即为Access Token。

{
"token_type":"Bearer",
"expires_in":3599,
"access_token":"eyJxxxx"
}

获得 OneDrive Drive ID与Item Id

首先你需要知道你要访问的文件夹目录,比如“/Pictures/PublicGallery”。

之后打开cmd发送请求,其中ACCESS_TOKEN为获得的Access Token,USER_EMAIL为账号邮箱,DIRECTORY为你要访问的目录(例如“/Pictures/PublicGallery”)。

curl -H "Authorization: Bearer ACCESS_TOKEN" "https://graph.microsoft.com/v1.0/users/USER_EMAIL/drive/root:Directory"

返回:

{
  "@odata.context": "https://graph.microsoft.com/v1.0/$metadata#Collection(driveItem)/$entity",
  "createdBy": {
    "application": {
      "id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
      "displayName": "Microsoft Graph"
    },
    "user": {
      "email": "user@example.com",
      "id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
      "displayName": "User"
    }
  },
  "createdDateTime": "2026-08-15T11:02:57Z",
  "eTag": "\"{xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx},1\"",
  "id": "[ITEM_ID]",
  "lastModifiedBy": {
    "application": {
      "id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
      "displayName": "Microsoft Graph"
    }
  },
  "lastModifiedDateTime": "2026-08-15T11:02:57Z",
  "name": "ExampleFolder",
  "parentReference": {
    "driveType": "business",
    "driveId": "[DRIVE_ID]",
    "id": "[PARENT_ITEM_ID]",
    "name": "ParentFolder",
    "path": "/drive/root:/ParentFolder",
    "siteId": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
  },
  "webUrl": "https://tenant-my.sharepoint.com/personal/user_domain_com/Documents/ParentFolder/ExampleFolder",
  "cTag": "\"c:{xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx},0\"",
  "fileSystemInfo": {
    "createdDateTime": "2026-08-15T11:02:57Z",
    "lastModifiedDateTime": "2026-08-15T11:02:57Z"
  },
  "folder": {
    "childCount": 1
  },
  "isAuthoritative": false,
  "size": 0
}

以上字段说明:

字段含义用途
id当前文件夹的 DriveItem ID[ITEM_ID],用于访问该文件夹
parentReference.driveId所属 OneDrive 的 Drive ID[DRIVE_ID],用于 Graph API 请求
parentReference.id父目录 ID[PARENT_ITEM_ID],一般不用
webUrl网页访问地址人工查看用

你只需要保存ITEM_IDDRIVE_ID即可。

给应用授权文件夹

发送请求授权,其中,DRIVE_ID为获得的Drive ID,ITEM_ID为获得的Item Id,ACCESS_TOKEN为获得的Access Token,CLIENT_ID为应用的客户端ID。

curl -X POST "https://graph.microsoft.com/v1.0/drives/DRIVE_ID/items/ITEM_ID/permissions" -H "Authorization: Bearer ACCESS_TOKEN" -H "Content-Type: application/json" -d "{\"roles\":[\"read\"],\"grantedTo\":{\"application\":{\"id\":\"CLIENT_ID\"}}}"

成功,将返回的JSON字符串:

{
"id":"xxx",
"roles":[
"read"
],
"grantedTo":{
"application":{
"id":"CLIENT_ID"
}
}
}

撤销 “Files.Read.All”权限

打开Microsoft Entra,点击”应用“,找到应用,点击”API 权限“,撤销“Files.Read.All”权限。

正在加载评论区...