Спецификация управления сеансом подключения OpenID определяет подход с привязкой к протоколу для клиентов OpenID для проверки идентичности уже прошедших проверку подлинности конечных пользователей на сервере авторизации и получения информации об их базовом профиле через REST-полнофункциональный способ. Кроме того, он определяет методологии для управления сеансами пользователей и выхода конечных пользователей из системы на сервере авторизации. Управление сеансом OpenID Connect использует обмен данными по переднему каналу. Это означает, что запросы входа / выхода из RP в OP и OP в RP выполняются через пользовательский агент (на основе браузера).

Прежде всего, нам нужно понять некоторые специфические термины openid connect, которые используются в статье.

Проверяющая сторона (RP): клиентское приложение OAuth 2.0, требующее аутентификации конечного пользователя и заявок пользователей от поставщика OpenID (OP).

Поставщик OpenID (OP): сервер авторизации OAuth 2.0, который способен аутентифицировать конечного пользователя и предоставлять претензии Проверяющей стороне о событии аутентификации и конечном пользователе.

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

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

Следующие подходы могут использоваться для получения информации о статусе входа в OP.

  • Использование атрибута exp в ID-токене - ID-токен обычно имеет срок действия. Если RP хочет завершить сеанс, когда сеанс OP завершается (из-за тайм-аута или выхода пользователя из системы), RP может полагаться на токен id для истечения срока действия сеанса RP. Однако вполне возможно, что конечный пользователь вышел из OP до истечения этого срока. Следовательно, лучший подход - узнать статус входа в систему Конечного пользователя на OP. Для этого RP должен периодически проверять статус сеанса на OP.
  • Повторение запросов пассивной аутентификации к конечной точке авторизации OP с добавленным параметром prompt = none - это, безусловно, самый простой подход. Однако в спецификации указывается, что такой подход приведет к дополнительному сетевому трафику, который может быть нежелательным.
  • Опрос скрытого iframe OP из iframe RP с postMessage с ограничением происхождения - этот механизм не вызовет никакого дополнительного сетевого трафика. Поэтому этот метод разработан в спецификации OIDC Session Management как решение этой проблемы.

OpenIDConnect использует следующие две конечные точки для управления пользовательскими сеансами. Любой сервер авторизации, реализующий управление сеансом OIDC, ДОЛЖЕН поддерживать эти две конечные точки.

check_session_iframe - URL-адрес iframe OP, который поддерживает обмен данными между источниками для получения информации о состоянии сеанса с клиентом RP с использованием API HTML5 postMessage. Страница загружается из невидимого фрейма iframe, встроенного в страницу RP, чтобы она могла работать в контексте безопасности OP. Он принимает запросы postMessage от соответствующего iframe RP и использует postMessage для отправки обратно статуса входа Конечного пользователя в OP.

end_session_endpoint - URL-адрес OP, на который RP может выполнить перенаправление, чтобы запросить выход конечного пользователя из OP.

Состояние сеанса

Если OP поддерживает управление сеансом, он ДОЛЖЕН также возвращать состояние сеанса на OP в качестве дополнительного параметра session_state в ответе аутентификации. RP использует это значение состояния сеанса для мониторинга сеанса конечного пользователя на OP.

Значение session_state содержит «соленый криптографический хэш идентификатора клиента, исходного URL-адреса и состояния браузера OP».

В качестве исходного URL-адреса сервер может использовать исходный URL-адрес ответа аутентификации.

var session_state = CryptoJS.SHA256(client_id + ' ' + e.origin + ' ' + op_browser_state + ' ' + salt) + "." + salt;

Когда пользователь первоначально аутентифицируется на OP (сервере авторизации) через RP (клиентское приложение OAuth), указанное выше значение сеанса вычисляется на сервере. Он отправляется обратно RP с ответом аутентификации.

Давайте посмотрим, как этот статус сеанса используется в RP для проверки статуса сеанса пользователя.

Опрос iframe OP из iframe RP, чтобы узнать статус сеанса OP

RP загружает из себя невидимый iframe для iframe RP, а также загружает в себя невидимый iframe OP из конечной точки OP check_session_iframe.

Этот iframe RP должен знать идентификатор iframe OP, чтобы он мог публиковать сообщения в iframe OP через HTML5 postMessage (). RP iframe вызывает Window.postMessage () в OP iframe, чтобы определить, действителен ли сеанс конечного пользователя в OP. RP Iframe должен отправлять значения client_id и состояния сеанса с каждым из этих запросов.

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

RP iframe должен постоянно публиковать сообщения (опрос) в OP iframe с интервалом в соответствии с требованиями приложения.

OP iframe имеет доступ к состоянию браузера в OP (в файле cookie или в хранилище HTML5), которое он использует для вычисления и сравнения с состоянием сеанса OP, которое передается RP с каждым запросом.

OP iframe пересчитывает текущий статус сеанса из идентификатора клиента (отправленного с запросом), исходного URL-адреса (из postMessage) и текущего состояния OP-браузера (например, значение файла cookie сеанса, если файл cookie используется для управления состоянием браузера) . Состояние сеанса включает всю эту информацию по соображениям конфиденциальности, поэтому разные клиенты, активные в одном браузере, имеют разные значения состояния сеанса.

Если полученное сообщение postMessage синтаксически искажено таким образом, что опубликованный идентификатор клиента и исходный URL не могут быть определены или являются синтаксически недопустимыми, тогда OP iframe возвращает строку «error» обратно источнику. Если полученное значение и рассчитанное значение не совпадают, тогда в OP iframe postMessage строка «изменилась» обратно на источник. Если он совпадает, то он ДОЛЖЕН публиковать в сообщении строку «без изменений».

RP iframe должен иметь возможность получать postMessage обратно из OP iframe. Полученные данные будут одним из следующих строковых значений.

  • «изменено» - указывает, что сеанс изменился на OP. Это может произойти из-за выхода пользователя из системы, тайм-аута сеанса или входа пользователя в систему из другого клиентского приложения. После получения изменения RP выполняет повторную аутентификацию с prompt = none, чтобы получить текущее состояние сеанса на OP.
  • без изменений’ - указывает, что сеанс пользователя все еще действителен в OP. RP продолжит опрашивать iframe OP для обнаружения любых изменений сеанса.
  • error’ - если OP определил, что синтаксис отправленного сообщения имеет неправильный формат, полученные данные будут ошибочными. При получении ошибки RP не должен выполнять повторную аутентификацию с prompt = none, чтобы не вызвать потенциальных бесконечных петель, которые генерируют сетевой трафик к OP.

Когда RP обнаруживает изменение состояния сеанса, когда он получает в ответ «изменено», он сначала попробует запрос prompt = none в iframe RP, чтобы получить новый идентификатор идентификатора и текущее состояние сеанса пользователя. Он должен отправить старый токен идентификатора в качестве параметра id_token_hint, который требуется для получения информации об аутентифицированном пользователе в OP. Если RP получает токен идентификатора для того же конечного пользователя, он просто обновит значение состояния сеанса до нового значения. Если он не получает токен идентификатора или получает токен идентификатора для другого конечного пользователя, это означает, что пользователь вышел из приложения, сеанс пользователя истек или этот пользователь вошел в систему как другой пользователь из другой RP. Следовательно, он должен обрабатывать этот случай как выход из системы для исходного конечного пользователя.

Поскольку состояние сеанса привязано к источнику, оно также будет возвращено с ответом об ошибке аутентификации.

Следующая диаграмма иллюстрирует вышеуказанные сценарии.

OP Состояние браузера

Состояние браузера OP обычно сохраняется в локальном хранилище файлов cookie или HTML5. Это источник привязан к серверу авторизации. Он фиксирует значимые события, такие как вход в систему, выход из системы, смена пользователя, изменение статуса аутентификации для Клиентов, используемых Конечным пользователем, и т. Д. Таким образом, OP СЛЕДУЕТ обновлять значение состояния браузера в ответ на такие значимые события. В результате следующий вызов check_session () после такого события вернет измененное значение. РЕКОМЕНДУЕТСЯ, чтобы OP не обновлял состояние браузера слишком часто при отсутствии значимых событий, чтобы сэкономить чрезмерный сетевой трафик на клиенте в ответ на ложные измененные события.

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

В случае авторизованного Клиента (успешный ответ аутентификации) OP ДОЛЖЕН изменить значение состояния сеанса, возвращаемое Клиенту при одном из следующих событий:

  • Набор пользователей, прошедших аутентификацию в браузере, изменяется (вход, выход, добавление сеанса).
  • Статус аутентификации Клиентов, используемых Конечным пользователем, изменяется.

Кроме того, состояние браузера, используемое для проверки состояния сеанса, ДОЛЖНО измениться с такими событиями. После таких событий вызовы check_session () вернут измененное по сравнению с более ранними версиями состояния сеанса. РЕКОМЕНДУЕТСЯ, что состояние браузера НЕ ДОЛЖНО изменяться слишком часто в отсутствие таких событий, чтобы минимизировать сетевой трафик, вызванный ответом Клиента на измененные уведомления.

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

Если файл cookie используется для поддержания состояния OP-браузера, флаг HttpOnly, скорее всего, не может быть установлен для этого файла cookie, поскольку к нему необходимо получить доступ из JavaScript. Следовательно, информацию, которая может быть использована для идентификации пользователя, не следует помещать в cookie, поскольку она может быть прочитана несвязанным JavaScript.

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

Выход из системы, инициированный RP

RP может уведомить OP о том, что конечный пользователь вышел из сайта и может также захотеть выйти из OP. В этом случае RP после выхода Конечного пользователя из RP перенаправляет агента пользователя Конечного пользователя на URL-адрес конечной точки выхода OP. Этот URL-адрес получается через end_session_endpoint, описанный выше.

Следующие параметры являются необязательными и рекомендуется передавать в качестве параметров запроса в запросе выхода из системы.

  • id_token_hint - ранее выданный идентификатор идентификатора передается конечной точке выхода в качестве подсказки о текущем сеансе аутентификации конечного пользователя с клиентом. Это используется как указание на идентичность конечного пользователя, которого RP запрашивает, чтобы OP вышел из системы. OP не обязательно должен быть указан как аудитория идентификатора токена, когда он используется в качестве значения id_token_hint.
  • post_logout_redirect_uri - URL-адрес, на который RP запрашивает перенаправление агента пользователя конечного пользователя после выхода из системы. Значение ДОЛЖНО быть предварительно зарегистрировано в OP либо с помощью параметра регистрации post_logout_redirect_uris, либо с помощью другого механизма. Если предоставлено, OP ДОЛЖЕН выполнить этот запрос после выхода из системы.
  • state - непрозрачное значение, используемое RP для поддержания состояния между запросом выхода и обратным вызовом к конечной точке, указанной параметром запроса post_logout_redirect_uri. Если он включен в запрос на выход, OP передает это значение обратно RP, используя параметр запроса состояния при перенаправлении агента пользователя обратно на RP.