我朋友想用我的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_ID、DRIVE_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”权限。