【发布时间】:2017-05-13 04:33:46
【问题描述】:
我正在编写一个 Python 脚本来编辑 SharePoint 中的 Excel 电子表格。我们有 Office 365 商业版。我正在使用 Microsoft Graph API。 我在 Microsoft Azure Active Directory (AD) 中注册了 Python 应用程序,并为 Graph API 添加了以下 2 个(仅限应用程序)权限:(1) 在所有网站集中读取和写入文件(预览版)和 (2) 读取目录数据。 (我让我们的公司管理员为我注册了该应用程序。)
我的 Python 脚本使用 requests 库发送 REST 请求:
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 服务器请求并接收到 access_token。访问令牌是这样开始的
eyJ0eXAiOiJKV1QiLCJub25jZSI6...
然后它在 getWorkbookID() 中请求我的文件列表:
GET https://graph.microsoft.com/v1.0/me/drive/root/children
Authorization: Bearer eyJ0eXAiOiJKV1QiLCJub25jZSI6...
这是对该 REST 请求的响应:
{
"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"
}
}
}
请注意,当我通过 Graph Explorer (https://graph.microsoft.io/en-us/graph-explorer) 请求文件时,我成功获取了文件列表。
编辑:
- 将标题从“Microsoft Graph API 返回未设置为对象实例的对象引用”更改为“访问令牌响应中缺少 Azure AD“范围”。
- 在阅读以下内容后,将 GET 请求的 uri 中的“me”更改为“myOrganization”:graph.microsft.io/en-us/docs/overview/call_api
也就是说,
GET https://graph.microsoft.com/v1.0/myOrganization/drive/root/children
Authorization: Bearer eyJ0eXAiOiJKV1QiLCJub25jZSI6...
现在得到以下响应。
{
"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 中的示例,我看到访问令牌响应正文包含一个“范围”属性,该属性列出了在应用注册期间授予应用的权限.但是,我从服务器收到的访问令牌响应没有“范围”属性。这是我的访问令牌响应的样子。
{
"token_type":"Bearer",
"expires_in":"3599",
"ext_expires_in":"0",
"expires_on":"1482968367",
"not_before":"1482964467",
"resource":"https://graph.microsoft.com",
"access_token":"eyJ0eXAiOiJKV..."
}
问题:
- 我让管理员在 Azure AD 中注册了应用程序,并选中了所需的 Microsoft Graph API 应用程序权限复选框。显然这还不够。还需要什么?为什么访问令牌响应正文中没有权限?
- GET 请求的正确 URI 是什么? “MyOrganization”是 URI 中的正确值吗?
【问题讨论】:
-
该错误是 .NET 中的经典 NullReferenceException。可能是 API 中的错误,或者缺少预期的东西。似乎不是权限问题。
标签: python azure office365 microsoft-graph-api