我有一个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中,您可以看到已授予所需的权限,但是请求仍然失败:
我试图在JS,Java SDK和Postman中执行操作,但我总是遇到相同的问题。我还尝试了beta和v1.0 API,没有明显的区别。问题与我的用户身份验证流程或令牌会话有关吗?我在Azure AD中是否有冲突或缺少权限?我很困惑。
答案 0 :(得分:1)
我将通过以下步骤诊断您的问题:
您可能已经检查了这一点,但是确定您的用户(对于资源所有者密码流)已分配了团队许可证?
我总是使用https://jwt.ms来检查令牌,然后继续将令牌粘贴到那里(不用担心,这是一个Microsoft拥有的网站,只能在本地解析令牌)
您的访问令牌应该至少具有ChannelMessage.Send
范围,并且可能至少具有Group.ReadWrite.All
范围(请参阅docs)。
受众群体应为https://graph.microsoft.com
如果您的令牌不正确,则应尝试更改“给我访问令牌”请求。
我的建议:
ChannelMessage.Send
。不确定,但是我认为即使您授予了更多访问权限,它也只会为您提供具有所请求范围的令牌。organizations
端点上请求令牌,但是要获取访问令牌,可能是您需要租户特定的端点。/v1.0/me/joinedteams
/v1.0/teams/xxxx-xxxx-xxxx-xxxx/channels
POST
/v1.0/teams/xxxx-xxxx-xxxx-xxxx/channels/{channelId}/messages
{
"body":{
"content":"Hello channel, from graph explorer"
}
}
在公共论坛上,我们无法调查具体问题,但是如果您按照上述步骤操作,并且您确定令牌是正确的(您将获得正确的作用域和受众),但仍然会遇到禁止的错误。您应该在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