Avanpost FAM реализует функциональность OpenID Connect Identity Provider и предоставляет для приложений и систем набор HTTP(S)-методов в соответствии с протоколами OAuth 2.0 и OpenID Connect.
Avanpost FAM предоставляет приложениям полнофункциональную реализацию протоколов OpenID Connect 1.0 и OAuth 2.0 и включает в себя следующие возможности:
- Аутентификация посредством всех стандартных Grant Types/OAuth 2.0 Flow:
- Authorization Code Grant,
- Authorization Code Grant with PKCE,
- Refresh Token Grant,
- Password Grant,
- Client Credentials Grant,
- Implicit Grant,
- Hybrid Grant.
- Поддержка публичных (Single-Page-приложения, мобильные приложения) и не публичных (приложения с бэкендом) клиентов с явным разделением.
- Поддержка стандартных наборов (scopes) атрибутов (claims) OpenID Connect:
openid
,profile
,email
,phone
. - Поддержка механизма передачи авторизационных наборов атрибутов на основе членства пользователя в группе:
groups
,groups:name
,groups:name:join
,groups:by_app
. - Поддержка расширяемых настраиваемых наборов атрибутов с возможностью:
- Передачи значения из дополнительного атрибута профиля пользователя;
- Передачи значения, вычисляемого на основе ECMAScript-скрипта (JavaScript-подобного) и основных и дополнительных атрибутов профиля пользователя;
- Передачи константы.
- CORS (Cross-Origin Resource Sharing) для Single-Page без бэкенда и мобильных приложений.
- Формирование с Access Token в стандартном формате случайной строки либо в формате JWT.
- Аутентификация запросов со стороны сервера приложений (Client Assertion Type) по методам
client_secret_basic
,client_secret_jwt
иprivate_key_jwt
.
В части аутентификации, работы с сессиями и токенами Avanpost FAM предоставляет следующие возможности:
- 2FA/MFA с использованием различных методов аутентификации.
- Прозрачная аутентификация посредством Single Sign-On с использованием механизма сессий.
- Централизованное завершение сессии посредством механизма Backchannel-Logout.
В части управления и администрирования OpenID Connect в Avanpost FAM предоставляет следующие возможности для каждого OpenID Connect-приложения:
- Настройку сроков жизни токенов всех типов (Authorization Code, Access Token, ID Token, Refresh Token) для каждого OpenID Connect-приложения.
- Настройку client_id с возможностью использовать значение, сформированное автоматически Avanpost FAM.
- Настройку формата Access Token в формате JWT либо случайного значения.
- Настройку стратегии завершения сессии при выходе пользователя из приложения.
- Настройку произвольных Scopes и Claims для каждого OpenID Connect-приложения с вычислением значения на основе JavaScript-сценария.
- Настройку модели доступа (Resources и Scopes) для каждого OpenID Connect-приложения.
- Настройку CORS.
Схематично аутентификация в приложение с использованием OpenID Connect Avanpost FAM выглядит следующим образом:
Сценарии использования
Некоторые возможные сценарии использования OpenID Connect-интерфейса для решения прикладных задач:
- 2FA/MFA и SSO/SLO для веб-приложений.
- 2FA/MFA и SSO/SLO для десктопных приложений.
- 2FA/MFA и SSO/SLO для мобильных приложений.
- Делегированная авторизация пользователей приложений (веб-приложений, десктопных приложений, мобильных приложений).
- Централизованная аутентификация для API, сервисов и микросервисов.
- Делегированная авторизация для API, сервисов и микросервисов.
2FA/MFA и SSO/SLO для веб-приложений
Avanpost FAM может быть использован для реализации SSO/SLO/2FA/MFA-сценариев для веб-приложений при их подключении по OpenID Connect.
Интеграция веб-приложений с Avanpost FAM выполняется посредством стандартных механизмов OpenID Connect.
Для подключения веб-приложений рекомендуется использование Authorization Code Flow with PKCE.
2FA/MFA и SSO/SLO для десктопных приложений
Avanpost FAM может быть использован для реализации SSO/SLO/2FA/MFA-сценариев для десктопных приложений при их подключении по OpenID Connect. Для унаследованных десктопных приложений без возможности реализации OAuth/OpenID Connect и других IdP-механизмов следует рассмотреть механизм Enterprise SSO.
Ниже описаны возможные варианты реализации интеграции десктопного приложения с системой Avanpost FAM.
Выбор сценария аутентификации (OAuth 2.0 Flow)
Для Native-приложений допустимо использование следующих сценариев (OAuth 2.0 Flow):
- Authorization Code Flow;
- Authorization Code Flow with PKCE.
Authorization Code Flow следует использовать при наличии у целевого приложения backend на сервере закрытого канала связи до token_endpoint
Системы.
Authorization Code Flow with PKCE следует использовать при отсутствии у целевого приложения backend закрытого канала связи до token_endpoint
Системы.
Возврат кода авторизации (OAuth 2.0 Authorization Code) из Системы в приложение
Для возврата кода авторизации (OAuth 2.0 Authorization Code) аутентифицированного Системой пользователя в десктопное приложение возможно несколько схем:
- Отображение интерфейса аутентификации Системы в WebView внутри приложения с чтением кода из адреса запроса в WebView;
- Отображение интерфейса аутентификации Системы в браузере с возвратом кода авторизации посредством нестандартной схемы URI приложения;
- Отображение интерфейса аутентификации Системы в браузере с возвратом кода авторизации посредством передачи запроса к локальному веб-серверу приложения.
Выбор схемы зависит от возможностей приложения и платформы, на которой выполняется приложение.
Отображение интерфейса аутентификации Системы в WebView внутри приложения с чтением кода из адреса запроса в WebView
Для сценария требуется, чтобы приложение обладало следующими возможностями:
- Отображение WebView внутри приложения.
- Получение информации об адресе (URL), открытом в настоящий момент в WebView.
Если приложение считает, что требуется выполнить аутентификацию пользователя средствами Системы, то:
- Приложение формирует запрос к
authorization_endpoint
в соответствии с выбранной схемой (Authorization Code Flow либо Authorization Code Flow with PKCE) и открывает сформированный запрос в WebView внутри приложения. - Система в ответ на этот запрос отображает веб-интерфейс аутентификации. Пользователь выполняет аутентификацию в Системе, используя веб-интерфейс Системы.
- После прохождения аутентификации Система выполняет перенаправление пользователя на адрес, содержащий заполненный HTTP Query String параметр
code
. Приложение считывает значение параметраcode
. - Приложение формирует запрос, используя полученный
code
, кtoken_endpoint
Системы и получает в ответ набор токенов (Access Token, ID Token, Refresh Token). Пользователь аутентифицирован.
Реализация данной схемы на стороне приложения и регистрация схемы URL для обработки приложением различается в зависимости от платформы (операционной системы), поэтому для этого следует руководствоваться документацией для разработчиков под платформу:
- Для приложений на базе Windows: https://docs.microsoft.com/en-us/previous-versions/windows/internet-explorer/ie-developer/platform-apis/aa767914(v=vs.85)?redirectedfrom=MSDN
- Для приложений на базе Linux: https://specifications.freedesktop.org/desktop-entry-spec/desktop-entry-spec-latest.html#exec-variables
- Для приложений на базе iOS/MacOS X: https://developer.apple.com/documentation/xcode/defining-a-custom-url-scheme-for-your-app
- Для приложений на базе Android: https://developer.android.com/training/app-links
Отображение интерфейса аутентификации Системы в браузере с возвратом кода авторизации посредством нестандартной схемы URI приложения
Запрос к authorization_endpoint
Avanpost FAM для данного сценария должен содержать параметр response_mode
со значением link
. Данный response_mode
не является стандартным с точки зрения протокола OAuth 2.0.
Для сценария требуется, чтобы приложение и платформа (операционная система на устройстве пользователя) обладали следующими возможностями:
- Открытие со стороны приложения URL в браузере, зарегистрированном в операционной системе как браузер по умолчанию.
- Регистрация нестандартной схемы URL в операционной системе при установке приложения на устройство пользователя.
- Обработка запроса к приложению по URL при запросе от браузера.
Если приложение считает, что требуется выполнить аутентификацию пользователя средствами Системы, то:
- Приложение формирует запрос к
authorization_endpoint
в соответствии с выбранной схемой (Authorization Code Flow либо Authorization Code Flow with PKCE), с той лишь разницей, что в запросе должен быть передан параметрresponse_mode
, содержащий значениеlink
. Приложение открывает сформированный запрос в браузере пользователя по умолчанию. - Система в ответ на этот запрос отображает веб-интерфейс аутентификации. Пользователь выполняет аутентификацию в Системе, используя веб-интерфейс Системы.
- После прохождения аутентификации Система отображает в браузере страницу Системы, содержащую ссылку с нестандартной схемой URL приложения и значение
code
. После подтверждения пользователем запроса на открытие ссылки браузер через вызов к платформе (операционной системе) запускает приложение с указанным URL. Приложение считывает значение параметраcode
. - Приложение формирует запрос, используя полученный
code
, кtoken_endpoint
Системы и получает в ответ набор токенов (Access Token, ID Token, Refresh Token). Пользователь аутентифицирован.
Отображение интерфейса аутентификации Системы в браузере с возвратом кода авторизации посредством передачи запроса к локальному веб-серверу приложения
Для реализации сценария требуется, чтобы приложение и платформа (операционная система на устройстве пользователя) обладали следующими возможностями:
- Запуск приложением локального веб-сервера, принимающего HTTP-запросы.
Если приложение считает, что требуется выполнить аутентификацию пользователя средствами Системы, то:
- Приложение формирует запрос к
authorization_endpoint
в соответствии с выбранной схемой (Authorization Code Flow либо Authorization Code Flow with PKCE). Приложение открывает сформированный запрос в браузере пользователя по умолчанию. - Система в ответ на этот запрос отображает веб-интерфейс аутентификации. Пользователь выполняет аутентификацию в Системе, используя веб-интерфейс Системы.
- После прохождения аутентификации Система перенаправляет пользователя на адрес локального веб-сервера с передачей в запросе значения параметра
code
. - Приложение формирует запрос, используя полученный
code
, кtoken_endpoint
Системы и получает в ответ набор токенов (Access Token, ID Token, Refresh Token). Пользователь аутентифицирован.
2FA/MFA и SSO/SLO для мобильных приложений
Avanpost FAM может быть использован для реализации SSO/SLO/2FA/MFA-сценариев для мобильных приложений при их подключении по OpenID Connect.
Интеграция мобильных приложений с Avanpost FAM выполняется посредством стандартных механизмов OpenID Connect.
Делегированная авторизация пользователей приложений (веб-приложений, десктопных приложений, мобильных приложений)
Avanpost FAM может быть использован для реализации сценариев делегированной авторизации для различных приложений при их подключении по OpenID Connect в рамках стандарта OAuth User-Managed Access (UMA) 2.0.
Централизованная аутентификация для API, сервисов и микросервисов
Avanpost FAM может быть использован для реализации сценариев кросс-аутентификации для API, сервисов и микросервисов при их подключении по OpenID Connect.
Делегированная авторизация для API, сервисов и микросервисов
Avanpost FAM может быть использован для реализации сценариев делегированной авторизации в рамках функциональности кросс-аутентификации для API, сервисов и микросервисов при их подключении по OpenID Connect в рамках стандарта OAuth User-Managed Access (UMA) 2.0.
Методика интеграции
Общая методика интеграции будет описана позднее.
Диагностика ошибок
Доступные методы диагностики ошибок:
- Анализ журнала событий безопасности.
- Анализ сообщений в процессе аутентификации.
- Анализ системного журнала на сервере службы.
Анализ журнала событий безопасности
В административной консоли доступен отдельный тип событий «OpenID Connect», который позволяет проанализировать входящие от приложений запросы.
Анализ сообщений в процессе аутентификации
OAuth 2.0 и OpenID Connect предоставляют наборы отладочных сообщений об ошибке в процессе аутентификации. В случае тестирования сценария аутентификации через браузер при наличии ошибок система предоставляет сообщение об ошибке error и подсказку error_hint, которых как правило достаточно для анализа проблем.
Анализ системного журнала на сервере службы
Служба регистрирует стандартный журнал, предоставляющий развёрнутую информацию об ошибках. Журнал может быть просмотрен и проанализирован стандартными инструментами операционной системы, к примеру, journalctl.
Приложение А. Endpoint'ы OpenID Connect
Доступные в Avanpost FAM в OpenID Connect Identity Provider методы:
Endpoint | URI Path | Назначение |
---|---|---|
Discovery Endpoint | https://${baseUrl}/.well-known/oauth-authorization-server | Discovery-запрос метаинформации о параметрах сервера авторизации в соответствии со спецификацией OAuth 2.0 |
| Discovery-запрос метаинформации о параметрах сервера аутентификации в соответствии со спецификацией OpenID Connect | |
Public Key Endpoint | https://${baseUrl}/oauth2/public_keys | Получение перечня открытых ключей в формате JSON Web Key Set, с использованием которых должна выполняться проверка подписи токенов |
Authorization Endpoint | https://${baseUrl}/oauth2/authorize | Выполнение аутентификации и авторизации с применением одного из доступных OAuth-сценариев (OAuth 2.0 Flow) |
Token Endpoint | https://${baseUrl}/oauth2/token | Выпуск и перевыпуск токенов после выполнения аутентификации и авторизации |
Token Introspection Endpoint | https://${baseUrl}/oauth2/token/introspect | Запрос сведений об актуальности токенов |
Token Revocation Endpoint | https://${baseUrl}/oauth2/token/revoke | Запрос на отзыв токенов, инициируемый приложением |
Userinfo Endpoint | https://${baseUrl}/oauth2/userinfo | Получение расширенной информации о пользователе |
End Session Endpoint | https://${baseUrl}/oauth2/end_session | Завершение сессии, инициируемое приложением |
Приложение Б. Структура OpenID Connect-токенов
Токены, используемые приложениями в рамках взаимодействий по OAuth и OpenID Connect, имеют различное предназначение и обладают некоторыми особенностями. Сравнение используемых токенов в Avanpost FAM приведено в таблице:
Критерий | Access Token | ID Token | Refresh Token |
---|---|---|---|
Назначение | Предоставление полномочий пользователя | Идентификация и предоставление сведений о пользователе | Перевыпуск токенов |
Структура | JWT с дополнительными атрибутами либо случайная строка (в зависимости от значения параметра «Access token type» конкретного приложения) | JWT с дополнительными атрибутами | Случайная строка |
Срок жизни токена | Зависит от значения параметра «Access token lifetime (in seconds) » конкретного приложения (client_id ); по умолчанию 3600 с. | Зависит от значения параметра «I » конкретного приложения (client_id ); по умолчанию 3600 с. | Зависит от значения параметра «Refresh token lifetime (in seconds) » конкретного приложения (client_id ); по умолчанию 7200 с. |
Получение стандартных OAuth/OpenID Connect Claims | Да, только REQUIRED в соответствии с RFC | Да | Нет |
Получение дополнительных Claims | Да, в случае использования в приложении формата JWT | Да | Нет |
Получение прав доступа пользователя | Да | Да | Нет |
Валидация токена | Да, подпись | Да, подпись | Нет |
Access Token
Данный вид токенов используется в соответствии со спецификацией OAuth для подтверждения авторизации пользователя. Токены, выпускаемые Системой, описаны в формате JWT и содержат в себе только минимальный набор обязательных атрибутов в соответствии со стандартом JWT, которые могут потребоваться приложению. Дополнительные scopes и claims в состав Access Token не включаются, в отличие от ID Token.
Access Token представляет из себя JWT в формате Base64 URL encoded-строки либо случайную строку. В формате JWT Access Token включает в себя, заголовок (header), содержимое (payload) и подпись.
Пример заголовка HTTP-ответа:
{ "alg": "RS256", "kid": "15js14w0djw388w" }
Пример содержимого HTTP-ответа:
{ "aud": "application", "client_id": "application", "exp": 1609249840, "iat": 1609246240, "iss": "idp.demo.avanpost.ru", "sid": "1a052aa6-a014-422e-8010-6d525018d488", "sub": "7c74be14-883c-4e62-80a7-737e10a57280", "uid": "7c74be14-883c-4e62-80a7-737e10a57280" }
Набор атрибутов, доступных в JWT, их назначение и способы получения описаны в таблице.
Срок жизни Access Token зависит от значения параметра «Access token lifetime (in seconds)
» конкретного приложения (client_id).
Максимальный срок жизни выпущенного токена содержится в атрибуте exp
JWT Access Token и может быть использован для контроля его актуальности на стороне приложения.
ID Token
ID Token представляет из себя JWT в формате Base64 URL encoded-строки. Включает в себя, заголовок (header), содержимое (payload) и подпись.
Пример заголовка HTTP-ответа (HTTP Header):
{ "alg": "RS256", "kid": "15js14w0djw388w" }
Пример содержимого HTTP-ответа (HTTP Payload):
{ "iss": "demo.avanpost.ru", "sub": "7c74be14-883c-4e62-80a7-737e10a57280", "aud": "arm", "exp": 1609249840, "iat": 1609246240, "email": "user@testmail.ru", "email_verified": true, "sid": "1a052aa6-a0b4-422e-8010-6d525018d478", "at_hash": "WjybnLKINSmFjJ0ppbvhmg", "uid": "7c74be49-ba3c-4e62-80a7-737e10a57280" }
Набор атрибутов, доступных в JWT, их назначение и способы получения описаны в таблице.
Срок жизни ID Token зависит от значения параметра «ID token lifetime (in seconds)
» конкретного приложения (client_id).
Refresh token
Срок жизни Refresh Token зависит от значения параметра «Refresh token lifetime (in seconds)» конкретного приложения (client_id).
Набор атрибутов в JWT
Стандартные атрибуты, передаваемые в составе JWT, имеют следующую структуру:
Параметр | Scope для Access Token | Scope для ID Token | Описание | Тип значения |
---|---|---|---|---|
iss | пусто | openid | Хост, настроенный в параметре | String |
exp | пусто | openid | UTC timestamp, когда истечения срока действия Access Token | UTC Timestamp Integer |
aud | пусто | openid |
| String |
sub | пусто | openid | Идентификатор пользователя | UUID String |
iat | пусто | openid | UTC timestamp, когда JWT Access Token был выпущен | UTC Timestamp Integer |
sid | пусто | openid | Идентификатор сессии в БД Системы | UUID String |
jti | пусто | - | Идентификатор токена | UUID String |
scope | пусто | - | Набор утверждений, который был запрошен для выдачи Access Token в составе запроса к Authorization Endpoint | String |
expires_in | пусто | - | Срок истечения информации, представленной в Access Token, в секундах | Integer |
at_hash | - | openid | Хеш Access Token, выпущенного совместно с ID Token (для дополнительной привязки ID Token к Access Token и валидации) | Hash String |
name | пусто | openid | Полное ФИО пользователя, сформированное путём конкатенации с разделителем « » | String |
client_id | пусто | openid | Идентификатор приложения (client_id), настроенный для приложения, либо синоним (ID Synonym) | String |
uid | uid | openid uid | Идентификатор пользователя | UUID String |
permissions | permissions | openid permissions | Структура с правами доступа пользователя в рамках данного приложения | Permission Array |
groups | groups |
| Структура с перечнем групп, в которых состоит пользователь, в рамках Системы; поддерживает несколько форматов предоставления результата, выбор формата зависит от переданного scope |
|
family_name | profile | openid profile | Фамилия | String |
given_name | profile | openid profile | Имя | String |
locale | profile | openid profile | Буквенный код предпочитаемого языка (локали) пользователя (ru , en и т.д.) | String |
preferred_username | profile | openid profile | Предпочитаемый логин пользователя | String |
updated_at | profile | openid profile | Метка последнего изменения данных профиля | UTC Timestamp Integer |
email | email | openid email | Адрес электронной почты | Email String |
email_verified | email | openid email | Признак подтверждённого адреса электронной почты | Boolean String |
phone | phone | openid phone | Номер телефона | Phone String |
phone_verified | phone | openid phone | Признак подтверждённого номера телефона | Boolean String |
Структура значений атрибута с информацией о правах пользователя (permissions)
Массив прав доступа возвращается при использовании механизма авторизации Системы и возвращается только в том случае, если пользователь авторизован и если у пользователя имеются какие-либо полномочия в составе приложения. Если у пользователя нет прав в контексте данного приложения, то claim permissions
возвращён не будет.
Массив прав доступа будет возвращён в составе Access Token или ID Token только в том случае, если в запросе содержится scope permissions
.
Пример permissions
в составе Access Token, выпущенного Системой:
..., "permissions": [{ "resource_id": "avanpostfam-permission", "resource_scopes": [ "view", "print", "edit" ] }], ...
В данном примере в составе permissions
содержатся:
- параметр
resource_set_id
содержит идентификатор объекта доступа, на которые пользователю выдано разрешение; - массив
scopes
содержит набор идентификаторов операций с указанным объектом доступа, на выполнение которых пользователю выдано разрешение.
Структура значений атрибута с информацией о группах пользователя (groups)
Если в атрибуте scope
содержится значение groups, то в claim groups
в составе JWT будет возвращён полный JSON-массив групп, содержащий UUID-идентификатор группы (id
), её наименование (name
) и описание (description
):
... "groups": [ { "id": "edf997b2-0140-4c30-9011-9f80dc787211", "name": "adminconsole" }, { "id": "4e1caffc-97b7-4b22-88a0-578bd997cc34", "name": "fam-arm", "description": "Группа доступа АРМ" }, { "id": "2cdd9d54-1d6e-40c6-9ab2-70a070437e76", "name": "fam-app1", "description": "Группа доступа для Приложения 1" } ], ...
Если в атрибуте scope
содержится значение groups:name
, то в составе JWT будет возвращён сокращённый JSON-массив групп, содержащий только наименования групп:
..., "groups": [ "adminconsole", "fam-arm", "fam-app1" ], ...
Если в атрибуте scope содержится значение groups:name:join
, то в составе JWT будет возвращена строка, выполненная путём конкатенации имён групп символом-разделителем «,
»:
... "groups": "adminconsole,arm,app1", ...
Если в атрибуте scope содержится значение groups:by_app
, то в составе JWT будет возвращена строка, содержащая только группы приложения:
... "groups": "adminconsolegbroup1,adminconsolegroup2", ...
Перечень ключей для вычисления значений claim'а с типом «Вычисляемое значение»
При выборе типа значения для claim «Вычисляемое значение» можно использовать следующий перечень стандартных ключей:
Атрибут | Обращение в коде | Содержащееся значение |
---|---|---|
id | user.id | Внутренний UUID-идентификатор пользователя |
userName | user.userName | Логин пользователя |
familyName | user.familyName | Фамилия |
givenName | user.givenName | Имя |
middleName | user.middleName | Отчество |
email | user.email | Адрес E-mail |
emailVerified | user.emailVerified | Признак того, что E-mail подтверждён |
locale | user.locale | Локаль пользователя |
phoneNumber | user.phoneNumber | Номер телефона |
phoneNumberVerified | user.phoneNumberVerified | Признак того, что номер телефона подтверждён |
updatedAt | user.updatedAt | Метка времени (timestamp) последнего обновления записи пользователя |
domain | user.domain | Домен пользователя |
isLocked | user.isLocked | Блокировка пользователя |
Для обращения к значению дополнительного атрибута следует использовать обращение через ключ user.extra.
, добавляя наименование дополнительного атрибута. К примеру, для обращения к значению дополнительного атрибута snils
следует использовать ключ user.extra.snils
.