Поделиться через


поток неявного предоставления платформа удостоверений Майкрософт и OAuth 2.0

Платформа удостоверений Майкрософт поддерживает поток неявного предоставления разрешений OAuth 2.0, как описано в спецификации OAuth 2.0. Определяющая характеристика неявного предоставления разрешения заключается в том, что токены (токены идентификаторов или маркеры доступа) возвращаются непосредственно из конечной точки /authorize, а не из конечной точки /token. Это часто используется как часть потока кода авторизации в так называемом "гибридном потоке" — получение токена идентификатора для запроса /authorize вместе с кодом авторизации.

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

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

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

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

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

Схема, показывающая поток неявного входа.

Подходящие сценарии для неявного предоставления OAuth2

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

Преимущества потока кода авторизации

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

Проблемы безопасности с неявным потоком предоставления

Поток неявного предоставления предназначен для традиционных веб-приложений, где сервер имеет контроль над безопасной обработкой данных POST. Существует два основных способа доставки маркеров с неявным потоком предоставления: где response_mode возвращается в качестве фрагмента URL-адреса или в качестве параметра запроса (с помощью form POST и GET ). В неявном потоке, где response_mode=form_postмаркер безопасно поставляется через HTML-форму POST в URI перенаправления клиента. Этот метод гарантирует, что маркер не предоставляется в фрагменте URL-адреса, что, в свою очередь, позволяет избежать рисков утечки маркеров через журнал браузера или заголовки ссылок.

Проблемы безопасности с неявным потоком возникают при доставке маркеров с помощью response_mode=fragment. Фрагмент URL-адреса является частью URL-адреса, который поступает после символа # и не отправляется на сервер, когда браузер запрашивает новую страницу, но доступен для JavaScript, запущенного в браузере. Это означает, что маркер предоставляется любому JavaScript, работающему на странице, что может быть угрозой безопасности, если страница включает сторонние скрипты. Эти проблемы безопасности для маркеров в spAs также не применяются к неявным потокам form POST.

Когда следует разрешить выдачу маркера доступа или маркера идентификатора при запросе с помощью неявного предоставления или гибридного потока?

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

Однако если вы (или разработчики) не используете MSAL в приложении, в следующей таблице описаны, когда маркеры доступа или маркер идентификатора должны быть включены.

Тип создаваемого приложения Маркеры, которые необходимо включить в регистрации приложений
SPA (одностраничное приложение), которое не использует поток кода авторизации с PKCE Маркеры доступа и маркеры идентификатора
Веб-приложение или приложение SPA, которое вызывает веб-API через JavaScript с помощью неявного потока Маркеры доступа и маркеры идентификатора
Веб-приложение ASP.NET Core и другие веб-приложения, использующие гибридную проверку подлинности Токен идентификатора

Отправка запроса на вход

Для первого входа пользователя в приложение можно отправить запрос на авторизацию OpenID Connect и получить id_token с платформы удостоверений Майкрософт.

Внимание

Чтобы успешно запросить маркер идентификатора и (или) маркер доступа, регистрация приложения в Центре администрирования Microsoft Entra — Регистрация приложений страница должна иметь соответствующий неявный поток предоставления, выбрав маркеры идентификатора и маркеры доступа в разделе неявного предоставления и гибридных потоков. Если он не включен, unsupported_response будет возвращена ошибка:

The provided value for the input parameter 'response_type' is not allowed for this client. Expected value is 'code'

// Line breaks for legibility only

https://login.microsoftonline.com/{tenant}/oauth2/v2.0/authorize?
client_id=00001111-aaaa-2222-bbbb-3333cccc4444
&response_type=id_token
&redirect_uri=http%3A%2F%2Flocalhost%2Fmyapp%2F
&scope=openid
&response_mode=fragment
&state=12345
&nonce=678910
Параметр Тип Описание
tenant обязательно Значение {tenant} в пути запроса можно использовать для того, чтобы контролировать, кто может входить в приложение. Допустимые значения: common, organizations, consumers, а также идентификаторы клиента. Дополнительные сведения см. в описании протоколов. В гостевых сценариях, в которых пользователь из одного клиента выполняет вход в другой, необходимо предоставить идентификатор клиента, чтобы вход выполнялся правильно.
client_id обязательно Идентификатор приложения (клиента), который центр администрирования Microsoft Entra — Регистрация приложений страницу, назначенную вашему приложению.
response_type обязательно Должен включать id_token для входа в OpenID Connect. Он также может включать response_type, token. С помощью token этого приложения можно сразу получить маркер доступа из конечной точки /authorize, не выполняя второй запрос к конечной точке /authorize. Если вы используете token response_type, параметр должен содержать область, scope указывающую, какой ресурс должен выдавать маркер (например, user.read в Microsoft Graph). Он также может содержать code вместо token, чтобы предоставить код авторизации для использования в потоке кода авторизации. Этот id_token+code ответ иногда называется гибридным потоком.
redirect_uri рекомендуется URI перенаправления приложения, где ответы проверки подлинности отправляются и получаются в приложении. Он должен точно соответствовать одному из URI перенаправления, зарегистрированных в Центре администрирования Microsoft Entra, за исключением того, что он должен быть закодирован URL-адресом.
scope обязательно Список областей с разделителями-пробелами. Для OpenID Connect (id_tokens) она должна включать область openid, которая преобразуется в разрешение "Вход" в пользовательском интерфейсе согласия. Если требуется доступ к дополнительным данным пользователя, вы также можете указать области email или profile. Этот запрос может также включать другие области в зависимости от ресурсов, к которым требуется получить доступ, если запрошен маркер доступа.
response_mode рекомендуется Указывает метод, с помощью которого результирующий маркер будет отправлен приложению. По умолчанию используется query только маркер доступа, но fragment если запрос включает id_token. По соображениям безопасности рекомендуется использовать form_post неявный поток, чтобы убедиться, что маркер не предоставляется в фрагменте URL-адреса.
state рекомендуется Значение, включенное в запрос, также возвращается в ответе маркера. Это может быть строка любого контента. Как правило, для предотвращения подделки межсайтовых запросовиспользуется генерируемое случайным образом уникальное значение. Параметр "state" также используется для кодирования информации о состоянии пользователя в приложении перед созданием запроса на проверку подлинности, например информации об открытой на тот момент странице или представлении.
nonce обязательно Значение, включенное в запрос и созданное приложением, которое входит в состав полученного маркера идентификации в качестве утверждения. Приложение может проверить это значение во избежание атак с использованием воспроизведения токена. Это значение обычно представляет собой случайную уникальную строку, которую можно использовать для определения источника запроса. Требуется только при запросе id_token.
prompt необязательно Указывает требуемый тип взаимодействия с пользователем. На текущий момент единственные допустимые значения — login, none, select_account и consent. prompt=loginПри значении пользователь должен ввести учетные данные по запросу. Единый вход не сработает. prompt=none является противоположностью — это гарантирует, что пользователь не представлен интерактивным запросом в любом случае. Если запрос не может быть выполнен автоматически через единый вход, платформа удостоверений Майкрософт возвращает ошибку. prompt=select_account отправляет пользователя в средство выбора учетных записей, где отображаются все учетные записи, запоминаемые в сеансе. Если установить значение prompt=consent, то после входа пользователь увидит диалоговое окно согласия OAuth с запросом на предоставление разрешений приложению.
login_hint необязательно Этот параметр можно использовать для предварительного заполнения поля имени пользователя и адреса электронной почты страницы входа пользователя, если вы знаете имя пользователя заранее. Этот параметр обычно используется в приложениях при повторной аутентификации после извлечения необязательного утверждения login_hint из предыдущего сеанса входа.
domain_hint необязательно Если он включен, он пропускает процесс обнаружения на основе электронной почты, который пользователь проходит на странице входа, что приводит к немного более упрощенной пользовательской среде. Этот параметр обычно используется для приложений Line of Business, работающих в одном клиенте, где они предоставляют доменное имя в данном клиенте, перенаправляя пользователя поставщику федерации для этого клиента. Это указание предотвращает вход гостей в это приложение и ограничивает использование облачных учетных данных, таких как FIDO.

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

После того как пользователь пройдет проверку подлинности и предоставит разрешения, платформа удостоверений Майкрософт вернет приложению ответ на указанный redirect_uri с помощью метода, указанного в параметре response_mode.

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

Успешный ответ с использованием response_mode=fragment и response_type=id_token+code выглядит следующим образом (разрывы строк — для удобства чтения):

GET https://localhost/myapp/#
code=0.AgAAktYV-sfpYESnQynylW_UKZmH-C9y_G1A
&id_token=eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6Ik5HVEZ2ZEstZnl0aEV1Q...
&state=12345
Параметр Описание
code Указывается, если параметр response_type содержит значение code. Это код авторизации, подходящий для использования в потоке кода авторизации.
access_token Указывается, если параметр response_type содержит значение token. Маркер доступа, запрошенный приложением. Этот маркер доступа не следует расшифровывать или каким-либо иным образом проверять. Его можно рассматривать как непрозрачную строку.
token_type Указывается, если параметр response_type содержит значение token. Это всегда Bearer.
expires_in Указывается, если параметр response_type содержит значение token. Указывает количество секунд, в течение которых маркер остается допустимым (для кэширования).
scope Указывается, если параметр response_type содержит значение token. Указывает одну или несколько областей, для которых access_token допустимо. Может не включать все запрошенные области, если они не были применимы к пользователю. Например, области, доступные только для Записи Майкрософт, запрашиваемые при входе в систему с помощью личная учетная запись.
id_token Подписанный JSON Web Token (JWT). Приложение может расшифровать сегменты этого маркера, чтобы запросить сведения о выполнившем вход пользователе. Эти значения можно кэшировать и (или) отображать в приложении, но их не следует использовать в любых процессах авторизации или обеспечения безопасности. Дополнительные сведения о маркерах идентификаторов см. в разделе id_token reference.
Примечание. Предоставляется, только если подан запрос на область openid, а тип response_type содержит id_tokens.
state Если запрос содержит параметр "state", в ответе должно отображаться то же значение. Приложение должно убедиться, что значения параметра state в запросе и отклике идентичны.

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

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

Отклик в случае ошибки

Сообщения об ошибках также можно отправлять на redirect_uri , чтобы приложение обрабатывало их должным образом:

GET https://localhost/myapp/#
error=access_denied
&error_description=the+user+canceled+the+authentication
Параметр Описание
error Строка кода ошибки, которую можно использовать для классификации типов возникающих ошибок и реагирования на них.
error_description Конкретное сообщение об ошибке, с помощью которого разработчик может определить причину возникновения ошибки проверки подлинности.

Автоматическое получение маркера доступа

Теперь, когда пользователь вошел в одностраничные приложения, вы можете автоматически получать маркеры доступа для вызова веб-API, защищенных платформа удостоверений Майкрософт, таких как Microsoft Graph. Даже если вы уже получили токен с использованием параметра response_type со значением token, этот метод можно использовать для получения токенов к дополнительным ресурсам. При наличии этих токенов пользователям не нужно повторно выполнять вход.

Внимание

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

В обычных потоках OpenID Connect и OAuth токены можно получить, отправив запрос к конечной точке платформы удостоверений Майкрософт/token. Для получения новых токенов для других веб-API можно сделать запрос в скрытом iframe.

// Line breaks for legibility only

https://login.microsoftonline.com/{tenant}/oauth2/v2.0/authorize?
client_id=00001111-aaaa-2222-bbbb-3333cccc4444&response_type=token
&redirect_uri=http%3A%2F%2Flocalhost%2Fmyapp%2F
&scope=https%3A%2F%2Fgraph.microsoft.com%2Fuser.read
&response_mode=fragment
&state=12345
&nonce=678910
&prompt=none
&login_hint=myuser@mycompany.com

Дополнительные сведения о параметрах запроса в URL-адресе см. в разделе Отправка запроса на вход.

Совет

Попробуйте скопировать и вставить следующий запрос на вкладку браузера с помощью реальной client_id и username из регистрации приложения. Это позволит увидеть автоматический запрос маркера в действии.

https://login.microsoftonline.com/common/oauth2/v2.0/authorize?client_id={your-client-id}&response_type=token&redirect_uri=http%3A%2F%2Flocalhost%2Fmyapp%2F&scope=https%3A%2F%2Fgraph.microsoft.com%2Fuser.read&response_mode=fragment&state=12345&nonce=678910&prompt=none&login_hint={username}

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

Благодаря параметру prompt=none этот запрос завершается успешно или завершается сбоем немедленно и возвращается в приложение. Ответ отправляется приложению по указанному адресу redirect_uri, используя метод, указанный в параметре response_mode .

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

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

GET https://localhost/myapp/#
access_token=eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6Ik5HVEZ2ZEstZnl0aEV1Q...
&state=12345
&token_type=Bearer
&expires_in=3599
&scope=https%3A%2F%2Fgraph.microsoft.com%2Fdirectory.read
Параметр Описание
access_token Указывается, если параметр response_type содержит значение token. Это маркер доступа, запрошенный приложением. В данном случае для Microsoft Graph. Этот маркер доступа не следует расшифровывать или каким-либо иным образом проверять. Его можно рассматривать как непрозрачную строку.
token_type Это всегда Bearer.
expires_in Указывает количество секунд, в течение которых маркер остается допустимым (для кэширования).
scope Указывает одну или несколько областей, для которых допустимы маркер доступа. Может не включать все запрошенные области, если они не применимы к пользователю (если области, доступные только для Microsoft Entra, запрашиваются, когда личная учетная запись используется для входа).
id_token Подписанный JSON Web Token (JWT). Указывается, если параметр response_type содержит значение id_token. Приложение может расшифровать сегменты этого маркера, чтобы запросить сведения о выполнившем вход пользователе. Эти значения можно кэшировать и (или) отображать в приложении, но их не следует использовать в любых процессах авторизации или обеспечения безопасности. Дополнительные сведения о маркерах id_token см. в статье id_tokenМаркеры идентификаторов.
Примечание. Предоставляется, только если подан запрос на область openid.
state Если запрос содержит параметр "state", в ответе должно отображаться то же значение. Приложение должно убедиться, что значения параметра state в запросе и отклике идентичны.

Отклик в случае ошибки

Сообщения об ошибках также можно отправлять на redirect_uri , чтобы приложение правильно обрабатывало их. Если prompt=noneожидаемое сообщение об ошибке:

GET https://localhost/myapp/#
error=user_authentication_required
&error_description=the+request+could+not+be+completed+silently
Параметр Описание
error Строка кода ошибки, которую можно использовать для классификации типов возникающих ошибок и реагирования на них.
error_description Конкретное сообщение об ошибке, с помощью которого разработчик может определить причину возникновения ошибки проверки подлинности.

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

Обновление маркеров

Неявное предоставление не предоставляет маркеры обновления. Срок действия маркеров идентификатора и маркеров доступа истекает через короткий период времени, поэтому приложение должно периодически обновлять эти маркеры. Чтобы обновить любой тип маркера, можно выполнить тот же скрытый запрос iframe ранее, используя prompt=none параметр для управления поведением платформы удостоверений. Если вы хотите получить новый маркер идентификатора, обязательно используйте id_token его response_type scope=openidи nonce параметр.

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

Отправка запроса на выход

Конечная точка end_session_endpoint OpenID Connect позволяет приложению отправить запрос на платформу удостоверений Майкрософт, чтобы завершить сеанс пользователя и очистить файлы cookie, заданные платформой. Чтобы пользователь полностью вышел из веб-приложения, приложение должно завершить свой сеанс пользователя (обычно с помощью очистки кэша маркеров или файлов cookie), а затем перенаправить браузер на:

https://login.microsoftonline.com/{tenant}/oauth2/v2.0/logout?post_logout_redirect_uri=https://localhost/myapp/
Параметр Тип Описание
tenant обязательно Значение {tenant} в пути запроса можно использовать для того, чтобы контролировать, кто может входить в приложение. Допустимые значения: common, organizations, consumers, а также идентификаторы клиента. Дополнительные сведения см. в описании протоколов.
post_logout_redirect_uri рекомендуется URL-адрес, к которому должен вернуться пользователь после завершения выхода. Это значение должно соответствовать одному из универсальных кодов ресурсов (URI) перенаправления, зарегистрированных для приложения. Если он не включен, пользователь отображает универсальное сообщение платформа удостоверений Майкрософт.

См. также

  • Перейдите на страницу примеров MSAL JS, чтобы приступить к созданию кода.
  • Рассмотрите поток кода авторизации как более новую, лучшую альтернативу неявному предоставлению разрешения.