为什么我收到 Microsoft Graph API 调用的“401 Unauthorized”?
Why am I Getting "401 Unauthorized" for Microsoft Graph API Call?
我在租户 A 中创建了应用程序并将其添加到租户 B。我已在两个租户中授予权限。为什么我每次 API 调用该应用程序时都会收到此响应?
resulted in a `401 Unauthorized` response: {"error":{"code":"NoPermissionsInAccessToken","message":"The token contains no permissions, or permissions can not be un (truncated...)
这是我正在发出的 PHP 请求(我正在使用租户 A 中的应用程序的客户端 ID 和客户端密码):
<?php
use League\OAuth2\Client\Provider\Exception\IdentityProviderException;
use Microsoft\Graph\Graph;
$guzzle = new \GuzzleHttp\Client();
$tenantId = 'common';
$clientId = 'ccc-ddd-fff';
$clientSecret = 'xxx-yyy-zzz';
$url = 'https://login.microsoftonline.com/' . $tenantId . '/oauth2/token?api-version=1.0';
try {
$token = json_decode($guzzle->post($url, [
'form_params' => [
'client_id' => $clientId,
'client_secret' => $clientSecret,
'resource' => 'https://graph.microsoft.com/',
'grant_type' => 'client_credentials',
],
])->getBody()->getContents());
$accessToken = $token->access_token;
} catch (\Exception $e) {
print $e->getMessage();
}
$graph = new Graph();
$graph->setAccessToken($accessToken);
try {
print_r($graph->createRequest("GET", '/users/email@email.com/messages/xxxxxxxxxxxxx==')->execute());
} catch (\Exception $e) {
print $e->getMessage();
}
两个租户都被授予了这些权限:
Permissions in Tenant A and B
首先,根据api document,你最好添加Mail.ReadBasic.All
申请权限,但我不确定是否影响了你在这里的调用。
您的问题主要是因为您使用了$tenantId = 'common';
,您应该将其设置为您要为其调用api的租户名称(例如xxx.onmicrosoft.com)。我的意思是,如果你想调用 /users/xxx@tenantA.com/messages
,你应该把 tenantA 的租户 id/name 到 $tenantId
变量,但是当你想调用 /users/yyy@tenantB.com/messages
时,你应该设置 tenantB 的。
下面的屏幕截图显示了当我使用 common
而不是我的租户名称生成的令牌时的情况。
401 未授权错误:您的令牌有效吗?
确保您的应用程序在请求中向 Microsoft Graph 提供有效的访问令牌。此错误通常表示 HTTP 身份验证请求 header 中可能缺少访问令牌,或者令牌无效或已过期。我们强烈建议您使用 Microsoft 身份验证库 (MSAL) 获取访问令牌。此外,如果您尝试使用授予个人 Microsoft 帐户的委托访问令牌访问仅支持工作或学校帐户(组织帐户)的 API,则可能会发生此错误。
您始终可以利用 jwt.ms 来检查对您的令牌的声明。使用它并检查您是否具有调用 API 端点的必要权限。
我需要做的是提示 Microsoft 管理员使用类似于此的 link 授予权限。仅从 Microsoft
添加企业
https://login.microsoftonline.com/common/oauth2/v2.0/authorize?scope=offline_access+openid+profile+User.Read+Mail.ReadWrite+Mail.Send
&response_type=code
&client_id=a62b0808-2b1f-4efc-a3d6-ad1223dc06a9
&redirect_uri=https://myurl/blah.html
&response_mode=query
我在租户 A 中创建了应用程序并将其添加到租户 B。我已在两个租户中授予权限。为什么我每次 API 调用该应用程序时都会收到此响应?
resulted in a `401 Unauthorized` response: {"error":{"code":"NoPermissionsInAccessToken","message":"The token contains no permissions, or permissions can not be un (truncated...)
这是我正在发出的 PHP 请求(我正在使用租户 A 中的应用程序的客户端 ID 和客户端密码):
<?php
use League\OAuth2\Client\Provider\Exception\IdentityProviderException;
use Microsoft\Graph\Graph;
$guzzle = new \GuzzleHttp\Client();
$tenantId = 'common';
$clientId = 'ccc-ddd-fff';
$clientSecret = 'xxx-yyy-zzz';
$url = 'https://login.microsoftonline.com/' . $tenantId . '/oauth2/token?api-version=1.0';
try {
$token = json_decode($guzzle->post($url, [
'form_params' => [
'client_id' => $clientId,
'client_secret' => $clientSecret,
'resource' => 'https://graph.microsoft.com/',
'grant_type' => 'client_credentials',
],
])->getBody()->getContents());
$accessToken = $token->access_token;
} catch (\Exception $e) {
print $e->getMessage();
}
$graph = new Graph();
$graph->setAccessToken($accessToken);
try {
print_r($graph->createRequest("GET", '/users/email@email.com/messages/xxxxxxxxxxxxx==')->execute());
} catch (\Exception $e) {
print $e->getMessage();
}
两个租户都被授予了这些权限: Permissions in Tenant A and B
首先,根据api document,你最好添加Mail.ReadBasic.All
申请权限,但我不确定是否影响了你在这里的调用。
您的问题主要是因为您使用了$tenantId = 'common';
,您应该将其设置为您要为其调用api的租户名称(例如xxx.onmicrosoft.com)。我的意思是,如果你想调用 /users/xxx@tenantA.com/messages
,你应该把 tenantA 的租户 id/name 到 $tenantId
变量,但是当你想调用 /users/yyy@tenantB.com/messages
时,你应该设置 tenantB 的。
下面的屏幕截图显示了当我使用 common
而不是我的租户名称生成的令牌时的情况。
401 未授权错误:您的令牌有效吗?
确保您的应用程序在请求中向 Microsoft Graph 提供有效的访问令牌。此错误通常表示 HTTP 身份验证请求 header 中可能缺少访问令牌,或者令牌无效或已过期。我们强烈建议您使用 Microsoft 身份验证库 (MSAL) 获取访问令牌。此外,如果您尝试使用授予个人 Microsoft 帐户的委托访问令牌访问仅支持工作或学校帐户(组织帐户)的 API,则可能会发生此错误。
您始终可以利用 jwt.ms 来检查对您的令牌的声明。使用它并检查您是否具有调用 API 端点的必要权限。
我需要做的是提示 Microsoft 管理员使用类似于此的 link 授予权限。仅从 Microsoft
添加企业https://login.microsoftonline.com/common/oauth2/v2.0/authorize?scope=offline_access+openid+profile+User.Read+Mail.ReadWrite+Mail.Send
&response_type=code
&client_id=a62b0808-2b1f-4efc-a3d6-ad1223dc06a9
&redirect_uri=https://myurl/blah.html
&response_mode=query