通过 Office 加载项使用 Microsoft Graph 访问 SharePoint (Word JS)

Accessing SharePoint using Microsoft Graph through Office Add-in (Word JS)

我开发了一个 Office.js Word 加载项,并且正在使用 here. It uses the Office.Auth interface method getAccessTokenAsync, shown here 所述的 SSO 功能。这按描述工作,但当我尝试使用更多范围使用 Microsoft Graph 访问 SharePoint 时,问题就出现了。

TL;DR 我无法使用 Office.Auth 接口 getAccessTokenAsync 方法生成的令牌成功调用 Microsoft Graph 来访问 SharePoint。

完整描述

我做了以下事情:

  1. 添加了 Sites.ReadWrite.AllSites.Manage.All 权限 Azure AD 应用程序注册。
  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. 在用户未登录 Word 时的 Authorize 方法中添加了附加范围,如 here.

    所述
    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 方法时,我能够使用 returned 令牌成功调用我的图形。

什么不起作用 当用户已经登录到 Word 并且加载项 JS 使用 getAccessTokenAsync 方法生成令牌时,我在尝试使用 returned [ 进行相同的图形调用时得到 'Unauthorized' =31=]

问题 我需要为 Office JS getAccessTokenAsync 方法做一些额外的事情来 return 授权令牌以用于我对 SharePoint 的 Graph 调用吗?

编辑Post进一步调查
我使用 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 方法,两者都在记录时 in并提示登录,(同样不起作用的场景),我 获取包含与上述相同的令牌。
  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": ...
}

请注意作用域的不同,后者的旧版本具有完整列出的作用域,我可以通过这种方式进行授权。

对此有何解释?

答案不多,但评论太长了:

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

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

究竟是哪个 HTTP 调用返回 "Unauthorized"?

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

2019 年 12 月 19 日更新:

根据您在评论 "To clarify..." 中的描述,您似乎在调用 MS Graph 时包含了从 getAccessToken 获得的令牌。这是行不通的。该令牌是 "bootstrap token"。它使 Office 可以访问您的 add-in 的 Web 应用程序。然后,Web 应用程序需要使用 On Behalf Of Flow 将该令牌交换为允许 Web 应用程序访问 MS Graph 的令牌。然后,您将此 second token 作为 Authorization header 包含在对 Graph 的调用中。您在问题的第一句中链接到的样本就是这样做的。另请参阅这些文章:

Enable SSO in Office Add-ins

Authorize to Microsoft Graph

最后,确保字符串"Bearer"和Authorizationheader中的token之间有一个空格space。