Платформа удостоверений Майкрософт и поток учетных данных клиента OAuth 2.0
Процесс предоставления учетных данных клиента OAuth 2.0 позволяет веб-службе (конфиденциальный клиент) вместо олицетворения пользователя использовать свои собственные учетные данные для аутентификации при вызове другой веб-службы. Грант, указанный в RFC 6749, иногда называемый двухуровневым OAuth, можно использовать для доступа к размещенным в Интернете ресурсам с помощью удостоверения приложения. Этот тип обычно используется для взаимодействия между серверами, которые должны выполняться в фоновом режиме, без немедленного взаимодействия с пользователем и часто называются daemons или учетными записями служб.
В потоке учетных данных клиента разрешения дает администратор непосредственно самому приложению. Когда приложение предоставляет маркер для ресурса, то для выполнения действия этот ресурс требует авторизацию приложения, поскольку в авторизации не участвует пользователь. В этой статье рассматриваются оба шага, необходимые для следующих действий.
В этой статье описывается, как программировать непосредственно протокол в приложении. По возможности рекомендуется использовать поддерживаемые библиотеки проверки подлинности Майкрософт (MSAL) вместо получения маркеров и вызова защищенных веб-API. Вы также можете ознакомиться с примерами приложений, использующих MSAL. Стоит отметить, что маркеры обновления никогда не будут предоставляться с этим потоком, поскольку client_id
и client_secret
(которые потребуются для получения маркера обновления) могут быть использованы для получения маркера доступа.
Для большей надежности платформа удостоверений Майкрософт также позволяет вызывающей службе проходить проверку подлинности с помощью сертификата или федеративных учетных данных вместо общего секрета. Так как используются собственные учетные данные приложения, эти учетные данные должны быть защищены. Никогда не публиковать эти учетные данные в исходном коде, внедрять его на веб-страницы или использовать его в широко распределенном собственном приложении.
Схема протокола
Весь поток учетных данных клиента аналогичен приведенному на следующей схеме. Описание каждого шага приведено далее в этой статье.
Получение прямой авторизации
Как правило, приложение получает прямую авторизацию на доступ к ресурсу двумя способами:
- с помощью списка управления доступом (ACL) в ресурсе;
- С помощью назначения разрешений приложения в идентификаторе Microsoft Entra
Эти два метода являются наиболее распространенными в идентификаторе Microsoft Entra, и мы рекомендуем их для клиентов и ресурсов, которые выполняют поток учетных данных клиента. Ресурс также может выбрать другой способ авторизации клиентов. Каждый сервер ресурсов может выбрать метод, являющийся наиболее оптимальным для приложения.
Доступ к спискам управления
Поставщик ресурсов может принудительно применять проверку авторизации на основе списка известных идентификаторов приложений (клиента), а также предоставлять определенный уровень доступа на основе этих идентификаторов. Когда ресурс получает маркер из платформы удостоверений Майкрософт, он может расшифровать этот маркер и извлечь идентификатор приложения клиента из утверждений appid
и iss
. Затем он проверяет наличие приложения в действующем списке управления доступом. Детализация и методы использования списка управления доступом для разных ресурсов могут значительно отличаться.
Нередко список управления доступом используется для выполнения тестов веб-приложения или веб-API. Веб-API может предоставить определенному клиенту только ограниченный набор прав доступа. Чтобы выполнить сквозные тесты в API, можно создать тестовый клиент, который получает маркеры из платформа удостоверений Майкрософт, а затем отправляет их в API. Затем API может проверить идентификатор приложения тестового клиента с помощью списка управления доступом для предоставления доступа ко всем возможностям API. При использовании такого списка управления доступом нужно не только проверить значение appid
вызывающей стороны, но и убедиться в надежности значения iss
маркера.
Данный тип авторизации часто используется в управляющих программах и учетных записях служб, которым требуется доступ к данным пользователей, являющихся потребителями с личной учетной записью Майкрософт. Необходимую авторизацию для доступа к корпоративным данным рекомендуется получать с помощью разрешений приложения.
Управление маркерами без утверждения roles
Чтобы включить этот шаблон авторизации на основе ACL, идентификатор Microsoft Entra ID не требует, чтобы приложения были авторизованы для получения маркеров для другого приложения. То есть маркеры только для приложений могут быть выданы без roles
утверждения. Приложения, которые предоставляют API, должны использовать проверки разрешений для того, чтобы они могли принять маркеры.
Если вы хотите запретить приложениям получать в приложении маркеры только для приложений без ролей, убедитесь, что для приложения включены требования к назначению. Это позволит пользователям и приложениям без назначенных ролей получить маркер для этого приложения.
Разрешения приложения
Вместо списков управления доступом можно использовать интерфейсы API, чтобы предоставлять набор разрешений для приложения. Они предоставляются администратору организации и могут использоваться только для доступа к данным, принадлежащим этой организации и его сотрудникам. Например, Microsoft Graph предоставляет несколько разрешений приложений для следующих действий:
- чтение почты во всех почтовых ящиках;
- чтение и запись почты во всех почтовых ящиках;
- отправка почты любым пользователем;
- Прочитать данные каталога
Чтобы использовать роли приложения (разрешения приложения) с собственным API (в отличие от Microsoft Graph), необходимо сначала предоставить роли приложения в регистрации приложений API в Центре администрирования Microsoft Entra. Затем нужно предоставить необходимые роли приложений, выбрав эти разрешения при регистрации клиентского приложения. Если вы не предоставили ролей приложений в регистрации приложения API, вы не сможете указать разрешения приложения для этого API в регистрации приложения клиента в Центре администрирования Microsoft Entra.
При проверке подлинности приложения (в отличие от пользователя) нельзя использовать делегированные разрешения, потому что не существует пользователя, от имени которого ваше приложение могло бы выполнять операции. Необходимо использовать разрешения приложения, которые называются ролями приложения и предоставляются администратором или владельцем API.
Дополнительные сведения о разрешениях приложения см. в статье Разрешения и согласие.
Рекомендуется назначить администратора в своем приложении, чтобы назначить роли приложения.
Обычно при создании приложения, использующего разрешения, для него нужно настроить страницу или представление, в котором администратор может утвердить разрешения приложения. Эта страница может быть частью потока входа приложения, части параметров приложения или выделенного потока подключения . Часто приложение может отображать это представление подключения только после входа пользователя с помощью рабочей или учебной учетной записи Майкрософт.
Если используется вход пользователя в приложение, то вы можете определить организацию, к которой он принадлежит, прежде чем запрашивать у пользователя утверждение разрешений приложения. Хотя это не обязательно, таким образом можно сделать пользовательский интерфейс более интуитивно понятным. Чтобы войти в систему как пользователь, следуйте рекомендациями в Руководстве по протоколу платформы удостоверений Майкрософт.
Запрос разрешений у администратора каталога
Когда вы будете готовы запросить разрешения у администратора организации, можно будет перенаправить пользователя к конечной точке предоставления согласия администратора платформы удостоверений Майкрософт.
// Line breaks are for legibility only.
GET https://login.microsoftonline.com/{tenant}/adminconsent?
client_id=00001111-aaaa-2222-bbbb-3333cccc4444
&state=12345
&redirect_uri=http://localhost/myapp/permissions
Совет от профессионала! Попробуйте выполнить следующий запрос в браузере.
https://login.microsoftonline.com/common/adminconsent?client_id=00001111-aaaa-2222-bbbb-3333cccc4444&state=12345&redirect_uri=http://localhost/myapp/permissions
Параметр | Условие | Description |
---|---|---|
tenant |
Обязательное поле | Клиент каталога, из которого необходимо запросить разрешение. Его можно указать в виде GUID или понятного имени. Если неизвестно, какому клиенту относится пользователь, и нужно обеспечить его вход с помощью любого клиента, используйте common . |
client_id |
Обязательное поле | Идентификатор приложения (клиента), который центр администрирования Microsoft Entra — Регистрация приложений, назначенный приложению. |
redirect_uri |
Обязательное поле | Универсальный код ресурса (URI) перенаправления, на который нужно направлять ответ для обработки в приложении. Он должен в точности соответствовать одному из универсальных кодов ресурсов (URI) перенаправления, зарегистрированных на портале, но иметь вид URL-адреса. Он может содержать дополнительные сегменты пути. |
state |
Рекомендуемая конфигурация | Значение, включенное в запрос, которое также возвращается в ответе маркера. Это может быть строка любого контента. Параметр state используется для кодирования сведений о состоянии пользователя в приложении перед созданием запроса на аутентификацию, например сведений об открытой на тот момент странице или представлении. |
На этом этапе идентификатор Microsoft Entra применяет, что только администратор клиента может войти в систему, чтобы завершить запрос. Администратору будет предложено утвердить все непосредственные разрешения, запрошенные для приложения на портале регистрации приложений.
Успешный ответ
Если администратор утверждает разрешения для приложения, успешный ответ будет выглядеть следующим образом.
GET http://localhost/myapp/permissions?tenant=aaaabbbb-0000-cccc-1111-dddd2222eeee&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:443
Content-Type: application/x-www-form-urlencoded
client_id=00001111-aaaa-2222-bbbb-3333cccc4444
&scope=https%3A%2F%2Fgraph.microsoft.com%2F.default
&client_secret=qWgdYAmab0YSkuL1qKv5bPX
&grant_type=client_credentials
# Replace {tenant} with your tenant!
curl -X POST -H "Content-Type: application/x-www-form-urlencoded" -d 'client_id=00001111-aaaa-2222-bbbb-3333cccc4444&scope=https%3A%2F%2Fgraph.microsoft.com%2F.default&client_secret=A1bC2dE3f...&grant_type=client_credentials' 'https://login.microsoftonline.com/{tenant}/oauth2/v2.0/token'
Параметр | Условие | Description |
---|---|---|
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:443
Content-Type: application/x-www-form-urlencoded
scope=https%3A%2F%2Fgraph.microsoft.com%2F.default
&client_id=11112222-bbbb-3333-cccc-4444dddd5555
&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
Параметр | Условие | Description |
---|---|---|
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:443
Content-Type: application/x-www-form-urlencoded
scope=https%3A%2F%2Fgraph.microsoft.com%2F.default
&client_id=11112222-bbbb-3333-cccc-4444dddd5555&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
Параметр | Условие | Description |
---|---|---|
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: 0000aaaa-11bb-cccc-dd22-eeeeee333333\r\nCorrelation ID: aaaa0000-bb11-2222-33cc-444444dddddd\r\nTimestamp: 2016-01-09 02:02:12Z",
"error_codes": [
70011
],
"timestamp": "YYYY-MM-DD HH:MM:SSZ",
"trace_id": "0000aaaa-11bb-cccc-dd22-eeeeee333333",
"correlation_id": "aaaa0000-bb11-2222-33cc-444444dddddd"
}
Параметр | Описание |
---|---|
error |
Строка кода ошибки, которую можно использовать для классификации типов возникших ошибок и реагирования на них. |
error_description |
Конкретное сообщение об ошибке, с помощью которого можно определить первопричину возникновения ошибки аутентификации. |
error_codes |
Список кодов ошибок, характерных для службы маркеров безопасности, которые могут помочь при диагностике. |
timestamp |
Время, когда произошла ошибка. |
trace_id |
Уникальный идентификатор для запроса, который помогает при диагностике. |
correlation_id |
Уникальный идентификатор для запроса, который помогает при диагностике компонентов. |
Использование маркера
После получения маркера его можно использовать для выполнения запросов к ресурсу. По истечении срока действия маркера повторно отправьте запрос к конечной точке /token
, чтобы получить новый маркер доступа.
GET /v1.0/users HTTP/1.1
Host: graph.microsoft.com:443
Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbG...
Выполните следующую команду в терминале, чтобы заменить маркер собственным.
curl -X GET -H "Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbG..." 'https://graph.microsoft.com/v1.0/users'
Примеры кода и другая документация
Чтобы получить дополнительные сведения об учетных данных клиента, прочтите эту статью из библиотеки проверки подлинности Майкрософт.
Пример | Платформа | Description |
---|---|---|
active-directory-dotnetcore-daemon-v2 | .NET 6.0+ | Приложение ASP.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 с помощью удостоверения приложения. |