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

通过Office加载项(Word JS)使用Microsoft Graph访问SharePoint,sharepoint,azure-active-directory,microsoft-graph-api,office-js,Sharepoint,Azure Active Directory,Microsoft Graph Api,Office Js,我已经开发了一个Office.js Word加载项,并且正在使用如上所述的SSO功能。它使用Office.Auth接口方法getAccessTokenAsync,如图所示。这是如上所述的,但当我尝试使用更多的作用域来使用Microsoft Graph访问SharePoint时,问题就出现了 TL;DR 我无法使用Office.Auth接口getAccessTokenAsync方法生成的令牌成功进行Microsoft Graph调用以访问SharePoint 完整描述 我已经做了以下工作: 在中添

我已经开发了一个Office.js Word加载项,并且正在使用如上所述的SSO功能。它使用
Office.Auth接口
方法
getAccessTokenAsync
,如图所示。这是如上所述的,但当我尝试使用更多的作用域来使用Microsoft Graph访问SharePoint时,问题就出现了

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

完整描述

我已经做了以下工作:

  • 在中添加了
    站点.ReadWrite.All
    站点.Manage.All
    权限 Azure广告应用程序注册
  • 在Word加载项清单中添加了其他作用域。

  • 如前所述,在
    Authorize
    方法中添加了用户未登录Word时的附加作用域

  • 什么有效 当用户未登录Word并且必须调用
    Authorize
    方法时,我能够使用返回的令牌成功地进行图形调用

    什么不起作用 当用户已经登录到Word并且插件JS使用
    getAccessTokenAsync
    方法生成令牌时,当尝试使用返回的

    问题 Office JS
    getAccessTokenAsync
    方法返回授权令牌以用于对SharePoint的图形调用,我还需要做些什么

    编辑后期进一步调查
    我过去常对收到的代币进行解码

  • 登录时使用较旧的
    getAccessTokenAsync
    方法 (不起作用的场景),我得到一个包含 以下:
  • 使用较新的
    getAccessToken
    方法,记录时 在中并提示登录(也不起作用的场景),我 获取包含与上面相同内容的令牌
  • 与老年人
    getAccessTokenAsync
    方法,当提示登录并转到
    AzureADAuthController
    ,(确实有效的场景!),我得到了一个 包含以下内容的令牌:
  • 请注意作用域之间的差异,后者(旧版本)已经完全列出了作用域,我可以通过这种方式进行授权


    什么能解释这一点呢?

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

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

    检查是否已将新作用域添加到登录操作方法中的
    graphScopes
    数组中。(除了将它们添加到Authorize操作方法之外,您已经完成了此操作。)

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

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

    19年12月19日更新:

    根据您在评论“澄清…”中的描述,看起来您在对MS Graph的调用中包含了从
    getAccessToken
    获得的令牌。这是行不通的。该令牌是“引导令牌”。它允许Office访问外接程序的web应用程序。然后,web应用程序需要代表流使用将该令牌交换为允许web应用程序访问MS Graph的令牌。然后将第二个令牌作为授权头包含在调用图中。您在问题的第一句中链接的示例就是这样做的。另请参阅以下文章:


    最后,确保字符串“Bearer”和授权头中的令牌之间有空格

    嗨,谢谢你的信息。我已经使用了
    OfficeRuntime.auth.getAccessToken
    并更新了登录操作方法中的
    graphScopes
    数组,但我仍然获得了“未经授权”的上述图形调用,以获取SharePoint列表项
    gethttps://graph.microsoft.com/v1.0/sites/{site id}/lists/{list id}/items/{item id}
    。我使用
    getAccessToken
    成功获取令牌,但无法将其用于图形调用。请使用Fiddler工具查看该调用的请求。访问令牌是否在授权标头中?再看看Fiddler中的响应。可能有关于错误的更多信息。我在使用对收到的令牌进行解码后更新了问题。我希望这能进一步澄清这个问题。再想一想,停止使用
    getAccessTokenAsync
    。我认为这只是增加了一层不必要的混乱
    getAccessToken
    是今后应该使用的。请按建议使用小提琴。(仅供参考:如果
    AzureADAuthController
    正在运行,则表示SSO系统发生故障并分支到回退系统。在该文件中查找
    对话框回退
    ,我理解我应该使用
    getAccessToken
    ,但回退系统使用
    AzureADAuth提供的令牌仍然是这种情况Controller
    是唯一允许我成功使用Graph访问SharePoint的方法。当我尝试使用Graph访问SharePoint时,所有其他SSO方法提供的令牌仍然会给我“未经授权”的权限。我试图突出显示生成的令牌之间的差异,以查看生成的令牌中是否缺少某些内容单点登录系统。
    <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>
    
    GET https://graph.microsoft.com/v1.0/sites/{site-id}/lists/{list-id}/items/{item-id}
    
    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();
    
    {
      "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"
    }
    
    {
      "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": ...
    }