2016-12-28 9 views
1

Я пишу скрипт Python для редактирования электронной таблицы Excel, которая живет в SharePoint. У нас есть офис 365 для бизнеса. Я использую Microsoft Graph API. Я зарегистрировал приложение Python с помощью Microsoft Azure Active Directory (AD) и добавил следующие разрешения (для приложения) для Graph API: (1) Чтение и запись файлов во всех семействах сайтов (предварительный просмотр) и (2) Чтение данных каталога , (У меня был наш администратор компании зарегистрировать приложение для меня.)Azure AD: свойство «scope», отсутствующее из тела ответа Token Response

Моего 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) 

Питон приложения успешно запрашивает и получает access_token с сервера Microsoft. Маркер доступа начинается как этот

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).

EDIT:

  1. Изменено название от "Microsoft Graph API Возвращает Object ссылка не указывает на экземпляр объекта" в "Azure AD "Сфера" Missing из маркера доступа Response".
  2. Изменено «меня» в Ури запроса GET к «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, я вижу, что тело маркеров доступа ответ содержит свойство «Scope», в котором перечислены разрешения, предоставленные для приложения во время регистрации приложения. Тем не менее, ответ маркера доступа, который я получаю с сервера, не имеет свойства «scope». Вот как выглядит мой токен доступа.

{ 
"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 и установите флажки для разрешений приложений API Microsoft Graph необходимо. По-видимому, этого недостаточно. Что еще нужно? Почему разрешения отсутствуют в теге ответа на токен?
  2. Каков правильный URI для запроса GET? Является ли «MyOrganization» правильное значение в URI?
+0

Ошибка в классическом исключении NullReferenceException в .NET. Может быть ошибкой в ​​API, или чего-то не хватает, чего он ожидал. Не похоже на проблему с разрешением. – juunas

ответ

1

Спасибо всем за ваши ответы. После дальнейших исследований я нашел ответ на свой вопрос.

Исходная задача: "Microsoft Graph API Возвращает Object ссылка не указывает на экземпляр объекта"

Запрос

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 "Сфера" Свойство Отсутствующее из маркеров доступа Response"

Обновленные (заменяет/меня/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>.

Success:

Мое приложение теперь может редактировать свои таблицы Excel в Интернете, без вмешательства пользователя-человека. Вопреки тому, что указано в PeterPan-MSFT, это возможно с помощью Graph API, и нет необходимости загружать электронную таблицу Excel и редактировать офлайн.

Резюме:

Были две проблемы: (1) с использованием /me и (2) разрешения приложения не было предоставлено в Azure AD администратором.

0

Поскольку используется поток токена client_credential (т. Е. Не существует аутентифицированного контекста пользователя), любой запрос с/me недействителен, так как/me относится к текущему пользователю с подписью.Попробуйте с делегированным токеном, если вы хотите получить доступ к файлам на диске пользователя.

Чтобы получить доступ к корневому диску в Sharepoint, запросите url is/drive/root/children (моя организация не является обязательной).

Что касается недостающих требований, администратор должен согласиться с приложением. Вы можете заставить согласие, попросив администратора для доступа к ниже URL (заменить, что из вашего приложения)

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

+0

Просто добавьте ответ Шрирам. Если у вас есть согласие администратора, как указано (возможно, вам нужно будет сопоставить redirect_uri с тем, что вы зарегистрировали для своего приложения), теперь вы увидите заявку * role * в токене доступа, в котором указаны роли (или разрешения приложений) к приложению (при использовании потока client_credential). ПРИМЕЧАНИЕ. В токене доступа вы найдете запрос * scp *, если вы используете поток делегированных (кодовых). –

0

Как сказал @juunas, первая информация об ошибке должна быть исключение NULL в .NET, которое должно быть вызвано на сервере, но также не ошибка API или проблема с разрешением.

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

Вы можете обратиться к SO thread знать этот случай, который, кажется, обновление для внутреннего интерфейса, пожалуйста, повторите попытку позже.

Для объяснения для второй ошибки, когда вы изменили параметр me к myOrganization в API URL Graph, так как @ SriramDhanasekaran-MSFT, это доступ к файлам для текущего пользователя или конкретного пользователя с <user-id> вместо me.

Однако, исходя из моего понимания, вы хотите редактировать электронную таблицу Excel, проживавшую в SharePoint для вашего orgnization, кажется, что это не подходит с помощью Graph API. По моему опыту, это должно быть сделано с помощью API OneDrive для бизнеса, чтобы скопировать файл Excel в локальный, чтобы загрузить &, чтобы перезаписать его, пожалуйста, обратитесь к the dev documents for OneDrive и попробуйте использовать the API for drive resource.

Надеюсь, это поможет.

 Смежные вопросы

  • Нет связанных вопросов^_^