如何让Entra ID应用永久读取用户已选的任意DriveItem文件?
解决方案:为Entra ID应用授予特定文件的永久读取权限
核心思路
通过用户委托权限完成文件权限向应用服务主体的授予操作,之后应用即可使用自身的客户端凭据令牌(无用户交互)永久读取该文件,完全符合你的业务限制。
步骤1:调整Entra ID应用权限配置
在Entra ID门户中配置应用的两类权限:
- 委托权限:添加
Files.ReadWrite(若涉及SharePoint网站集文件,可替换为Sites.ReadWrite.All),此权限仅在用户首次授权时需要同意,属于用户主动授予的操作,符合权限最小化原则。 - 应用权限:添加
Files.SelectedOperations.Selected,此权限允许应用读取已被明确授予权限的特定文件,避免了过度的全局文件访问权限。
步骤2:用户选择文件后自动授予权限
当用户通过FilePicker SDK选择文件并返回siteId、driveId、itemId后,在后端执行以下操作:
获取应用的服务主体ID:
使用用户的委托accessToken调用Graph API,查询当前应用的服务主体信息:GET /v1.0/servicePrincipals?$filter=appId eq '{你的Entra ID应用ID}'从返回结果中提取
id字段,即为服务主体ID。为应用授予文件读取权限:
同样使用用户的委托accessToken,调用Graph API将文件的读取权限分配给应用服务主体:POST /v1.0/sites/{siteId}/drives/{driveId}/items/{itemId}/permissions Content-Type: application/json { "roles": ["read"], "grantedToIdentities": [ { "application": { "id": "{服务主体ID}", "displayName": "{你的应用名称}" } } ] }此操作必须使用用户的委托令牌执行——只有文件的所有者或拥有共享权限的用户,才能将文件权限授予应用身份。
步骤3:后台任务无交互读取文件
权限授予完成后,后台任务可通过客户端凭据流获取应用令牌,无需用户交互即可读取目标文件:
- 获取应用令牌:
POST /{tenant_id}/oauth2/v2.0/token Content-Type: application/x-www-form-urlencoded grant_type=client_credentials &client_id={你的应用ID} &client_secret={你的应用密钥} &scope=https://graph.microsoft.com/.default - 读取文件内容:
使用获取到的应用令牌调用Graph API:GET /v1.0/sites/{siteId}/drives/{driveId}/items/{itemId}/content
为什么之前的尝试失败?
- 使用应用令牌执行权限授予:应用权限
Files.SelectedOperations.Selected仅允许读取文件,不具备修改文件权限的能力,必须由用户的委托令牌执行授权操作。 - 用户accessToken权限不足:之前使用的
Files.Read.All委托权限仅允许读取文件,无法执行权限授予操作,需要升级为Files.ReadWrite或Sites.ReadWrite.All委托权限。
符合业务限制的验证
- ✅ 未使用过度应用权限:仅用
Files.SelectedOperations.Selected应用权限,无全局文件访问能力。 - ✅ 无需Sites.Selected:无需转移文件到专用网站集,直接对用户选择的文件授权。
- ✅ 无需用户使用开发工具:所有操作通过Web应用流程自动完成,用户仅需正常授权和选择文件。
- ✅ 无需刷新用户令牌:后台任务仅依赖应用自身的客户端凭据,与用户令牌完全解耦。
内容的提问来源于stack exchange,提问作者Dmytro Moskovchenko
相关产品推荐
相关产品推荐

