首页 > 解决方案 > 无法访问 /me/drive/root/children(也无法访问任何 driveItem 对象)

问题描述

Microsoft Graph 无法访问任何 driveItem 对象(即 GET /me/drive/root/children)

我正在开发一个概念验证网络应用程序,它(除其他外)从经过身份验证的用户访问一些 Excel 工作簿(在 SharePoint 或 OneDrive 上)。

它基于 Microsoft 教程 [使用 Microsoft Graph 构建 Node.js Express 应用程序] https://docs.microsoft.com/en-us/graph/tutorials/node用于 Ms Graph 的大部分方面。- 最终用户的 Azure AD 身份验证 ( https://login.microsoftonline.com/common/oauth2/v2.0/authorize ) - 在 AAD 门户中注册的应用程序(隐式授权:ID tokens,Ms Graph 的 API 权限包括Files.ReadWrite.AllSites.ReadWrite.All

使用Microsoft Graph Explorer我们验证的 API 查询到具有以下路径的相关 driveItem 资源 -/drives/<id>/items/<id>对于/shares/<shareId>/driveItemSharePoint -/me/drive/items/<id>对于 OneDrive

但是当从 Web 应用程序运行时,所有这些 API 查询都会失败(而其他图形调用,如/me/,/me/drive/并且/me/drive/root/工作正常)

得到https://graph.microsoft.com/v1.0/drives/<id>/items/<id>

{
  statusCode: 404,
  code: 'itemNotFound',
  message: 'The resource could not be found.',
  requestId: 'cd35bf5b-1577-420e-980d-c1c2811a6fff',
  date: 2019-09-18T08:42:05.000Z,
  body:
   '{"code":"itemNotFound","message":"The resource could not be found.","innerError":{"request-id":"cd35bf5b-1577-420e-980d-c1c2811a6fff","date":"2019-09-18T10:42:05"}}' }

得到https://graph.microsoft.com/v1.0/shares/<shareId>/driveItem

{
  statusCode: 403,
  code: 'accessDenied',
  message: 'The caller does not have permission to perform the action.',
  requestId: '1d3bba03-6c15-41f0-9de5-979ce42127b5',
  date: 2019-09-18T08:46:37.000Z,
  body:
   '{"code":"accessDenied","message":"The caller does not have permission to perform the action.","innerError":{"request-id":"1d3bba03-6c15-41f0-9de5-979ce42127b5","date":"2019-09-18T10:46:37"}}' }

我很可能忽略了令牌的处理方式,但我找不到什么。

标签: azure-active-directorymicrosoft-graph-api

解决方案


我终于找到了问题。

如果在身份验证期间应用程序未在其范围内指定这些权限,则在 Azur AD 门户中授予权限是没有用的。

就我而言,添加files.readwrite.all解决了这个问题。

.env

OAUTH_SCOPES='profile files.readwrite.all mail.send user.read'

用于 Passport AAD:

import { IOIDCStrategyOptionWithoutRequest } from 'passport-azure-ad';

const oidcOptions: IOIDCStrategyOptionWithoutRequest = {
  allowHttpForRedirectUrl: true,
  clientID: oauthOptions.client.id,
  clientSecret: oauthOptions.client.secret,
  identityMetadata: `${oauthOptions.auth.tokenHost}${process.env.OAUTH_ID_METADATA}`,
  loggingLevel: 'info',
  passReqToCallback: false,
  redirectUrl: process.env.OAUTH_REDIRECT_URI!,
  responseMode: 'form_post',
  responseType: 'code id_token',
  scope: process.env.OAUTH_SCOPES!.split(' '),
  validateIssuer: false,
};

推荐阅读