sharepoint - 通过 Office 插件 (Word JS) 使用 Microsoft Graph 访问 SharePoint
问题描述
我已经开发了一个 Office.js Word 加载项,并且我正在使用此处描述的 SSO 功能。它使用这里所示的Office.Auth interface
方法。这如所描述的那样工作,但是当我尝试使用更多范围来使用 Microsoft Graph 访问 SharePoint 时,问题就出现了。 getAccessTokenAsync
TL;DR
我无法使用从 Office.Auth 接口getAccessTokenAsync
方法生成的令牌成功调用 Microsoft Graph 来访问 SharePoint。
详细描述
我做了以下事情:
- 在 Azure AD 应用注册中添加
Sites.ReadWrite.All
和Sites.Manage.All
权限。 在 Word 加载项清单中添加了其他范围。
<WebApplicationInfo> <Id>$application_GUID here$</Id> <Resource>api://localhost:44355/$application_GUID here$</Resource> <Scopes> <Scope>Files.Read.All</Scope> <Scope>Sites.ReadWrite.All</Scope> <Scope>Sites.Manage.All</Scope> <Scope>offline_access</Scope> <Scope>openid</Scope> <Scope>profile</Scope> </Scopes> </WebApplicationInfo>
使用 Graph Explorer 确认我可以作为我的用户进行 SharePoint Graph 调用。
GET https://graph.microsoft.com/v1.0/sites/{site-id}/lists/{list-id}/items/{item-id}
Authorize
在方法中添加了用户未登录 Word 时的附加范围,如此处所述。ConfidentialClientApplicationBuilder clientBuilder = ConfidentialClientApplicationBuilder.Create(Settings.AzureADClientId); clientBuilder.WithClientSecret(Settings.AzureADClientSecret); clientBuilder.WithRedirectUri(loginRedirectUri.ToString()); clientBuilder.WithAuthority(Settings.AzureADAuthority); ConfidentialClientApplication clientApp = (ConfidentialClientApplication) clientBuilder.Build(); string[] graphScopes = { "Files.Read.All", "User.Read", "Sites.ReadWrite.All", "Sites.Manage.All" }; // Get and save the token. var authResultBuilder = clientApp.AcquireTokenByAuthorizationCode( graphScopes, Request.Params["code"] // The auth 'code' parameter from the Azure redirect. ); try { var authResult = await authResultBuilder.ExecuteAsync(); ViewBag.AccessToken = authResult.AccessToken; } catch (Exception e) { ViewBag.Error = e.Message; } return View();
什么工作
当用户没有登录到 Word 并且必须调用该Authorize
方法时,我可以使用返回的令牌成功地进行我的 Graph 调用。
什么不起作用
当用户已经登录到 Word 并且加载项 JS 使用该getAccessTokenAsync
方法生成令牌时,我在尝试使用返回的进行相同的 Graph 调用时得到“未授权”
问题getAccessTokenAsync
为了让 Office JS方法返回授权令牌以用于我对 SharePoint 的 Graph 调用,
我需要做一些额外的事情吗?
编辑发布进一步调查
我使用jwt.io来解码收到的令牌。
- 使用旧
getAccessTokenAsync
方法登录时(场景不起作用),我得到一个包含以下内容的令牌:
{
"aud": $application_GUID$,
"iss": "https://login.microsoftonline.com/$tenant_GUID$/v2.0",
"iat": ...,
"nbf": ...,
"exp": ...,
"aio": ...,
"azp": ...,
"azpacr": "0",
"name": $user_full_name$,
"oid": $GUID$,
"preferred_username": $user_email$,
"scp": "access_as_user",
"sub": ...,
"tid": $tenant_GUID$,
"uti": ...,
"ver": "2.0"
}
- 使用较新的
getAccessToken
方法,在登录和提示登录时(也不起作用的场景),我得到一个包含与上述相同的令牌。 - 使用较旧的
getAccessTokenAsync
方法,当提示登录并进入AzureADAuthController
, (确实有效的场景! ) 时,我得到一个包含以下内容的令牌:
{
"aud": "00000003-0000-0000-c000-000000000000",
"iss": "https://sts.windows.net/$tenant_GUID$/",
"iat": ...,
"nbf": ...,
"exp": ...,
"acct": 0,
"acr": "1",
"aio": ...,
"amr": [
"pwd"
],
"app_displayname": "Office-Add-in-ASPNET-SSO",
"appid": $application_GUID$,
"appidacr": "1",
"deviceid": $GUID$,
"family_name": $user_last_name$,
"given_name": $user_first_name$,
"ipaddr": ...,
"name": $user_full_name$,
"oid": $GUID$,
"platf": "3",
"puid": ...,
"scp": "Files.Read.All openid profile Sites.Manage.All Sites.ReadWrite.All User.Read email",
"sub": ...,
"tid": $tenant_GUID$,
"unique_name": $user_email$,
"upn": $user_email$,
"uti": ...,
"ver": "1.0",
"xms_st": {
"sub": ...
},
"xms_tcdt": ...
}
请注意范围的差异,后者的旧版本已完全列出范围,我可以通过这种方式进行授权。
这有什么可以解释的?
解决方案
答案不多,但太长了,无法发表评论:
该示例最近更改为使用新的OfficeRuntime.auth.getAccessToken
. 您似乎使用的是旧版本,它使用Office.auth.getAccessTokenAsync
. 这应该仍然有效,但它是一个预览 API,可能会在某个时候停止工作。考虑克隆较新的版本。不过等几天。我即将对新版本进行一些修复。
检查您是否还在graphScopes
Login 操作方法中将新范围添加到数组中。(除了像您已经完成的那样将它们添加到 Authorize 操作方法之外。)
究竟哪个 HTTP 调用返回“未经授权”?
getAccessToken
从(或)返回什么错误getAccessTokenAsync
?它通常有一个 13xxx 号码。
2019 年 12 月 19 日更新:
根据您在评论“澄清...”中的描述,您似乎getAccessToken
在调用 MS Graph 时包含了您从中获得的令牌。这行不通。该令牌是“引导令牌”。它使 Office 可以访问加载项的 Web 应用程序。然后,Web 应用程序需要使用On Behalf Of Flow将该令牌交换为允许 Web 应用程序访问 MS Graph 的令牌。然后,您将第二个令牌作为Authorization标头包含在对 Graph 的调用中。您在问题的第一句话中链接到的示例就是这样做的。另请参阅这些文章:
最后,请确保字符串“Bearer”和 Authorization 标头中的令牌之间有一个空格。
推荐阅读
- mule - 我正在尝试通过骡子从共享点获取文件元数据
- c# - DTO、数据层和要返回的类型
- python - Python程序不写入输出csv,其他一切似乎都正常工作
- c - 将 __m256d 转换为 __m256i
- swift - 我不能使用 MKPointAnnotation 添加多个引脚
- php - 如何在 laravel 中使用 foreach 循环仅显示一次数据....请编码
- php - PHP GD:imagecopy() 无法正常工作
- javascript - doPost(e) 不会触发 onChange(e) - 在 Google 电子表格中触发更改事件
- android - 如何从同一应用程序的另一个模块访问应用程序上下文?
- python - Python:单击下一页没有要关注的链接(javascript/AJAX)