【问题标题】:How to solve "NoPermissionsInAccessToken" returned by Microsoft Graph when reading calendar or sending mail阅读日历或发送邮件时,Microsoft Graph 返回“NoPermissionsInAccessToken”如何解决
【发布时间】:2019-11-06 09:48:53
【问题描述】:

在我们部门内,我们有一个 Classic ASP 网站,该网站一直在使用我们的公司 Google 帐户进行身份验证并将活动插入到我们的 Google 日历中。该组织刚刚从 Google 切换到 Office 365,我正在尝试将代码切换为使用 Outlook,但没有成功。

我可以使用访问令牌 GET https://graph.microsoft.com/v1.0/me 并查看基本资料,但如果我尝试阅读日历事件或发送电子邮件,我会看到以下消息:

"error": {
  "code": "NoPermissionsInAccessToken",
  "message": "The token contains no permissions, or permissions can not be understood."

我使用我的个人 Microsoft 帐户创建了一个 Azure 帐户并添加了一个应用程序。我将我的同事和我的公司帐户添加为来宾用户。我设置了所需的权限并做了管理员同意的事情:

然后我按照this page 上的步骤进行操作。

我第一次访问https://login.microsoftonline.com/{tenant id}/oauth2/v2.0/authorize,包括以下查询项:

client_id={client id}
response_type=code
redirect_uri={our URL}
response_mode=query
scope=https%3A%2F%2Fgraph.microsoft.com%2F.default
state={number}

这会返回一个“代码”,我将其发送给https://login.microsoftonline.com/{tenant id}/oauth2/v2.0/token,包括:

grant_type=authorization_code
client_secret={client secret}
client_id={client id}
scope=https%3A%2F%2Fgraph.microsoft.com%2F.default
state={same number as above}
redirect_uri={same URL as above}
code={code returned from /authorize}

这将返回 id、访问和刷新令牌。如果我使用https://jwt.ms/ 解码访问令牌,它似乎包含适当的受众和范围:

"aud": "https://graph.microsoft.com"
"scp": "Calendars.ReadWrite email Mail.Send openid profile User.Read"

...尽管我注意到在某些文档中没有“角色”条目。这是个问题吗?

然后我将访问令牌发送到https://graph.microsoft.com/v1.0/me,并带有以下标头:

"Authorization", "Bearer {access token}"
"Host", "graph.microsoft.com"
"Content-Type", "application/json"
"Prefer", "outlook.timezone Europe/London"

这将返回我的电子邮件地址等,但如果我将 URL 更改为其他任何内容,例如 /me/photo/$value/me/calendar/events,或者尝试发送电子邮件,我会被告知有令牌中没有权限。

我看到还有其他类似的问题,但它们主要针对client_credentials 流程(我不确定这有什么不同),并且没有一个答案可以帮助我解决我的问题。

如果我明显遗漏了任何内容,或者我以错误的方式访问客户端的 Graph 数据,请告诉我?使用 Google 似乎很简单,但我发现 Microsoft 文档和示例的详细程度略低。

【问题讨论】:

  • 您是否配置了 Exchange Online 邮箱?
  • 所有来宾帐户(包括我用来登录以进行测试的帐户,并且出现错误)都有邮箱和日历 - 数据是从 Google 迁移到其中的帐户,但从那以后添加了一些东西。但是,作为 Azure 帐户所有者的帐户没有邮箱或日历。如果我使用该帐户登录 Web 应用程序,则在尝试使用 Graph 访问日历时会看到未指定的错误 500。
  • 访客账户与普通账户不同。 Graph 无法访问另一个租户中的邮箱,因此如果您在租户 A 中与来自租户 B 的来宾进行身份验证,则它无法访问该用户的邮箱。 Graph 一次只能与一个租户对话。
  • 感谢您的帮助 - 希望这将为我指明正确的方向。 Google 解决方案没有任何需要考虑的问题,这可能就是我苦苦挣扎的原因 - 每个用户都可以自行表示同意,无论是谁创建了帐户。

标签: azure-active-directory microsoft-graph-api


【解决方案1】:

添加访客用户毫无意义。

您所做的是使用您的个人 Microsoft 帐户对 Azure AD 进行管理员同意。

您实际需要做的是获得目标 Azure AD/O365 租户的管理员同意。

如下构建同意链接:

https://login.windows.net/{tenant ID of the target Azure AD}/oauth2/authorize?response_type=id_token&client_id={client ID}&redirect_uri={reply url}&response_mode=form_post&nonce=a4014117-28aa-47ec-abfb-f377be1d3cf5&resource=https://graph.microsoft.com&prompt=admin_consent

在浏览器中访问它并使用目标 Azure AD 的管理员帐户登录。

另一个问题是您使用的是Get access on behalf of a user。因此,您必须在 Azure AD 应用程序中分配委托权限而不是应用程序权限。

【讨论】:

  • 谢谢 - 我确实想知道这个问题是否与类似的事情有关。我还刚刚注意到,我对 /me 的调用返回的详细信息与我在 Graph Explorer 中看到的不同 - 大概是因为我的代码提供了来宾帐户的详细信息,而 Graph Explorer 显示的是原始帐户?我会给你的建议一试。这些东西在任何地方都有解释吗?如果您不知道自己缺少什么,那么您就不知道要搜索什么!
  • 是的。 Graph Explorer 将显示原始帐户的信息。您可以对目标租户进行管理员同意并调用 /users/user id。如果您有任何进一步的疑虑,请告诉我。
  • 谢谢 - 我不是目标租户的管理员,所以现在我的任务是说服公司 IT 部门为我解决这个问题。祝我好运!
猜你喜欢
  • 1970-01-01
  • 2020-06-11
  • 1970-01-01
  • 1970-01-01
  • 2020-05-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多