【发布时间】:2021-06-15 05:35:07
【问题描述】:
我有一个 Web 应用程序,它允许我使用委派的权限登录我的 OneDrive 帐户,以授权该应用程序代表我浏览我的驱动器文件。我现在正在尝试构建一个需要处理这些文件的服务器端作业,因此需要在管理员同意的情况下授予应用程序权限。
我已按照各种说明来实现此目的,但无论我做什么,我都会不断收到此 403 错误:
令牌中需要存在 scp 或角色声明
我在 Azure 门户中注册的应用程序具有应用程序权限 Files.Read.All,并且我已授予管理员许可。我正在获取我的访问令牌,如下所示:
IConfidentialClientApplication app = ConfidentialClientApplicationBuilder.Create("<client-id>")
.WithClientSecret("<secret>")
.WithAuthority(new Uri("https://login.microsoftonline.com/common"))
var apiUrl = "https://graph.microsoft.com/";
string[] scopes = { $"{apiUrl}.default" };
result = await app.AcquireTokenForClient(scopes).ExecuteAsync();
然后我使用返回的令牌请求"{apiUrl}v1.0/drives/<my-drive-id>/items/<drive-item-id>"
这就是我拒绝访问的地方。显然,API 期望我的令牌具有 roles 声明或 scp 声明。
在阅读this related post on SO 之后,我确实想知道问题是否与我为前端和后端操作使用相同的应用程序注册这一事实有关(因此它具有委托和应用程序权限的混合)但我尝试了仅使用应用程序权限创建一个新的应用程序注册,这是同样的错误。
另外,该帖子表明我应该期望在我的令牌中看到 scp 或 roles 声明(取决于身份验证流程的选择),但我没有得到这些声明。这导致我找到this other SO post,这表明我需要在我的访问令牌中明确包含roles,但roles 并未在应用注册的令牌配置 刀片中列为可选声明.
所以我被困住了。有人可以帮忙吗?
更新 1
我现在尝试使用 POST 到 https://login.microsoftonline.com/<tenant-id>/oauth2/v2.0/token 和包含 grant_type=client_credentials 的表单正文手动构建身份验证请求,现在我发现在令牌中返回了 roles 声明。所以我猜ConfidentialClientApplicationBuilder 并没有像我想象的那样构建客户端凭据身份验证请求。但是,当我使用此令牌对驱动器项目发出上述 Graph API 请求时,我收到错误:
租户没有 SPO 许可证
当我在被告知使用 common 而不是我的租户 ID 之前遇到此问题时。但是,当我在这种情况下进行更改时,我再次留下了一个没有角色声明的令牌。
【问题讨论】:
-
(1) 登录用户是否具有访问上述资源的必要权限?使用jwt.ms 进行检查并验证 scp/权限 (2) 确保您在 Onedrive for Business 或您拥有有效许可证的资源中测试上述场景。
-
这是个人 OneDrive,并且使用的是未委托的应用程序权限,因此在这种情况下登录的用户不相关
标签: c# microsoft-graph-api onedrive