Получить токен доступа авторизации с помощью /token endpoint
Я работаю над созданием приложения на Python, которое будет использовать API-интерфейсы Microsoft Security Graph. Я следовал за примером, представленным здесь без проблем. Теперь я хочу иметь возможность создавать приложение Python, которое может получить токен доступа (и обновить его при необходимости) без использования веб-браузера.
До сих пор я создал новое приложение с SecurityEvent.Read.All
а также SecurityEvent.ReadWrite.All
разрешения под обоими Delegated Permissions
а также Application Permissions
, Затем я зашел по следующему адресу в веб-браузере, чтобы дать согласие на мое приложение, и вошел в систему с администратором клиента:
https://login.microsoftonline.com/common/adminconsent?
client_id=APPLICATION_ID
&state=12345
&redirect_uri=REDIRECT_URL
Далее я предполагаю, что хочу выполнить описанные здесь шаги, чтобы выполнить вызов POST для получения токена. Ниже приведен пример того, как я это делаю.
d = {
"client_id": <client_id>,
"scope": ["https://graph.microsoft.com/.default"],
"client_secret": <client_secret>,
"grant_type": "client_credentials"
}
r = requests.post("https://login.microsoftonline.com/common/oauth2/v2.0/token", data=d)
Ниже приводится ответ, который я получаю
{
"token_type": "Bearer",
"expires_in": 3600,
"ext_expires_in": 0,
"access_token": "eyJ0eXAiOiJKV1QiLCJub25jZSI6IkFRQUJBQUFBQUFDNXVuYTBFVUZnVElGOEVsYXh0V2pUR2cxQV9PR0FJWmx3T1V0b2hMNHdWN2hURHVoQTJSTzIyQnY0cGljcGJ2UmkwdEdpcmY0Q2cxaDhRZF9RamUzX2l0LUhfT1VhTnJRaDFxYXpINWtIRENBQSIsImFsZyI6IlJTMjU2IiwieDV0IjoiaTZsR2szRlp6eFJjVWIyQzNuRVE3c3lISmxZIiwia2lkIjoiaTZsR2szRlp6eFJjVWIyQzNuRVE3c3lISmxZIn0.eyJhdWQiOiJodHRwczovL2dyYXBoLm1pY3Jvc29mdC5jb20iLCJpc3MiOiJodHRwczovL3N0cy53aW5kb3dzLm5ldC83MmY5ODhiZi04NmYxLTQxYWYtOTFhYi0yZDdjZDAxMWRiNDcvIiwiaWF0IjoxNTQwNDE3MjI0LCJuYmYiOjE1NDA0MTcyMjQsImV4cCI6MTU0MDQyMTEyNCwiYWlvIjoiNDJSZ1lMRDUvK2RINkplbC9EK1RHRmZlaVNqMUJnQT0iLCJhcHBfZGlzcGxheW5hbWUiOiJTZWN1cml0eSBHcmFwaCBQT0MiLCJhcHBpZCI6IjMxMjA0MGRmLWIyZmUtNDI1Ni04ZWZkLTk1NDYyOTVjNWZhNyIsImFwcGlkYWNyIjoiMSIsImlkcCI6Imh0dHBzOi8vc3RzLndpbmRvd3MubmV0LzcyZjk4OGJmLTg2ZjEtNDFhZi05MWFiLTJkN2NkMDExZGI0Ny8iLCJ0aWQiOiI3MmY5ODhiZi04NmYxLTQxYWYtOTFhYi0yZDdjZDAxMWRiNDciLCJ1dGkiOiJnLUtlY1dkZXcwQzV2cjBoLUhGZ0FBIiwidmVyIjoiMS4wIiwieG1zX3RjZHQiOjEyODkyNDE1NDd9.JGu6fjJk_vVvG_4NYRBfZto6nW9YRWh43JzhrlcFqFYAnJSJvWDlHbzka_H3gUKkZernQanzjI6AumER9mOtapmj1qhu_58pCuL2lTl2ubj1MTBTYOpUX3hlKgN16AeyvjO1x95LKDO9xAcIYLXEmwbkNw87x7YxZ1lKBA59c1BCCILmqMf86E7CDExf7EPqbqAPdCI6FPkStx5CJ0YnvAN2Uk5EHloTL3BTXMqMmT05h7OAvZRogkIk4aeGof1OXKcqXw7dJbzYg8XiEeXdAYhA1ld6VEwiVBMSpqf4w476Ksvr8JUbg-xhAmGoU8CrXBB4em5Gv2ko89-qP49nUA"
}
Получив токен доступа, я пытаюсь вызвать /alerts
конечная точка. Ниже описано, как это делается.
headers = {
"Content-type": "application/json",
"Authorization": "Bearer " + <access_token>,
}
alerts = requests.get("https://graph.microsoft.com/v1.0/security/alerts", headers=headers)
Вместо того, чтобы возвращать оповещения, вот как выглядит ответ для меня:
{
"error": {
"code": "UnknownError",
"message": "Auth token does not contain valid permissions or user does not have valid roles. Please see document at https://techcommunity.microsoft.com/t5/Using-Microsoft-Graph-Security/Authorization-and-Microsoft-Graph-Security-API/m-p/184376",
"innerError": {
"request-id": "1319d099-7b14-4eb0-9834-4614d5231085",
"date": "2018-10-24T21:23:16"
}
}
}
У меня как-то неправильные разрешения?
2 ответа
Ты очень близко. Проблема здесь в том, что scope
значение https://graph.microsoft.com/v1.0/security/alerts/.default
это неверно.
Если вы хотите использовать API-интерфейсы безопасности, вы можете включить либо SecurityEvents.Read.All
или же SecurityEvents.ReadWrite.All
в регистрации вашего приложения (через https://apps.dev.microsoft.com/).
Важно: Всякий раз, когда вы изменяете области для своего приложения, вы должны повторять процесс согласия администратора. Согласие администратора применимо только к областям, которые вы настроили во время предоставления согласия.
Как только это будет завершено, вам нужно сообщить /token
конечная точка для использования предварительно зарегистрированных областей. Это делается путем установки scope
собственность на https://graph.microsoft.com/.default
, То, что вы делаете здесь, говорит, что вы хотите использовать Предварительно зарегистрирован (.default
) Области применения для Microsoft Graph (https://graph.microsoft.com/
):
d = {
"client_id": <client_id>,
"scope": ["https://graph.microsoft.com/.default"],
"client_secret": <client_secret>,
"grant_type": "client_credentials"
}
r = requests.post("https://login.microsoftonline.com/{tenant}/oauth2/v2.0/token", data=d)
ОБНОВИТЬ
Существует дополнительная проблема с /token
конечная точка, которую вы используете. Когда используешь client_credentials
Вы не можете использовать /common
арендатор. Поскольку пользователь не проходит аутентификацию, AAD не может определить, против какого клиента он должен аутентифицироваться. Не зная, какой арендатор не может определить, какие области должны применяться, что, в свою очередь, приводит к получению токена без каких-либо областей.
Вам необходимо явно указать идентификатор клиента, для которого вы хотите получить токен. Вы можете использовать идентификатор арендатора (GUID) или домен:
https://login.microsoftonline.com/00000000-0000-0000-0000-000000000000/oauth2/v2.0/token
https://login.microsoftonline.com/tenantdomain.onmicrosoft.com/oauth2/v2.0/token
Почему это возвращается мне? Я пропускаю шаг?
Вы путаете Graph API и AAD Graph API. Для реализации потока учетных данных клиента вы должны следовать следующим документам:
Register your app. Configure permissions for Microsoft Graph on your app. Get administrator consent. Get an access token. Use the access token to call Microsoft Graph.
И больше информации о том, как использовать Graph Security API.