Платформа удостоверений Майкрософт и поток учетных данных клиента OAuth 2.0

Предоставление учетных данных клиента OAuth 2.0, указанное в спецификации RFC 6749, которое иногда называют также двусторонним OAuth, можно использовать для доступа к интернет-ресурсам с помощью удостоверения приложения. Этот тип предоставления разрешения часто используется для взаимодействия между серверами, которое должно выполняться в фоновом режиме без непосредственного взаимодействия с пользователем. Такие типы приложений часто называют управляющими программами или учетными записями служб.

В этой статье описывается, как программировать непосредственно в протокол в приложении. По возможности рекомендуется использовать поддерживаемые библиотеки проверки подлинности Майкрософт (MSAL) вместо получения маркеров и вызова защищенных веб-API. Также ознакомьтесь с примерами приложений, которые используют MSAL. Стоит отметить, что маркеры обновления никогда не будут предоставляться с этим потоком, поскольку client_id и client_secret (которые потребуются для получения маркера обновления) могут быть использованы для получения маркера доступа.

Поток предоставления учетных данных клиента OAuth 2.0 позволяет веб-службе (конфиденциальному клиенту) при вызове другой веб-службы проходить проверку подлинности с собственными учетными данными, а не олицетворять пользователя. Для большей надежности платформа удостоверений Майкрософт также позволяет вызывающей службе проходить проверку подлинности с помощью сертификата или федеративных учетных данных вместо общего секрета. Так как используются собственные учетные данные приложений, эти данные должны храниться в надежном состоянии — нельзя публиковать их в исходном коде, внедрять в веб-страницы или использовать в широко распространенном собственном приложении.

В потоке учетных данных клиента разрешения дает администратор непосредственно самому приложению. Когда приложение предоставляет маркер для ресурса, то для выполнения действия этот ресурс требует авторизацию приложения, поскольку в авторизации не участвует пользователь. В этой статье описаны действия, необходимые для авторизации приложения для вызова API, а также способы получения маркеров, необходимых для вызова этого API.

Совет

Попытайтесь выполнить этот запрос в Postman
Попробуйте выполнить этот запрос и многое другое в Postman — не забудьте заменить токены и идентификаторы!

Схема протокола

Весь поток учетных данных клиента аналогичен приведенному на следующей схеме. Каждый из этих шагов мы опишем далее в этой статье.

Схема, на которой показан поток учетных данных клиента

Получение прямой авторизации

Как правило, приложение получает прямую авторизацию на доступ к ресурсу двумя способами:

Эти два метода являются самыми распространенными в Azure AD, и их рекомендуется использовать для клиентов и ресурсов, применяющих поток учетных данных клиента. Ресурс также может выбрать другой способ авторизации клиентов. Каждый сервер ресурсов может выбрать метод, являющийся наиболее оптимальным для приложения.

Доступ к спискам управления

Поставщик ресурсов может принудительно применять проверку авторизации на основе списка известных идентификаторов приложений (клиента), а также предоставлять определенный уровень доступа на основе этих идентификаторов. Когда ресурс получает маркер из платформы удостоверений Майкрософт, он может расшифровать этот маркер и извлечь идентификатор приложения клиента из утверждений appid и iss. Затем он проверяет наличие приложения в действующем списке управления доступом. Детализация и методы использования списка управления доступом для разных ресурсов могут значительно отличаться.

Нередко список управления доступом используется для выполнения тестов веб-приложения или веб-API. Веб-API может предоставить определенному клиенту только ограниченный набор прав доступа. Для выполнения комплексных тестов API создайте тестовый клиент, получающий маркеры от платформы удостоверений Майкрософт и отправляющий их в API. Затем API может проверить идентификатор приложения тестового клиента с помощью списка управления доступом для предоставления доступа ко всем возможностям API. При использовании такого списка управления доступом нужно не только проверить значение appid вызывающей стороны, но и убедиться в надежности значения iss маркера.

Данный тип авторизации часто используется в управляющих программах и учетных записях служб, которым требуется доступ к данным пользователей, являющихся потребителями с личной учетной записью Майкрософт. Необходимую авторизацию для доступа к корпоративным данным рекомендуется получать с помощью разрешений приложения.

Управление маркерами без утверждения roles

Чтобы включить этот шаблон авторизации на основе ACL, в Azure AD не требуется, чтобы приложения имели разрешения на получение маркеров для другого приложения. То есть маркеры только для приложений могут быть выданы без roles утверждения. Приложения, которые предоставляют API, должны использовать проверки разрешений для того, чтобы они могли принять маркеры.

Если вы хотите запретить приложениям получать в приложении маркеры только для приложений без ролей, убедитесь, что для приложения включены требования к назначению. Это позволит пользователям и приложениям без назначенных ролей получить маркер для этого приложения.

Разрешения приложения

Вместо списков управления доступом можно использовать интерфейсы API, чтобы предоставлять набор разрешений для приложения. Администратор организации предоставляет приложению разрешения, которые можно использовать только для доступа к данным, принадлежащим этой организации и ее сотрудникам. Например, Microsoft Graph предоставляет несколько разрешений приложений для следующих действий:

  • чтение почты во всех почтовых ящиках;
  • чтение и запись почты во всех почтовых ящиках;
  • отправка почты любым пользователем;
  • Чтение данных каталога

Чтобы использовать роли приложений (разрешения приложения) с собственным API (не относящимися к Microsoft Graph), необходимо сначала определить роли приложений для регистрации приложения API на портале Azure. Затем нужно предоставить необходимые роли приложений, выбрав эти разрешения при регистрации клиентского приложения. Если вы не укажете роли приложения при регистрации приложения API, вы не сможете предоставить разрешения приложения для этого API при регистрации клиентского приложения на портале Azure.

При проверке подлинности приложения (в отличие от пользователя) нельзя использовать делегированные разрешения, потому что не существует пользователя, от имени которого ваше приложение могло бы выполнять операции. Необходимо использовать разрешения приложения, которые называются ролями приложения и предоставляются администратором или владельцем API.

Дополнительные сведения о разрешениях приложения см. в статье Разрешения и согласие.

Обычно при создании приложения, использующего разрешения, для него нужно настроить страницу или представление, в котором администратор может утвердить разрешения приложения. Эта страница может быть частью потока входа в приложение, параметров приложения или выделенного потока подключения. Во многих случаях разумно отображать это представление подключения в приложении только после того, как пользователь выполнил вход с помощью учебной или рабочей учетной записи Майкрософт.

Если используется вход пользователя в приложение, то вы можете определить организацию, к которой он принадлежит, прежде чем запрашивать у пользователя утверждение разрешений приложения. Хотя это не обязательно, таким образом можно сделать пользовательский интерфейс более интуитивно понятным. Чтобы войти в систему как пользователь, следуйте рекомендациями в Руководстве по протоколу платформы удостоверений Майкрософт.

Запрос разрешений у администратора каталога

Когда вы будете готовы запросить разрешения у администратора организации, можно будет перенаправить пользователя к конечной точке предоставления согласия администратора платформы удостоверений Майкрософт.

// Line breaks are for legibility only.

GET https://login.microsoftonline.com/{tenant}/adminconsent?
client_id=6731de76-14a6-49ae-97bc-6eba6914391e
&state=12345
&redirect_uri=http://localhost/myapp/permissions

Совет от профессионала! Попробуйте выполнить следующий запрос в браузере.

https://login.microsoftonline.com/common/adminconsent?client_id=6731de76-14a6-49ae-97bc-6eba6914391e&state=12345&redirect_uri=http://localhost/myapp/permissions
Параметр Условие Описание
tenant Обязательно Клиент каталога, из которого необходимо запросить разрешение. Его можно указать в виде GUID или понятного имени. Если неизвестно, какому клиенту относится пользователь, и нужно обеспечить его вход с помощью любого клиента, используйте common.
client_id Обязательно Идентификатор приложения (клиента) , назначенный вашему приложению функцией Регистрация приложений портала Azure.
redirect_uri Обязательно Универсальный код ресурса (URI) перенаправления, на который нужно направлять ответ для обработки в приложении. Он должен в точности соответствовать одному из универсальных кодов ресурсов (URI) перенаправления, зарегистрированных на портале, но иметь вид URL-адреса. Он может содержать дополнительные сегменты пути.
state Рекомендуемая Значение, включенное в запрос, которое также возвращается в ответе маркера. Это может быть строка любого контента. Параметр state используется для кодирования сведений о состоянии пользователя в приложении перед созданием запроса на аутентификацию, например сведений об открытой на тот момент странице или представлении.

На этом этапе Azure AD обеспечивает вход только администратора клиента для выполнения запроса. Администратору будет предложено утвердить все непосредственные разрешения, запрошенные для приложения на портале регистрации приложений.

Успешный ответ

Если администратор утверждает разрешения для приложения, успешный ответ будет выглядеть следующим образом.

GET http://localhost/myapp/permissions?tenant=a8990e1f-ff32-408a-9f8e-78d3b9139b95&state=state=12345&admin_consent=True
Параметр Описание
tenant Клиент каталога, предоставивший приложению запрошенные разрешения в формате GUID.
state Значение, добавленное в запрос, которое также возвращается в ответе маркера. Это может быть строка любого контента. Параметр state используется для кодирования сведений о состоянии пользователя в приложении перед созданием запроса на аутентификацию, например сведений об открытой на тот момент странице или представлении.
admin_consent Присвойте значение True.
Сообщение об ошибке

Если администратор не утверждает разрешения для приложения, сообщение о неудачном выполнении будет выглядеть следующим образом.

GET http://localhost/myapp/permissions?error=permission_denied&error_description=The+admin+canceled+the+request
Параметр Описание
error Строка кода ошибки, которую можно использовать для классификации типов ошибок и реагирования на ошибки.
error_description Конкретное сообщение об ошибке, с помощью которого можно определить первопричину возникновения ошибки.

После получения успешного ответа от конечной точки подготовки приложения приложение получило запрошенные непосредственные разрешения. Теперь вы можете запросить маркер для ресурса, который вам нужен.

Получение маркера

Авторизовав приложение, можно переходить к получению маркеров доступа для интерфейсов API. Для получения маркера путем предоставления учетных данных клиента отправьте запрос POST к платформе удостоверений Майкрософт /token:

Первый пример. Запрос маркера доступа по общему секрету

POST /{tenant}/oauth2/v2.0/token HTTP/1.1           //Line breaks for clarity
Host: login.microsoftonline.com
Content-Type: application/x-www-form-urlencoded

client_id=535fb089-9ff3-47b6-9bfb-4f1264799865
&scope=https%3A%2F%2Fgraph.microsoft.com%2F.default
&client_secret=sampleCredentia1s
&grant_type=client_credentials
# Replace {tenant} with your tenant!
curl -X POST -H "Content-Type: application/x-www-form-urlencoded" -d 'client_id=535fb089-9ff3-47b6-9bfb-4f1264799865&scope=https%3A%2F%2Fgraph.microsoft.com%2F.default&client_secret=qWgdYAmab0YSkuL1qKv5bPX&grant_type=client_credentials' 'https://login.microsoftonline.com/{tenant}/oauth2/v2.0/token'
Параметр Условие Описание
tenant Обязательно Клиент каталога, который будет использовать приложение, в формате GUID или доменного имени.
client_id Обязательно Идентификатор приложения, назначенный приложению. Эти сведения можно найти на портале, где вы зарегистрировали свое приложение.
scope Обязательно Значение, передаваемое для параметра scope в этом запросе, должно быть идентификатором требуемого ресурса (универсальным кодом ресурса (URI) идентификатора приложения) с суффиксом .default. В примере Microsoft Graph используется значение https://graph.microsoft.com/.default.
Это значение сообщает платформе удостоверений Майкрософт, что среди всех непосредственных разрешений, настроенных для приложения, она должна выдать маркер для тех, которые связаны с требуемым ресурсом. Дополнительные сведения об области /.default можно найти в документации о согласии здесь.
client_secret Обязательно Секрет клиента, который вы создали для приложения на портале регистрации приложений. Секрет клиента должен быть закодирован в формат URL-адреса перед отправкой. Также поддерживается шаблон базовой аутентификации вместо предоставления учетных данных в заголовке авторизации согласно RFC 6749.
grant_type Обязательно Нужно задать значение client_credentials.

Второй пример. Запрос маркера доступа по сертификату

POST /{tenant}/oauth2/v2.0/token HTTP/1.1               // Line breaks for clarity
Host: login.microsoftonline.com
Content-Type: application/x-www-form-urlencoded

scope=https%3A%2F%2Fgraph.microsoft.com%2F.default
&client_id=97e0a5b7-d745-40b6-94fe-5f77d35c6e05
&client_assertion_type=urn%3Aietf%3Aparams%3Aoauth%3Aclient-assertion-type%3Ajwt-bearer
&client_assertion=eyJhbGciOiJSUzI1NiIsIng1dCI6Imd4OHRHeXN5amNScUtqRlBuZDdSRnd2d1pJMCJ9.eyJ{a lot of characters here}M8U3bSUKKJDEg
&grant_type=client_credentials
Параметр Условие Описание
tenant Обязательно Клиент каталога, который будет использовать приложение, в формате GUID или доменного имени.
client_id Обязательно Идентификатор приложения (клиента), который назначен приложению.
scope Обязательно Значение, передаваемое для параметра scope в этом запросе, должно быть идентификатором требуемого ресурса (универсальным кодом ресурса (URI) идентификатора приложения) с суффиксом .default. В примере Microsoft Graph используется значение https://graph.microsoft.com/.default.
Это значение сообщает платформе удостоверений Майкрософт, что среди всех непосредственных разрешений, настроенных для приложения, точка должна выдать маркер для тех, которые связаны с требуемым ресурсом. Дополнительные сведения об области /.default можно найти в документации о согласии здесь.
client_assertion_type Обязательно Его значением должно быть urn:ietf:params:oauth:client-assertion-type:jwt-bearer.
client_assertion Обязательно Утверждение (JSON Web Token), которое необходимо создать и подписать с помощью сертификата, зарегистрированного как учетные данные для приложения. Ознакомьтесь с информацией об учетных данных сертификата, чтобы узнать, как зарегистрировать сертификат и задать формат утверждения.
grant_type Обязательно Нужно задать значение client_credentials.

Параметры запроса на основе сертификата отличаются от запроса на основе общего секрета только одним: параметр client_secret заменяется параметрами client_assertion_type и client_assertion.

Третий пример: запрос маркера доступа с федеративными учетными данными

POST /{tenant}/oauth2/v2.0/token HTTP/1.1               // Line breaks for clarity
Host: login.microsoftonline.com
Content-Type: application/x-www-form-urlencoded

scope=https%3A%2F%2Fgraph.microsoft.com%2F.default
&client_id=97e0a5b7-d745-40b6-94fe-5f77d35c6e05
&client_assertion_type=urn%3Aietf%3Aparams%3Aoauth%3Aclient-assertion-type%3Ajwt-bearer
&client_assertion=eyJhbGciOiJSUzI1NiIsIng1dCI6Imd4OHRHeXN5amNScUtqRlBuZDdSRnd2d1pJMCJ9.eyJ{a lot of characters here}M8U3bSUKKJDEg
&grant_type=client_credentials
Параметр Условие Описание
client_assertion Обязательно Утверждение (JWT или JSON Web Token), которое приложение получает от другого поставщика удостоверений за пределами платформы идентификаторов Майкрософт, например Kubernetes. Особенности этого JWT должны быть зарегистрированы в приложении как учетные данные федеративного удостоверения. Ознакомьтесь со сведениями о федерации удостоверений рабочей нагрузки, чтобы узнать, как настроить и использовать утверждения, созданные другими поставщиками удостоверений.

Все в запросе аналогично приведенному выше потоку на основе сертификата, но с одним важным исключением — источником client_assertion. В этом потоке приложение не создает утверждение JWT. Вместо этого приложение использует JWT, созданное другим поставщиком удостоверений. Это называется федерацией удостоверений рабочей нагрузки, где удостоверение приложений в другой платформе удостоверений используется для получения маркеров внутри платформы удостоверений Майкрософт. Это лучше всего подходит для сценариев между облаками, например для размещения вычислительных ресурсов за пределами Azure с получением доступа к API, защищенным платформой удостоверений Майкрософт. Дополнительные сведения о формате JWT, созданных другими поставщиками удостоверений, см. в статье о формате утверждения.

Успешный ответ

Успешный ответ любого из методов выглядит следующим образом:

{
  "token_type": "Bearer",
  "expires_in": 3599,
  "access_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6Ik1uQ19WWmNBVGZNNXBP..."
}
Параметр Описание
access_token Запрашиваемый маркер доступа. Приложение может использовать этот маркер для аутентификации в защищенном ресурсе, таком как веб-API.
token_type Указывает значение типа маркера. Платформа удостоверений Майкрософт поддерживает только тип bearer.
expires_in Срок действия маркера доступа (в секундах).

Предупреждение

Не пытайтесь проверить или прочесть маркеры для любого API, который вам не принадлежит, включая маркеры в этом примере, в коде. Маркеры для служб Майкрософт могут использовать специальный формат, который не будет проверяться как JWT и может также быть зашифрован для пользователей-потребителей (учетная запись Майкрософт). Несмотря на то, что чтение маркеров является полезным средством отладки и обучения, не задавайте зависимости от него в коде или не опирайтесь на конкретные сведения о токенах, которые не предназначены для контролируемого вами API.

Сообщение об ошибке

Ответ с ошибкой (400 Bad Request (недопустимый запрос)) выглядит следующим образом:

{
  "error": "invalid_scope",
  "error_description": "AADSTS70011: The provided value for the input parameter 'scope' is not valid. The scope https://foo.microsoft.com/.default is not valid.\r\nTrace ID: 255d1aef-8c98-452f-ac51-23d051240864\r\nCorrelation ID: fb3d2015-bc17-4bb9-bb85-30c5cf1aaaa7\r\nTimestamp: 2016-01-09 02:02:12Z",
  "error_codes": [
    70011
  ],
  "timestamp": "2016-01-09 02:02:12Z",
  "trace_id": "255d1aef-8c98-452f-ac51-23d051240864",
  "correlation_id": "fb3d2015-bc17-4bb9-bb85-30c5cf1aaaa7"
}
Параметр Описание
error Строка кода ошибки, которую можно использовать для классификации типов возникших ошибок и реагирования на них.
error_description Конкретное сообщение об ошибке, с помощью которого можно определить первопричину возникновения ошибки аутентификации.
error_codes Список кодов ошибок, характерных для службы маркеров безопасности, которые могут помочь при диагностике.
timestamp Время, когда произошла ошибка.
trace_id Уникальный идентификатор для запроса, который помогает при диагностике.
correlation_id Уникальный идентификатор для запроса, который помогает при диагностике компонентов.

Использование маркера

Теперь, когда вы получили маркер, примените его для выполнения запросов к ресурсу. По истечении срока действия маркера повторно отправьте запрос к конечной точке /token, чтобы получить новый маркер доступа.

GET /v1.0/me/messages
Host: https://graph.microsoft.com
Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6Ik5HVEZ2ZEstZnl0aEV1Q...
# Pro tip: Try the following command! (Replace the token with your own.)

curl -X GET -H "Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbG...." 'https://graph.microsoft.com/v1.0/me/messages'

Примеры кода и другая документация

Чтобы получить дополнительные сведения об учетных данных клиента, прочтите эту статью из библиотеки проверки подлинности Майкрософт.

Образец Платформа Описание
active-directory-dotnetcore-daemon-v2 Консоль .NET Core 2.1 Простое приложение .NET Core, которое отображает пользователей клиента, которые делают запрос в Microsoft Graph не от имени пользователя, а используя удостоверение приложения. В примере также показаны различные варианты проверки подлинности с помощью сертификатов.
active-directory-dotnet-daemon-v2 ASP.NET MVC 3 Веб-приложение, которое синхронизирует данные из Microsoft Graph на основе удостоверения приложения, а не имени пользователя.
ms-identity-javascript-nodejs-console Консоль Node.js Простое приложение Node.js, которое отображает пользователей клиента. Для этого оно отправляет запрос Microsoft Graph, используя удостоверение приложения