Я работаю над созданием приложения на Python, которое будет использовать API Microsoft Security Graph. Я без проблем следовал образцу, представленному здесь. Теперь я хочу иметь возможность создать приложение на Python, которое может получать токен доступа (и обновлять его при необходимости) без использования веб-браузера.

До сих пор я создал новое приложение с разрешениями SecurityEvent.Read.All и SecurityEvent.ReadWrite.All под Delegated Permissions и Application Permissions. Затем я перешел по следующему URL-адресу в веб-браузере, чтобы дать согласие на мое приложение, и вошел в систему со своим администратором клиента:

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

У меня как-то неправильные разрешения?

1
walshbm15 24 Окт 2018 в 02:19

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)

< Сильный > UPDATE

Существует дополнительная проблема с конечной точкой /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
0
Marc LaFleur 25 Окт 2018 в 13:25

Почему мне это возвращают? Я пропустил шаг?

Вы путаете 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.

0
Seiya Su 24 Окт 2018 в 04:55
52959033