在 SPfx 应用程序中获取用户事件的 Microsoft GraphAPI 403 错误
Microsoft GraphAPI 403 error getting users' events in SPfx app
我使用 Microsoft GraphAPI 编写了一个托管在 SharePoint Online 上的 SharePoint SPfx 应用程序来获取用户配置文件信息和日历事件。根据微软文档,我在 package-solution.json 文件中声明了我的范围,并通过 SharePoint APi 管理页面批准了请求。我能够读取每个人的个人资料信息,但是,当我尝试访问我自己的日历事件时,出现错误 403。用户的日历不是私有的,它们对整个组织开放。
包-solution.json权限请求
"webApiPermissionRequests": [
{
"resource": "Microsoft Graph",
"scope": "User.Read"
},
{
"resource": "Microsoft Graph",
"scope": "User.ReadBasic.All"
},
{
"resource": "Microsoft Graph",
"scope": "People.Read"
},
{
"resource": "Microsoft Graph",
"scope": "Calendars.Read"
}
]
}
管理员批准请求图片
Screen of approved app permissions
请求代码:
private _searchUserCalendar(keyword: string): Promise<any[]> {
console.log("connection to GraphAPI event domain")
return new Promise<any[]>((resolve, reject) => {
this._context.msGraphClientFactory.getClient()
.then((client: MSGraphClient): void => {
client
.api(`/users/${keyword}/calendar/events`) // The api i.e> /me | /users
.version('v1.0')
.select("showAs,start,subject, end")
.top(5)
.get((error, response: any, rawResponse?: any) => {
if (error) {
console.log("ooops somethign went wrong get events",error);
reject(error);
}
var users:Array<any>=new Array<any>();
// Map the JSON response to the output array
if (response != null && response != undefined) {
console.log(response);
response.value.map((item: any) => {
console.log("found events for:", item)
}); // mapping over users
}
resolve(users);
});
});
});
}
错误响应
{error: {code: "ErrorAccessDenied", message: "Access is denied. Check credentials and try again.",…}}
error: {code: "ErrorAccessDenied", message: "Access is denied. Check credentials and try again.",…}
code: "ErrorAccessDenied"
message: "Access is denied. Check credentials and try again."
innerError: {request-id: "5dca3d4f-ab4c-4237-8ff4-78d8cacbd43b", date: "2020-01-16T19:05:26"}
request-id: "5dca3d4f-ab4c-4237-8ff4-78d8cacbd43b"
date: "2020-01-16T19:05:26"
我已经尝试了所有方法,如有任何帮助,我们将不胜感激。
- 我在 Graph Explorer 上测试了我的请求,效果很好
- 我uninstalled/re-installed 应用程序
- 我拒绝并重新批准了 API 管理仪表板上的权限请求
- 我将请求 URL 从使用用户 ID 更改为使用电子邮件(仅适用于我的个人资料,但仍然不适用于其他任何人)
- 我让用户与我共享他们的日历并授予 read/write 权限,但仍然没有用,因为该权限是特定于应用程序而不是用户委派的。
User.Read
和 User.ReadBasic.All
没有权限执行您想要执行的操作。
这个URL讨论日历阅读共享事件。
As an example, Garth has shared with John his default calendar and given John read access. If John has signed into your app and provided delegated permissions (Calendars.Read.Shared or Calendars.ReadWrite.Shared), your app will be able to access Garth's default calendar and events in that calendar as described below.
你可以尝试添加 Calendar.Read.Shared
在尝试了不同的权限范围(包括@chad 建议的范围)之后,Calendar.Read.Shared 似乎奏效了。但是,它之所以有效,是因为它是一种委派权限,用户必须隐式地与整个组织或登录用户共享他们的日历。这是误导性的,并且与我在找到的 graphAPI 文档中读到的内容相反
here 在“日历”>“应用程序”权限下:
Calendars.Read | Read calendars in all mailboxes Allows the app to read
events of all calendars without a signed-in user.
...和
Calendars.Read.Shared | Read user and shared calendars Allows the app
to read events in all calendars that the user can access, including
delegate and shared calendars.
因此,根据前面的陈述,我只需要 Calendars.Read 即可读取该用户创建的用户日历中的所有事件。使用 Calendars.Read.Shared 的逻辑也是读取用户共享的所有事件,包括那些未创建但与用户共享的事件。
最后,我将其标记为已回答,因为它是唯一对我有用的东西(某种程度上),而不是因为它解决了原始问题。有关此主题的文档自相矛盾且令人困惑。现在这是我的答案,除非微软改变了一些东西或澄清了这个问题,或者你发现了其他东西 or/and 我的逻辑是有缺陷的。如果我的逻辑和理解有问题,请 post 回复并告诉我。毕竟,这就是社区的目的。
谢谢
我使用 Microsoft GraphAPI 编写了一个托管在 SharePoint Online 上的 SharePoint SPfx 应用程序来获取用户配置文件信息和日历事件。根据微软文档,我在 package-solution.json 文件中声明了我的范围,并通过 SharePoint APi 管理页面批准了请求。我能够读取每个人的个人资料信息,但是,当我尝试访问我自己的日历事件时,出现错误 403。用户的日历不是私有的,它们对整个组织开放。
包-solution.json权限请求
"webApiPermissionRequests": [
{
"resource": "Microsoft Graph",
"scope": "User.Read"
},
{
"resource": "Microsoft Graph",
"scope": "User.ReadBasic.All"
},
{
"resource": "Microsoft Graph",
"scope": "People.Read"
},
{
"resource": "Microsoft Graph",
"scope": "Calendars.Read"
}
]
}
管理员批准请求图片
Screen of approved app permissions
请求代码:
private _searchUserCalendar(keyword: string): Promise<any[]> {
console.log("connection to GraphAPI event domain")
return new Promise<any[]>((resolve, reject) => {
this._context.msGraphClientFactory.getClient()
.then((client: MSGraphClient): void => {
client
.api(`/users/${keyword}/calendar/events`) // The api i.e> /me | /users
.version('v1.0')
.select("showAs,start,subject, end")
.top(5)
.get((error, response: any, rawResponse?: any) => {
if (error) {
console.log("ooops somethign went wrong get events",error);
reject(error);
}
var users:Array<any>=new Array<any>();
// Map the JSON response to the output array
if (response != null && response != undefined) {
console.log(response);
response.value.map((item: any) => {
console.log("found events for:", item)
}); // mapping over users
}
resolve(users);
});
});
});
}
错误响应
{error: {code: "ErrorAccessDenied", message: "Access is denied. Check credentials and try again.",…}}
error: {code: "ErrorAccessDenied", message: "Access is denied. Check credentials and try again.",…}
code: "ErrorAccessDenied"
message: "Access is denied. Check credentials and try again."
innerError: {request-id: "5dca3d4f-ab4c-4237-8ff4-78d8cacbd43b", date: "2020-01-16T19:05:26"}
request-id: "5dca3d4f-ab4c-4237-8ff4-78d8cacbd43b"
date: "2020-01-16T19:05:26"
我已经尝试了所有方法,如有任何帮助,我们将不胜感激。
- 我在 Graph Explorer 上测试了我的请求,效果很好
- 我uninstalled/re-installed 应用程序
- 我拒绝并重新批准了 API 管理仪表板上的权限请求
- 我将请求 URL 从使用用户 ID 更改为使用电子邮件(仅适用于我的个人资料,但仍然不适用于其他任何人)
- 我让用户与我共享他们的日历并授予 read/write 权限,但仍然没有用,因为该权限是特定于应用程序而不是用户委派的。
User.Read
和 User.ReadBasic.All
没有权限执行您想要执行的操作。
这个URL讨论日历阅读共享事件。
As an example, Garth has shared with John his default calendar and given John read access. If John has signed into your app and provided delegated permissions (Calendars.Read.Shared or Calendars.ReadWrite.Shared), your app will be able to access Garth's default calendar and events in that calendar as described below.
你可以尝试添加 Calendar.Read.Shared
在尝试了不同的权限范围(包括@chad 建议的范围)之后,Calendar.Read.Shared 似乎奏效了。但是,它之所以有效,是因为它是一种委派权限,用户必须隐式地与整个组织或登录用户共享他们的日历。这是误导性的,并且与我在找到的 graphAPI 文档中读到的内容相反 here 在“日历”>“应用程序”权限下:
Calendars.Read | Read calendars in all mailboxes Allows the app to read events of all calendars without a signed-in user.
...和
Calendars.Read.Shared | Read user and shared calendars Allows the app to read events in all calendars that the user can access, including delegate and shared calendars.
因此,根据前面的陈述,我只需要 Calendars.Read 即可读取该用户创建的用户日历中的所有事件。使用 Calendars.Read.Shared 的逻辑也是读取用户共享的所有事件,包括那些未创建但与用户共享的事件。
最后,我将其标记为已回答,因为它是唯一对我有用的东西(某种程度上),而不是因为它解决了原始问题。有关此主题的文档自相矛盾且令人困惑。现在这是我的答案,除非微软改变了一些东西或澄清了这个问题,或者你发现了其他东西 or/and 我的逻辑是有缺陷的。如果我的逻辑和理解有问题,请 post 回复并告诉我。毕竟,这就是社区的目的。
谢谢