首页 > 解决方案 > 通过 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。

详细描述

我做了以下事情:

  1. 在 Azure AD 应用注册中添加Sites.ReadWrite.AllSites.Manage.All权限。
  2. 在 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>
    
  3. 使用 Graph Explorer 确认我可以作为我的用户进行 SharePoint Graph 调用。

    GET https://graph.microsoft.com/v1.0/sites/{site-id}/lists/{list-id}/items/{item-id}
    
  4. 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来解码收到的令牌。

  1. 使用旧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"
}
  1. 使用较新的getAccessToken方法,在登录和提示登录时(也不起作用的场景),我得到一个包含与上述相同的令牌。
  2. 使用较旧的 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": ...
}

请注意范围的差异,后者的旧版本已完全列出范围,我可以通过这种方式进行授权。

这有什么可以解释的?

标签: sharepointazure-active-directorymicrosoft-graph-apioffice-js

解决方案


答案不多,但太长了,无法发表评论:

该示例最近更改为使用新的OfficeRuntime.auth.getAccessToken. 您似乎使用的是旧版本,它使用Office.auth.getAccessTokenAsync. 这应该仍然有效,但它是一个预览 API,可能会在某个时候停止工作。考虑克隆较新的版本。不过等几天。我即将对新版本进行一些修复。

检查您是否还在graphScopesLogin 操作方法中将新范围添加到数组中。(除了像您已经完成的那样将它们添加到 Authorize 操作方法之外。)

究竟哪个 HTTP 调用返回“未经授权”?

getAccessToken从(或)返回什么错误getAccessTokenAsync?它通常有一个 13xxx 号码。

2019 年 12 月 19 日更新:

根据您在评论“澄清...”中的描述,您似乎getAccessToken在调用 MS Graph 时包含了您从中获得的令牌。这行不通。该令牌是“引导令牌”。它使 Office 可以访问加载项的 Web 应用程序。然后,Web 应用程序需要使用On Behalf Of Flow将该令牌交换为允许 Web 应用程序访问 MS Graph 的令牌。然后,您将第二个令牌作为Authorization标头包含在对 Graph 的调用中。您在问题的第一句话中链接到的示例就是这样做的。另请参阅这些文章:

在 Office 加载项中启用 SSO

授权给 Microsoft Graph

最后,请确保字符串“Bearer”和 Authorization 标头中的令牌之间有一个空格。


推荐阅读