Microsoft Graph API随机返回403-禁止

时间:2020-09-20 01:45:38

标签: microsoft-graph-api microsoft-teams

我有一个NodeJS应用程序,该应用程序在过去一年中已成功使用Microsoft Graph API beta与Teams和Drive进行交互(主要是上传文件并将消息发布到频道)。在过去的两周内,当请求对Drive或Teams端点进行写操作时,Graph API已经开始返回403(禁止)响应。该应用使用委派的权限和resource-owner password credentials grant flow来获取令牌以发出请求(以下邮递员代码示例):

var myHeaders = new Headers();
myHeaders.append("Content-Type", "application/x-www-form-urlencoded");
myHeaders.append("Host", "login.microsoftonline.com");

var urlencoded = new URLSearchParams();
urlencoded.append("client_id", "xxxxx");
urlencoded.append("scope", "user.read mail.read openid profile offline_access");
urlencoded.append("grant_type", "password");
urlencoded.append("username", "xxxx");
urlencoded.append("password", "xxxx");
urlencoded.append("client_secret", "xxxxx");

var requestOptions = {
  method: 'POST',
  headers: myHeaders,
  body: urlencoded,
  redirect: 'follow'
};

fetch("https://login.microsoftonline.com/organizations/oauth2/v2.0/token", requestOptions)
  .then(response => response.text())
  .then(result => console.log(result.access_token))
  .catch(error => console.log('error', error));

这将成功返回令牌并列出该应用的授予权限:

{
    "token_type": "Bearer",
    "scope": "ChannelMessage.Send Chat.Read Chat.ReadWrite Files.Read.All Files.ReadWrite.All Group.Read.All Group.ReadWrite.All Mail.Read Member.Read.Hidden People.Read People.Read.All profile Sites.Read.All Sites.ReadWrite.All User.Read User.Read.All User.ReadBasic.All User.ReadWrite openid email",
    "expires_in": 3599,
    "ext_expires_in": 3599,
    "access_token": "xxx",
    "refresh_token": "xxx",
    "id_token": "xxx"
}

然后我可以使用此令牌发出请求,例如以下请求,这些请求会将消息发布到Teams频道:

var myHeaders = new Headers();
myHeaders.append("Content-Type", "application/json");
myHeaders.append("Authorization", "Bearer xxxxx");

var raw = "{\n  body: { \n      content: '<h1>This is a test</h1><h3>More stuff here</h3>',\n   contentType: 'html'\n  }\n}";

var requestOptions = {
  method: 'POST',
  headers: myHeaders,
  body: raw,
  redirect: 'follow'
};

fetch("https://graph.microsoft.com/v1.0/teams/xxxxx/channels/xxxxx/messages", requestOptions)
  .then(response => response.text())
  .then(result => console.log(result))
  .catch(error => console.log('error', error));

使用403响应,将其工作的时间减半,而失败的时间减半:

{
    "error": {
        "code": "Forbidden",
        "message": "Forbidden",
        "innerError": {
            "date": "2020-09-20T17:15:54",
            "request-id": "60e2a57a-6b44-4039-be4f-636debd10f87",
            "client-request-id": "60e2a57a-6b44-4039-be4f-636debd10f87"
        }
    }
}

在Graph Explorer中,您可以看到已授予所需的权限,但是请求仍然失败:

Graph explorer error

我试图在JS,Java SDK和Postman中执行操作,但我总是遇到相同的问题。我还尝试了beta和v1.0 API,没有明显的区别。问题与我的用户身份验证流程或令牌会话有关吗?我在Azure AD中是否有冲突或缺少权限?我很困惑。

2 个答案:

答案 0 :(得分:1)

我将通过以下步骤诊断您的问题:

1。检查许可证

您可能已经检查了这一点,但是确定您的用户(对于资源所有者密码流)已分配了团队许可证?

2。检查令牌

我总是使用https://jwt.ms来检查令牌,然后继续将令牌粘贴到那里(不用担心,这是一个Microsoft拥有的网站,只能在本地解析令牌)

您的访问令牌应该至少具有ChannelMessage.Send范围,并且可能至少具有Group.ReadWrite.All范围(请参阅docs)。

受众群体应为https://graph.microsoft.com

3。修复令牌

如果您的令牌不正确,则应尝试更改“给我访问令牌”请求。

我的建议:

  • 您不是在请求具有正确范围的令牌,因此我想您应该在原始请求中添加ChannelMessage.Send。不确定,但是我认为即使您授予了更多访问权限,它也只会为您提供具有所请求范围的令牌。
  • 您正在organizations端点上请求令牌,但是要获取访问令牌,可能是您需要租户特定的端点。

4。在资源管理器中尝试

  1. 列出团队/v1.0/me/joinedteams
  2. 选择一个团队并列出频道/v1.0/teams/xxxx-xxxx-xxxx-xxxx/channels
  3. 选择一个频道并发送一条消息POST /v1.0/teams/xxxx-xxxx-xxxx-xxxx/channels/{channelId}/messages
{
    "body":{
        "content":"Hello channel, from graph explorer"
    }
}

结果: enter image description here

5。打开支持请求

在公共论坛上,我们无法调查具体问题,但是如果您按照上述步骤操作,并且您确定令牌是正确的(您将获得正确的作用域和受众),但仍然会遇到禁止的错误。您应该在azure门户上创建一个支持问题。并向他们提供403错误的正文。他们应该能够通过搜索request-id来诊断问题。

答案 1 :(得分:0)

在获得应用程序管理员的同意后,您可能已更改了API权限。当您获得管理员同意时,Azure AD将在同意时对权限进行“快照”。然后,如果以后更改权限,则需要再次重新执行管理员同意过程。

尝试输入

https://login.microsoftonline.com/common/adminconsent?client_id={YOUR-APP-ID} 进入浏览器窗口,以再次提示管理员同意您的应用程序。有关更多详细信息,请参阅 https://docs.microsoft.com/en-us/azure/active-directory/develop/v2-permissions-and-consent#request-the-permissions-from-a-directory-admin