当应用程序具有读取共享点站点的权限时,scp 或角色声明需要出现在令牌中

iJK*_*iJK 4 sharepoint-online microsoft-graph-api

我在 Azure 中创建了一个应用程序并将其设置为使用访问令牌和 ID 令牌。

在此输入图像描述

我想连接到不同的租户并阅读 SharePoint 网站。以下是我已请求并获得管理员同意的权限:

在此输入图像描述

目前,我已经设置了应用程序密钥,但我计划稍后转向证书。

我有这个代码来获取访问令牌,并且我确实得到了一个访问令牌:

const params = new URLSearchParams();
params.append("grant_type", "client_credentials");
params.append("scope", "https://graph.microsoft.com/.default");
params.append("client_id", process.env.client_id);
params.append("client_secret", process.env.client_secret);

var url = `https://login.microsoftonline.com/${tenant}/oauth2/v2.0/token`;
const response = await fetch(url,
    {
        method: 'POST',
        body: params,
        headers: { 'Content-Type': 'application/x-www-form-urlencoded' }
    }
);
Run Code Online (Sandbox Code Playgroud)

但是,当我尝试阅读下面的根站点时

var url = "https://graph.microsoft.com/v1.0/sites?search=*";
const response = await fetch(url,
    {
        method: 'GET',
        headers: { 'Authorization': `Bearer ${access_token}` }
    }
);
Run Code Online (Sandbox Code Playgroud)

我收到此错误:

error: { 
    code: 'AccessDenied',
    message: 'Either scp or roles claim need to be present in the token.',
    innerError: { 
        'request-id': 'ec47913f-2624-4d1c-9b27-5baf05ccebfd',
        date: '2019-08-16T14: 15: 37'
    }
}
Run Code Online (Sandbox Code Playgroud)

我在https://jwt.io/检查了令牌,实际上我没有看到roles或的任何条目scp

看起来我错过了一步,但我不知道是哪一步。

我得到这样的令牌:

https://login.microsoftonline.com/${tenant}/oauth2/v2.0/token 
Run Code Online (Sandbox Code Playgroud)

我做错了什么?

Mar*_*eur 5

首先要了解的是,您不能以同一个令牌同时接收应用程序权限和委派权限,这是一个非此即彼的场景。您收到的类型完全取决于您用于请求令牌的 OAuth Grant:

  • 授权代码和隐式返回具有scp属性的委托令牌
  • 客户端凭证返回带有roles属性的应用程序令牌

第二件事是您请求了两个不同 API 的范围。根据您的选择,您将无法通过 Microsoft Graph 访问 SharePoint,因为您仅请求访问旧版 SharePoint API。更重要的是,您只请求了User.ReadGraph 的委派范围,因此当您使用客户端凭据获取令牌时,该令牌将没有任何权限。

为了获取用于读取 SharePoint 网站的应用程序令牌,您需要选择Sites.Read.All Microsoft Graph应用程序权限

  • 您需要“Microsoft Graph”下的“Sites.Read.All”权限,而不是“SharePoint”下的“Sites.Read.All”权限。 (3认同)