Azure AD: “scope” Property Missing from Access Token Response Body
我正在编写一个python脚本来编辑一个位于SharePoint中的Excel电子表格。我们有365办公室。我正在使用Microsoft Graph API。我在Microsoft Azure Active Directory(AD)中注册了python应用程序,并为graph api添加了以下2个(仅限应用程序)权限:(1)读取和写入所有网站集中的文件(预览)和(2)读取目录数据。(我让公司管理员为我注册了应用程序。)
我的python脚本使用请求库发送REST请求:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 | import json import requests MSGRAPH_URI = 'https://graph.microsoft.com' VERSION = 'v1.0' def requestAccessToken(tenant_id, app_id, app_key): MSLOGIN_URI = 'https://login.microsoftonline.com' ACCESS_TOKEN_PATH = 'oauth2/token' GRANT_TYPE = 'client_credentials' endpoint = '{0}/{1}/{2}'.format(MSLOGIN_URI, tenant_id, ACCESS_TOKEN_PATH) headers = {'Content-Type': 'Application/Json'} data = { 'grant_type': GRANT_TYPE, 'client_id': app_id, 'client_secret': app_key, 'resource': MSGRAPH_URI } access_token = response.json()['access_token'] return access_token def getWorkbookID(access_token, fileName): endpoint = '{0}/{1}/me/drive/root/children'.format(MSGRAPH_URI, VERSION) headers = { 'Content-Type': 'Application/Json', 'Authorization': 'Bearer {}'.format(access_token) } response = requests.get(endpoint, headers=headers) print response.text assert response.status_code == 200 items = response.json()['value'] workbook_id = None for item in items: if item['name'] == fileName: workbook_id = item['id'] return workbook_id access_token = requestAccessToken(TENANT_ID, APP_ID, APP_KEY) workbook_id = getWorkbookID(access_token, WORKBOOK_FILENAME) |
python应用程序成功地请求并接收来自Microsoft服务器的
1 | eyJ0eXAiOiJKV1QiLCJub25jZSI6... |
然后它在getWorkbookID()中请求我的文件列表:
1 2 | GET https://graph.microsoft.com/v1.0/me/drive/root/children Authorization: Bearer eyJ0eXAiOiJKV1QiLCJub25jZSI6... |
这是对该REST请求的响应:
1 2 3 4 5 6 7 8 9 10 | { "error": { "code":"InternalServerError", "message":"Object reference not set to an instance of an object.", "innerError": { "request-id":"aa97a822-7ac5-4986-8ac0-9852146e149a", "date":"2016-12-26T22:13:54" } } } |
请注意,当我通过图形资源管理器(https://graph.microsoft.io/en us/graph explorer)请求时,我成功地获得了一个文件列表。
编辑:
也就是说,
1 2 | GET https://graph.microsoft.com/v1.0/myOrganization/drive/root/children Authorization: Bearer eyJ0eXAiOiJKV1QiLCJub25jZSI6... |
现在得到以下响应。
1 2 3 4 5 6 7 8 9 10 | { "error": { "code":"AccessDenied", "message":"Either scp or roles claim need to be present in the token.", "innerError": { "request-id":"bddb8c51-535f-456b-b43e-5cfdf32bd8a5", "date":"2016-12-28T22:39:25" } } } |
查看graph.microsoft.io/en-us/docs/authorization/app_authorization中的示例,我发现access token response body包含一个"scope"属性,其中列出了在应用程序注册期间为应用程序授予的权限。但是,我从服务器收到的访问令牌响应没有"scope"属性。这里是我的访问令牌响应的样子。
1 2 3 4 5 6 7 8 9 | { "token_type":"Bearer", "expires_in":"3599", "ext_expires_in":"0", "expires_on":"1482968367", "not_before":"1482964467", "resource":"https://graph.microsoft.com", "access_token":"eyJ0eXAiOiJKV..." } |
问题:
感谢大家的回答。经过更多的研究,我找到了我问题的答案。
原始问题:"Microsoft Graph API返回未设置为对象实例的对象引用"
请求
1 2 | GET https://graph.microsoft.com/v1.0/me/drive/root/children Authorization: Bearer eyJ0eXAiOiJKV1QiLCJub25jZSI6... |
获取响应
1 2 3 4 5 6 7 8 9 10 | { "error": { "code":"InternalServerError", "message":"Object reference not set to an instance of an object.", "innerError": { "request-id":"aa97a822-7ac5-4986-8ac0-9852146e149a", "date":"2016-12-26T22:13:54" } } } |
正如@sriramdhanasekaran msft指出的,
更新的问题:访问令牌响应中缺少"azure ad"scope"属性"
更新的(用/myorganization替换/me)请求
1 2 | GET https://graph.microsoft.com/v1.0/myOrganization/drive/root/children Authorization: Bearer eyJ0eXAiOiJKV1QiLCJub25jZSI6... |
获取响应
1 2 3 4 5 6 7 8 9 10 | { "error": { "code":"AccessDenied", "message":"Either scp or roles claim need to be present in the token.", "innerError": { "request-id":"bddb8c51-535f-456b-b43e-5cfdf32bd8a5", "date":"2016-12-28T22:39:25" } } } |
正如@sriramdhanasekaran msft和@dankershaw msft提到的,
但是,@sriramdhanasekaran msft提供的解决方案:
1 | https://login.microsoftonline.com/common/oauth2/authorize?client_id=&response_type=code&redirect_uri=http://localhost&resource=https://graph.microsoft.com&prompt=consent |
没有帮助,因为我的应用程序没有
另外,
成功:
我的应用程序现在可以在线编辑我的Excel电子表格,而无需人工用户的干预。与@peterpan msft所说的相反,使用graph api可以做到这一点,并且无需下载Excel电子表格并离线编辑。
总结:
存在两个问题:(1)使用
正如@juunas所说,下面的第一个错误信息应该是.NET中由服务器端引起的空异常,而不是API错误或权限问题。
1
2
3 error": {
"code":"InternalServerError",
"message":"Object reference not set to an instance of an object.",
您可以参考so线程来了解此情况,该情况似乎在为后端更新,请稍后再试。
为了解释将图形API URL中的选项
但是,根据我的理解,您希望为组织编辑一个在SharePoint中使用的Excel电子表格,它似乎不适合通过使用图形API来编辑。根据我的经验,应该通过使用OneDrive for Business的API将Excel文件复制到本地进行编辑和上载以覆盖它,请参阅OneDrive的开发文档并尝试将API用于驱动器资源。
希望它有帮助。
由于正在使用客户机的凭证令牌流(即没有经过身份验证的用户上下文),任何带有/me的请求都是无效的,因为/me指的是当前登录的用户。如果要访问用户驱动器中的文件,请尝试使用委派令牌。
要访问SharePoint中的根驱动器,请求URL是/drive/root/children(myorganization是可选的)。
对于丢失的索赔,管理员必须同意应用程序。您可以通过请求管理员访问以下URL(替换为应用程序的URL)来强制同意。
https://login.microsoftonline.com/common/oauth2/authorize?client_id=&;response_type=code&;redirect_uri=http://localhost&resource=https://graph.microsoft.com&prompt=同意