Предоставление доступа к веб-приложениям с помощью OpenID Connect и Azure Active Directory

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

В этом руководстве используется устаревшая конечная точка Azure Active Directory версии 1.0. Для новых проектов используйте платформу удостоверений Майкрософт.

OpenID Connect представляет простой уровень идентификации на основе протокола OAuth 2.0. OAuth 2.0 определяет механизмы получения и использования маркеров доступа для доступа к защищенным ресурсам, но не содержит стандартные методы для предоставления сведений об удостоверении. OpenID Connect реализует функции аутентификации как расширение процесса авторизации OAuth 2.0. Эта служба предоставляет сведения о конечном пользователе в форме маркера id_token, который идентифицирует пользователя и предоставляет базовые данные профиля пользователя.

Мы рекомендуем использовать OpenID Connect для веб-приложений, которые размещаются на сервере и доступны через веб-браузер.

Регистрация приложения в клиенте AD

В начале необходимо зарегистрировать приложение в клиенте Azure Active Directory (Azure AD). После этого вашему приложению будет присвоен идентификатор, и оно сможет получать маркеры.

  1. Войдите на портал Azure.

  2. Выберите клиент Azure AD. Для этого выберите учетную запись в правом верхнем углу страницы, щелкните элемент навигации Переключение каталога и выберите соответствующий клиент.

    • Если в вашей учетной записи только один клиент Azure AD или если вы уже выбрали соответствующий клиент Azure AD, этот шаг можно пропустить.
  3. На портале Azure найдите и выберите Azure Active Directory.

  4. В левом меню Azure Active Directory выберите Регистрация приложений, а затем выберите Новая регистрация.

  5. Следуя инструкциям на экране, создайте приложение. Данное руководство не рассматривает конкретно, будет ли это веб-приложение или общедоступное клиентское приложение (на мобильном устройстве или на компьютере), и, если вам нужны конкретные примеры веб-приложений или клиентских приложений, ознакомьтесь с нашими краткими руководствами.

    • Имя — это имя приложения, которое описывает его для конечных пользователей.
    • В разделе Поддерживаемые типы учетных записей выберите Accounts in any organizational directory and personal Microsoft accounts (Учетные записи в любом каталоге организации и личные учетные записи Майкрософт).
    • Обеспечьте URI перенаправления. Для веб-приложений это базовый URL-адрес приложения, через который пользователи могут входить в приложение. Например, http://localhost:12345. В общедоступном клиенте (мобильное устройство и компьютер) Azure AD использует его для возврата ответов маркеров. Укажите значение, специфичное для вашего приложения. Например, http://MyFirstAADApp.
  6. По завершении регистрации система Azure AD присвоит приложению уникальный идентификатор клиента (Идентификатор приложения). Это значение вам понадобится в следующих разделах, поэтому не забудьте скопировать его на странице приложения.

  7. Чтобы найти приложение на портале Azure, выберите Регистрация приложений, а затем — Показать все приложения.

Поток проверки подлинности при использовании OpenID Connect

Наиболее простой процесс входа содержит следующие этапы. Каждый из них подробно описан ниже.

Поток проверки подлинности OpenID Connect

Документ метаданных OpenID Connect

OpenID Connect описывает документ метаданных, который содержит большинство сведений, необходимых приложению для выполнения входа. Сюда входят такие сведения, как используемые URL-адреса и расположение открытых ключей подписывания службы. Документ метаданных OpenID Connect можно найти по адресу:

https://login.microsoftonline.com/{tenant}/.well-known/openid-configuration

Метаданные — это простой документ JSON. В качестве примера ниже приведен фрагмент кода. Его содержимое полностью описано в спецификации OpenID Connect. Учтите, что предоставление клиента, отличного от common, вместо {tenant} приведет к получению URI, определенных клиентом, в возвращаемом объекте JSON.

{
    "authorization_endpoint": "https://login.microsoftonline.com/{tenant}/oauth2/authorize",
    "token_endpoint": "https://login.microsoftonline.com/{tenant}/oauth2/token",
    "token_endpoint_auth_methods_supported":
    [
        "client_secret_post",
        "private_key_jwt",
        "client_secret_basic"
    ],
    "jwks_uri": "https://login.microsoftonline.com/common/discovery/keys"
    "userinfo_endpoint":"https://login.microsoftonline.com/{tenant}/openid/userinfo",
    ...
}

Если в приложении есть настраиваемые ключи подписывания в результате использования функции сопоставления утверждений, необходимо добавить параметр запроса appid, содержащий идентификатор приложения, чтобы получить jwks_uri, указывающий на сведения о ключе подписывания приложения. Например: https://login.microsoftonline.com/{tenant}/.well-known/openid-configuration?appid=6731de76-14a6-49ae-97bc-6eba6914391e содержит jwks_uri для https://login.microsoftonline.com/{tenant}/discovery/keys?appid=6731de76-14a6-49ae-97bc-6eba6914391e.

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

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

  • Запрос должен содержать область openid в параметре scope.
  • Параметр response_type должен включать id_token.
  • Запрос должен содержать параметр nonce .

Запрос в целом будет выглядеть примерно так.

// Line breaks for legibility only

GET https://login.microsoftonline.com/{tenant}/oauth2/authorize?
client_id=6731de76-14a6-49ae-97bc-6eba6914391e
&response_type=id_token
&redirect_uri=http%3A%2F%2Flocalhost%3a12345
&response_mode=form_post
&scope=openid
&state=12345
&nonce=7362CAEA-9CA5-4B43-9BA3-34D7C303EBA7
Параметр Тип Описание
tenant обязательно Значение {tenant} в пути запроса можно использовать для того, чтобы контролировать, кто может входить в приложение. Допустимые значения — идентификаторы клиента, например 8eaef023-2b34-4da1-9baa-8bc8c9d6a490, contoso.onmicrosoft.com или common для маркеров без указания клиента.
client_id обязательно Идентификатор приложения, назначенный вашему приложению при регистрации в Azure AD. Его значение можно найти на портале Azure. Щелкните Azure Active Directory, щелкните Регистрация приложений, выберите приложение и найдите идентификатор приложения на его странице.
response_type обязательно Должен включать id_token для входа в OpenID Connect. Параметр также может содержать другие типы response_types, например code или token.
область рекомендуется Спецификация протокола OpenID Connect требует наличие области openid, которая переносит в разрешение на "Вход" в пользовательском интерфейсе предоставления согласия. Эта и другие области OIDC игнорируются в конечной точке v 1.0, но по-прежнему рекомендуются для клиентов, которые соответствуют стандартам.
nonce обязательные Значение, включенное в запрос и созданное приложением, которое входит в состав маркера id_token в качестве утверждения. Приложение может проверять это значение, чтобы устранить атаки с воспроизведением маркеров. Это значение обычно представляет собой случайную уникальную строку или глобальный уникальный идентификатор, которые можно использовать для определения источника запроса.
redirect_uri рекомендуется URI перенаправления приложения, на который можно отправлять ответы проверки подлинности для их получения приложением. Он должен в точности соответствовать одному из URI перенаправления, зарегистрированных на портале, но иметь форму закодированного URL-адреса. В случае отсутствия агент пользователя будет отправлен обратно в один из URI перенаправления, зарегистрированных для приложения, в случайном порядке. Максимальная длина составляет 255 байт.
response_mode необязательно Указывает метод, с помощью которого следует отправлять полученный код авторизации приложению. Поддерживаются значения form_post для формы HTTP POST и fragment для фрагмента URL-адреса. Для веб-приложений рекомендуется использовать response_mode=form_post, чтобы обеспечить наиболее безопасную передачу маркеров в приложение. Значение по умолчанию для любого потока, включая маркер id_token, — fragment.
Состояние рекомендуется Значение, включенное в запрос, которое также возвращается в ответе маркера. Это может быть строка любого контента. Как правило, для предотвращения подделки межсайтовых запросовиспользуется генерируемое случайным образом уникальное значение. Состояние также используется для кодирования сведений о состоянии пользователя в приложении перед выполнением запроса проверки подлинности, например о просматриваемой странице или представлении.
prompt необязательно Указывает требуемый тип взаимодействия с пользователем. На текущий момент единственные допустимые значения — login, none и consent. При значении prompt=login пользователь должен ввести учетные данные по запросу. Единый вход не сработает. Значение prompt=none является противоположным — оно гарантирует, что интерактивные запросы не будут выводиться ни при каких обстоятельствах. Если запрос не удается завершить автоматически с использованием единого входа, то конечная точка возвращает ошибку. Если установить значение prompt=consent, то после входа пользователь увидит диалоговое окно согласия OAuth с запросом на предоставление разрешений приложению.
login_hint необязательно Может использоваться для предварительного заполнения полей имени пользователя или адреса электронной почты на отображаемой пользователю странице входа, если имя пользователя уже известно. Зачастую этот параметр используется в приложениях при повторной аутентификации. При этом имя пользователя извлекается во время предыдущего входа с помощью утверждения preferred_username.

На текущем этапе пользователю предлагается ввести учетные данные и завершить аутентификацию.

Пример ответа

Пример ответа, отправленный в redirect_uri, указанный в запросе на вход после проверки подлинности пользователя, может выглядеть следующим образом:

POST / HTTP/1.1
Host: localhost:12345
Content-Type: application/x-www-form-urlencoded

id_token=eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6Ik1uQ19WWmNB...&state=12345
Параметр Описание
id_token Значение id_token, запрошенное приложением. Вы можете использовать маркер id_token для идентификации пользователя и запуска сеанса с пользователем.
Состояние Значение, включенное в запрос, которое также возвращается в ответе маркера. Как правило, для предотвращения подделки межсайтовых запросовиспользуется генерируемое случайным образом уникальное значение. Состояние также используется для кодирования сведений о состоянии пользователя в приложении перед выполнением запроса проверки подлинности, например о просматриваемой странице или представлении.

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

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

POST / HTTP/1.1
Host: localhost:12345
Content-Type: application/x-www-form-urlencoded

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

Коды ошибок конечной точки авторизации

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

Код ошибки Описание Действие клиента
invalid_request Ошибка протокола, например отсутствует обязательный параметр. Исправьте запрос и отправьте его повторно. Это ошибка разработки, которая, как правило, обнаруживается во время первоначального тестирования.
unauthorized_client Клиентскому приложению не разрешено запрашивать код авторизации. Как правило, это происходит, если клиентское приложение не зарегистрировано в Azure AD или не добавлено в клиент Azure AD пользователя. Приложение может отобразить пользователю запрос с инструкцией по установке приложения и его добавлению в Azure AD.
access_denied Владелец ресурса отказал в использовании Клиентское приложение может уведомить пользователя, что не может продолжить работу без согласия пользователя.
unsupported_response_type Сервер авторизации не поддерживает тип ответа в запросе. Исправьте запрос и отправьте его повторно. Это ошибка разработки, которая, как правило, обнаруживается во время первоначального тестирования.
server_error Сервер обнаружил непредвиденную ошибку. Повторите запрос. Эти ошибки могут возникать в связи с временными условиями. Клиентское приложение может отобразить для пользователя сообщение о том, что его ответ задерживается из-за временной ошибки.
temporarily_unavailable Сервер временно занят и не может обработать запрос. Повторите запрос. Клиентское приложение может отобразить для пользователя сообщение о том, что его ответ задерживается из-за временных условий.
invalid_resource Целевой ресурс недопустим, так как он не существует. Azure AD не удается найти ресурс, или он настроен неправильно. Это означает, что ресурс, если он существует, не настроен в клиенте. Приложение может отобразить пользователю запрос с инструкцией по установке приложения и его добавлению в Azure AD.

Проверка токена "id_token"

Для аутентификации пользователя недостаточно просто получить маркер id_token. Вам также нужно проверить подпись маркера id_token и утверждения в нем на соответствие с требованиями приложения. В конечной точке Azure AD для подписи токенов и проверки их правильности используются веб-токены JSON (JWTs) и шифрование с открытым ключом.

Вы можете выбрать проверку id_token в клиентском коде, но обычно id_token отправляется на проверку внутреннему серверу.

Вам также может потребоваться проверить дополнительные утверждения в зависимости от сценария. Ниже приведены некоторые из стандартных проверок:

  • Обеспечение регистрации пользователя или организации в приложении.
  • Предоставление пользователю необходимого уровня авторизации и привилегий с помощью утверждений wids или roles.
  • Обеспечение определенного уровня проверки подлинности, например Многофакторной Идентификации.

После проверки маркера id_token вы можете начать сеанс с пользователем, используя утверждения из маркера id_token для получения сведений о пользователе в приложении. Эти сведения можно использовать для показа, записи, персонализации и т. д. Дополнительные сведения об утверждениях id_tokens и см. в статье id_tokens AAD.

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

Для выхода пользователя из приложения недостаточно очистить файлы cookie или каким-то другим образом завершить сеанс пользователя. Также необходимо перенаправить пользователя на end_session_endpoint для выхода. Если этого не сделать, то пользователь сможет повторно выполнить аутентификацию в приложении без ввода учетных данных, поскольку для него сохранится действительный сеанс единого входа на конечной точке Azure AD.

Можно просто перенаправить пользователя на адрес, указанный в параметре end_session_endpoint в документе метаданных OpenID Connect:

GET https://login.microsoftonline.com/common/oauth2/logout?
post_logout_redirect_uri=http%3A%2F%2Flocalhost%2Fmyapp%2F

Параметр Тип Описание
post_logout_redirect_uri рекомендуется URL-адрес, по которому пользователь должен быть перенаправлен после успешного выхода. Этот URL-адрес должен соответствовать одному из URI перенаправления, зарегистрированных для вашего приложения на портале регистрации приложений. Если post_logout_redirect_uri не указан, то пользователю будет направлено универсальное сообщение.

Единый выход

Если перенаправить пользователя в end_session_endpoint, Azure AD очистит сеанс пользователя из браузера. Тем не менее пользователь может оставаться вошедшим в другие приложения, использующие Azure AD для аутентификации. Чтобы обеспечить одновременный выход пользователя из всех приложений, Azure AD отправляет HTTP-запрос GET к зарегистрированному LogoutUrl для всех приложений, в которые в настоящее время вошел пользователь. Приложения должны ответить на него, удалив любой сеанс, который идентифицирует пользователя, и возвратив ответ 200. Для поддержки единого входа в приложении необходимо в его коде реализовать такой URL-адрес LogoutUrl. LogoutUrl можно настроить на портале Azure.

  1. Войдите на портал Azure.
  2. Выберите свой каталог Active Directory, щелкнув имя своей учетной записи в правом верхнем углу страницы.
  3. В области навигации слева выберите Azure Active Directory, затем щелкните Регистрация приложений и выберите свое приложение.
  4. Щелкните Параметры > Свойства и найдите текстовое поле URL-адрес выхода.

Получение токена

Многим веб-приложениям требуется не только выполнить вход пользователя, но и получить доступ к веб-службе от лица этого пользователя с помощью OAuth. В этом сценарии OpenID Connect используется для аутентификации пользователей и одновременного получения кода authorization_code, который можно использовать для получения маркеров access_tokens с использованием потока кода авторизации OAuth.

Получение токенов доступа

Для получения маркера доступа необходимо немного изменить приведенный выше запрос на вход:

// Line breaks for legibility only

GET https://login.microsoftonline.com/{tenant}/oauth2/authorize?
client_id=6731de76-14a6-49ae-97bc-6eba6914391e        // Your registered Application ID
&response_type=id_token+code
&redirect_uri=http%3A%2F%2Flocalhost%3a12345          // Your registered Redirect Uri, url encoded
&response_mode=form_post                              // `form_post' or 'fragment'
&scope=openid
&resource=https%3A%2F%2Fservice.contoso.com%2F        // The identifier of the protected resource (web API) that your application needs access to
&state=12345                                          // Any value, provided by your app
&nonce=678910                                         // Any value, provided by your app

Если включить в запрос области разрешений и применить response_type=code+id_token, конечная точка authorize обеспечит, чтобы пользователь предоставил согласие на разрешения, перечисленные в параметре запроса scope, а затем возвратит приложению код авторизации в обмен на маркер доступа.

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

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

POST /myapp/ HTTP/1.1
Host: localhost
Content-Type: application/x-www-form-urlencoded

id_token=eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6Ik1uQ19WWmNB...&code=AwABAAAAvPM1KaPlrEqdFSBzjqfTGBCmLdgfSTLEMPGYuNHSUYBrq...&state=12345
Параметр Описание
id_token Значение id_token, запрошенное приложением. Вы можете использовать маркер id_token для идентификации пользователя и запуска сеанса с пользователем.
code Запрашиваемый приложением код авторизации. Приложение может использовать код авторизации для запроса маркера доступа для целевого ресурса. Срок действия кодов авторизации мал и обычно истекает по прошествии порядка 10 минут.
state Если в запрос включен этот параметр состояния, идентичное значение должно содержаться и в ответе на этот запрос. Приложение должно проверить, совпадают ли значения параметра "state" в запросе и ответе.

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

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

POST /myapp/ HTTP/1.1
Host: localhost
Content-Type: application/x-www-form-urlencoded

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

Описания кодов ошибок и сведения о рекомендуемых действиях в клиенте см. в разделе Коды ошибок конечной точки авторизации.

После авторизации code и id_token вы можете выполнить вход и получить маркеры доступа от имени пользователя. Для входа пользователя необходимо проверить маркер id_token , как описано выше. Чтобы получить маркеры доступа, необходимо выполнить действия, описанные в разделе "Использование кода авторизации для запроса маркера доступа" документации по потокам кода OAuth.

Дальнейшие действия