2016-12-28 38 views
1

我正在編寫一個Python腳本來編輯生活在SharePoint中的Excel電子表格。我們有Office 365 for Business。我正在使用Microsoft Graph API。 我向Microsoft Azure Active Directory(AD)註冊了Python應用程序,併爲Graph API添加了以下2個(僅適用於應用程序)權限:(1)讀取和寫入所有網站集中的文件(預覽)和(2)讀取目錄數據。 (我有我們公司管理員註冊應用程序對我來說)。Azure AD:訪問令牌響應正文丟失的「範圍」屬性

我的Python腳本使用請求庫發送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應用程序成功地請求,並從微軟服務器接收到一個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" 
    } 
    } 
} 

注當我通過圖形瀏覽器(https://graph.microsoft.io/en-us/graph-explorer)請求時,我成功獲取了我的文件列表。

編輯:

  1. 從「微軟圖形API返回對象引用不設置到對象的實例」到「Azure的AD‘範圍’從訪問令牌響應丟失」改了稱呼。
  2. 更改了 「我」 的GET請求 「myOrganization」 的URI,看完這個: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..." 
} 

問題:

  1. 我有管理員登記在Azure的AD應用程序,並檢查盒爲所需的Microsoft Graph API應用程序的權限。顯然這還不夠。還需要什麼?爲什麼權限不在訪問令牌響應正文中?
  2. GET請求的正確URI是什麼? 「MyOrganization」是URI中的正確值嗎?
+0

錯誤是.NET中經典的NullReferenceException。可能是API中的一個錯誤,或者是它預期的錯誤。似乎不是一個權限問題。 – juunas

回答

1

非常感謝您的回覆。經過更多的研究,我找到了我的問題的答案。

原來的問題: 「微軟圖形API返回對象引用不設置到對象的實例」

請求

GET https://graph.microsoft.com/v1.0/me/drive/root/children 
Authorization: Bearer eyJ0eXAiOiJKV1QiLCJub25jZSI6... 

獲得響應

{ 
    "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指出,/me指的是當前登錄的用戶。在我們的情況下,我們沒有登錄用戶,所以我們不能使用/me。相反,我們可以使用/myOrganization或者什麼都不用,它是可選的。

更新的問題: 「Azure的AD 」範圍「 屬性從訪問令牌響應丟失」

更新(替換/我/ myOrganization)請求

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" 
    } 
    } 
} 

As @ SriramDhanasekaran-MSFT和@ DanKershaw-MSFT提到,access_token響應錯失了scope屬性是管理員未在Azure AD中「授予」權限。

然而,@ SriramDhanasekaran-MSFT提供的解決方案:

https://login.microsoftonline.com/common/oauth2/authorize?client_id=&response_type=code&redirect_uri=http://localhost&resource=https://graph.microsoft.com&prompt=consent 

並不能幫助我,因爲我的應用程序沒有一個redirect uri。授予權限的解決方案比此更簡單:只需讓管理員登錄到Azure AD,然後單擊「授予權限」鏈接即可授予權限。

此外,/myOrganization/driver/root/children列出了管理員的驅動器的內容。正如@ PeterPan-MSFT所述,要列出其他用戶的驅動器,請將/myOrganization替換爲/users/<user-id>

成功:

我的應用程序現在可以在線編輯我的Excel電子表格,而無需人類用戶的干預。與@PiePAN-MSFT所說的相反,這可以通過圖形API實現,無需下載Excel電子表格並離線編輯。

總結:

有兩個問題:(1)使用/me和(2)的應用程序的權限沒有被在天青AD由管理員批准。

0

由於正在使用client_credential令牌流(即,沒有經過身份驗證的用戶上下文),因此/ me的任何請求都無效,因爲/ me是指當前登錄的用戶。如果您訪問用戶驅動器中的文件,請嘗試使用授權令牌。

要訪問Sharepoint中的根驅動器,請求url是/ drive/root/children(myorganization是可選的)。

關於丟失索賠,管理員必須同意該應用程序。您可以強制同意通過詢問管理員訪問以下網址(與您的應用的替換)

https://login.microsoftonline.com/common/oauth2/authorize?client_id= & RESPONSE_TYPE =代碼& REDIRECT_URI = http://localhost&resource=https://graph.microsoft.com&prompt=consent

+0

只需添加Sriram的答案。一旦您獲得管理員同意(可能需要將redirect_uri與您的應用註冊的內容相匹配),您現在將在訪問令牌中看到* roles *聲明,該聲明表示授予的角色(或應用程序權限)到應用程序(使用client_credential流程時)。注意:如果您使用委託(代碼)流程,您會在訪問令牌中找到* scp *聲明。 –

0

正如@juunas說,低於第一錯誤的信息應該是.NET中的NULL異常在服務器端引起,但也不是API錯誤或權限問題。

error": { 
    "code": "InternalServerError", 
    "message": "Object reference not set to an instance of an object.", 

您可以參考SO thread知道這種情況下,這似乎是更新後端,請稍後再試。

要爲第二個錯誤,當您在圖形API URL改變了選項memyOrganization,如@ SriramDhanasekaran-MSFT解釋,它的訪問文件爲當前用戶或<user-id>代替me指定的用戶。

但是,根據我的理解,您要編輯一個適用於您的組織的SharePoint電子表格,它似乎不適合通過使用Graph API。根據我的經驗,應該通過使用OneDrive for Business的API將Excel文件複製到本地來編輯&上傳來覆蓋它,請參閱the dev documents for OneDrive並嘗試使用the API for drive resource

希望它有幫助。

相關問題