scp 或 roles 声明需要出现在令牌中,使用时应用程序权限读取 sharepoint 站点

Either scp or roles claim need to be present in the token using when application permissions to read sharepoint sites

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

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

目前,我已经设置了一个 App Secret,但我打算稍后转移到证书。

我有这个代码来获取访问令牌,我确实取回了一个访问令牌:

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' }
    }
);

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

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

我收到这个错误:

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'
    }
}

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

我好像错过了一步,但我不知道是哪一步。

我得到的令牌是这样的:

https://login.microsoftonline.com/${tenant}/oauth2/v2.0/token 

我做错了什么?

首先要了解的是,您不能同时获得应用程序和委派权限,这是一种 either/or 情况。您收到哪种类型完全取决于您用于请求令牌的 OAuth Grant:

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

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

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