В настоящее время я работаю над ботом Microsoft Teams, который предназначен для загрузки файлов в OneDrive, чтобы поделиться URL-адресом с пользователем на основе запроса чата. Тем не менее, я сталкиваюсь с повторяющейся проблемой с сообщением об ошибке «В токене должно присутствовать утверждение scp или roles».
Вот разбивка того, что я делаю, и шаги, которые я предпринял:
Шаг 1: Первоначальный запрос аутентификации
Я инициирую процесс аутентификации со следующим запросом POST:
POST /<MY TENANT ID>/oauth2/token HTTP/1.1
Host: login.microsoftonline.com
Authorization: Bearer <MY ACCESS TOKEN>
grant_type=client_credentials&client_id=<MY APP ID>&client_secret=<MY APP PASSWORD>&resource=https%3A%2F%2Fgraph.microsoft.com
Это успешно возвращает токен доступа носителя, который я использую для дальнейших взаимодействий.
Шаг 2: Запрос на загрузку файла
Имея на руках токен доступа, я загружаю текстовый файл, содержащий только содержимое «Hello world». Вот запрос POST, который я использую:
POST /v1.0/drive/root:/filename.txt:/content HTTP/1.1
Host: graph.microsoft.com
Authorization: Bearer <MY ACCESS TOKEN>
Content-Type: text/plain
hello_world
Однако ответ, который я получаю:
{"error": {"code": "AccessDenied", "message": "Either scp or roles claim need to be present in the token.", "innerError": {"date": "2023-08-11T20:51:52", "request-id": "e7bb0afc-d6ce-348e-b6cf-7cba046e70b4", "client-request-id": "e7bb0afc-d6ce-4f07-b6cf-7cba046e7222"}}}
Мои вопросы:


Ошибка обычно возникает, если вы пропустили добавление необходимого разрешения API при регистрации приложения или пропустили предоставление согласия администратора на него.
Я зарегистрировал одно приложение Azure AD и добавил разрешение Files.ReadWrite.All типа приложения, добавив согласие:

Теперь я сгенерировал токен доступа, используя поток учетных данных клиента через Postman со следующими параметрами:
POST https://login.microsoftonline.com/tenantID/oauth2/v2.0/token
grant_type:client_credentials
client_id: appID
client_secret: secret
scope: https://graph.microsoft.com/.default
Ответ:

Чтобы проверить, есть ли у токена разрешение или нет, вы можете расшифровать его, вставив токен в jwt.ms и найти в нем roles требование:

Теперь используйте приведенный ниже запрос PUT, чтобы загрузить текстовый файл, содержащий только содержимое «Hello world», включив в него userID:
PUT https://graph.microsoft.com/v1.0/users/<userID>/drive/root:/srifile.txt:/content
Authorization: Bearer <MY ACCESS TOKEN>
Content-Type: text/plain
hello_world
Ответ:

Чтобы подтвердить это, я проверил то же самое в OneDrive пользователя, где файл был успешно создан, как показано ниже:

Когда я открыл вышеуказанный текстовый файл, в нем есть hello_world:

Обратите внимание, что предоставление разрешения Files.ReadWrite.All типа приложения позволяет приложению читать, создавать, обновлять и удалять все файлы во всех семействах сайтов без входа пользователя. Чтобы убедиться в этом, вы можете проверить этот MS Doc.
Если вы предпочитаете наименьшие привилегии, вам нужно перейти на делегированные потоки, такие как поток кода авторизации, пароль имени пользователя и т. д., для создания токена и предоставления разрешений типа Delegated, которые дают доступ только к файлам вошедшего пользователя, ссылаясь на это MS Doc в зависимости от ваших требований.
Ааа ок попался. Поскольку это крупная организация, я предполагаю, что они не дадут такого разрешения, поскольку это откроет значительно больше доступа, чем необходимо. Жаль, что нет специального разрешения только для приложения, чтобы обмениваться файлами туда и обратно, не подвергая чрезмерному доступу или требуя взаимодействия пользователя с аутентификацией. Я очень ценю помощь!
Это очень полезно - спасибо! Знаете ли вы, предоставит ли разрешение Files.ReadWrite.All доступ для чтения/записи ко всем сайтам sharepoint или это зависит от приложения? У меня нет доступа к нашему порталу Azure, но мне дали зеленый свет, и я просто сообщу об этом ИТ-отделу, чтобы они могли его одобрить, но хотел убедиться, что это не создаст угрозы безопасности, разрешив доступ к другие сайты.