[ ] [ Настройка Avanpost ESIA IdP Adapter ] [ Выпуск сертификата ЕСИА Адаптер ] [ Утилита для генерации GUID ] [ Приложение А. Пример настройки переменных окружения ] [ Приложение Б. Пример файла clients.json ] [ Приложение В. Пример конфигурационного файла внешнего провайдера идентификации ] [ Приложение Г. Список эндпоинтов ЕСИА Адаптер ]
Avanpost ESIA IdP Adapter представляет собой OpenID Connect-сервер, который перенаправляет аутентификацию пользователя в ЕСИА. Компонент реализует функции сервера OpenID Connect и клиента ЕСИА, позволяя осуществлять простую и централизованную аутентификацию в OIDC-приложениях при помощи механизма ЕСИА. Использование компонента позволяет выполнять настройку OIDC-приложений стандартизованным способом без необходимости отдельно настраивать специфичные для ЕСИА параметры. Обработка криптографических операций (подпись и проверка JWT) выполняется локально с использованием КриптоПро CSP, что повышает безопасность и упрощает интеграцию.
Компонент Avanpost ESIA IdP Adapter может использоваться для работы по протоколу OpenID Connect с любым OIDC-клиентом. В данной инструкции описывается настройка Avanpost ESIA IdP Adapter для Avanpost FAM Server.
Настройка Avanpost ESIA IdP Adapter
Настройку компонента следует выполнять следующим образом:
- Настроить в административной консоли FAM Server OIDC-приложение (описание настройки приложения представлено в статье Управление OpenID Connect-приложениями), в котором должен аутентифицироваться пользователь посредством ЕСИА.
- Настроить в административной консоли FAM Server IdP типа ЕСИА (описание настройки провайдера идентификации описано в статье Управление внешними провайдерами идентификации), посредством которого будет аутентифицироваться пользователь.
- Скачать Avanpost ESIA IdP Adapter из репозитория.
- Настроить конфигурацию Avanpost ESIA IdP Adapter при помощи переменных окружения, задав следующие параметры:
Параметр Значение DEBUG Флаг, активирующий режим отладки. При значении trueсервис выводит расширенную диагностическую информацию в логи. В рабочей среде рекомендуется устанавливать значениеfalse.BASE_URL Базовый URL-адрес, по которому доступен сервис Adapter. Должен соответствовать реальному сетевому расположению сервиса. HOST Сетевой интерфейс, на котором сервис Adapter принимает входящие HTTP-соединения. PORT Номер порта, на котором сервис Adapter ожидает входящие HTTP-запросы. KEY Путь к файлу, содержащему приватный RSA-ключ в формате PEM. Этот ключ использует IdP Adapter для подписи JWT-токенов (ID Token, Access Token), выдаваемых OIDC-клиентам. KEY_ID Уникальный идентификатор приватного ключа, указанного в параметре KEY. Используется для ссылки на конкретный ключ в наборе ключей.CLIENTS Путь к JSON-файлу, содержащему список доверенных OIDC-клиентов. Каждая запись в файле определяет IDклиента и егоDomainдля валидацииredirect_uri.EXTIDP Путь к JSON-файлу, содержащему конфигурацию внешнего провайдера идентификации (ЕСИА). Данный файл определяет параметры подключения к ЕСИА. EXTIDP_REQUEST_TTL Время жизни запроса к внешнему IdP (ЕСИА). Определяет, как долго Adapter будет хранить состояние (state) и другие параметры запроса авторизации до его завершения или истечения срока действия.. EXTIDP_REQUEST_CLEAN_UP Интервал времени, по истечении которого сервис выполняет фоновую очистку устаревших или завершенных запросов к внешнему IdP. USERINFO_TTL Время жизни кэшированной информации о пользователе, полученной от ЕСИА. Используется, чтобы избежать повторных запросов к API ЕСИА в течение указанного периода. USERINFO_CLEAN_UP Интервал времени, по прошествии сервис выполняет фоновую очистку устаревшей кэшированной информации о пользователях. SESSION_COOKIE_NAME Имя HTTP cookie, используемой Adapter для хранения идентификатора сессии пользователя. SESSION_COOKIE_LIFETIME Время жизни сессионной HTTP cookie в секундах. Определяет, как долго браузер пользователя будет хранить куку до ее автоматического удаления. SESSION_COOKIE_SECURE Флаг безопасности для сессионной cookie. При значении truecookie будет передаваться только по защищенному HTTPS-соединению.SESSION_EXPIRED Время жизни серверной сессии пользователя в секундах. Определяет, через какое время неактивная сессия будет автоматически уничтожена на стороне сервера. CPROCSP_BIN_DIR Путь к директории, содержащей исполняемые файлы криптопровайдера КриптоПро CSP. NODEID Уникальный идентификатор экземпляра (ноды) адаптера. Используется для корректной работы внешней балансировки нагрузки ЕСИА Адаптера. Параметр (nid) передается внутри параметра state при формировании Authorization Code. В сценарии Authorization Code Flow код генерируется на одной ноде, и для его обмена на токен важно, чтобы запрос попал на ту же ноду. Параметр помогает обеспечить маршрутизацию последующих запросов от того же клиента на ту же ноду. GEN_GUIDS_BIN_PATH Путь к бинарному файлу утилиты genguids. Указывается абсолютный путь к исполняемому файлу. Пример значения: /opt/avanpost/esia-adapter/genguids.GEN_GUIDS_BATCH_SIZE Количество генерируемых идентификаторов за один вызов утилиты genguids. Определяет, сколько UUID будет сгенерировано при каждом обращении к утилите. GEN_GUIDS_SEPARATOR Разделитель идентификаторов в выводе утилиты genguids. Определяет символ или последовательность символов, которыми разделяются сгенерированные UUID в потоке вывода. Пример значения: \r. - Для автоматического запуска Avanpost ESIA IdP Adapter при загрузке системы необходимо зарегистрировать его как службу systemd:
- Создать конфигурационный файл службы при помощи команды:
sudo vi /etc/systemd/system/esia-idp.service
- Настроить конфигурационный файл согласно примеру:
[Unit] Description=Avanpost ESIA IdP Adapter After=network.target [Service] WorkingDirectory=/opt/esia-idp ExecStart=/opt/esia-idp/esia-idp Restart=always RestartSec=10 SyslogIdentifier=esia-idp User=esia-idp Environment="DEBUG=false" Environment="BASE_URL=https://esia-adapter.corp:4010" Environment="CPROCSP_BIN_DIR=/opt/cprocsp/bin/amd64" [Install] WantedBy=multi-user.target
- Выполнить команды:
sudo systemctl daemon-reload sudo systemctl enable esia-idp sudo systemctl start esia-idp
- Создать конфигурационный файл службы при помощи команды:
- Убедиться, что пользователь корректно проходит аутентификацию в целевом OIDC-приложении посредством ЕСИА.
Выпуск сертификата ЕСИА Адаптер
Для интеграции Avanpost FAM с Единой системой идентификации и аутентификации (ЕСИА) требуется:
- Выпустить ГОСТ-совместимый сертификат в тестовом удостоверяющем центре (УЦ) КриптоПро;
- Зарегистрировать сертификат в ЕСИА.
До начала работы с УЦ требуется выполнить следующие действия:
- Установить СКЗИ КриптоПро CSP;
- Установить КриптоПро ЭЦП Browser plug-in;
- Скачать и установить корневой сертификат тестового Удостоверяющего центра в хранилище Доверенные корневые центры сертификации;
- Скачать и установить промежуточный сертификат тестового Удостоверяющего центра в хранилище Промежуточные центры сертификации.
Для работы с УЦ рекомендуется использовать браузер с поддержкой ГОСТ TLS, например: chromium-gost, Internet Explorer, Яндекс.Браузер, Microsoft Edge (в режиме Internet Explorer). Для работы браузеров отличных от IE, следует установить расширение для Chrome-подобных браузеров или Яндекс.Браузера.
Выпуск и регистрацию сертификата для ЕСИА Адаптера требуется выполнять следующим образом:
- Войти в УЦ:
- Допускается авторизоваться под учётной записью тестового пользователя:
- Логин: avanpost-dev-2;
- Пароль: 7705494692.
- Допускается зарегистрировать нового пользователя.
- Допускается авторизоваться под учётной записью тестового пользователя:
- Убедиться, что в профиле заполнены все обязательные поля для ЕСИА:
- Общее имя;
- Страна;
- Область;
- Город;
- Адрес;
- Организация;
- ОГРН;
- ИНН ЮЛ.
Если вышеперечисленные поля не заполнены, сертификат не будет валиден для ЕСИА.
- Перейти в раздел "Сертификаты", нажать кнопку "Создать" и создать сертификат со следующими параметрами:
Параметр Значение Шаблон сертификата Тестовый квалифицированный сертификат Криптопровайдер Crypto-Pro GOST R 34.10-2012 Cryptographic Service Provider Ключ будет использоваться для Выбрать "Подписи и шифрования" Размер ключа 512 Алгоритм хеширования ГОСТ Р 34.11-2012 256 бит - Выпустить сертификат, используя в качестве хранилища ключа HDImage (директория).
- Открыть утилиту «Инструменты КриптоПро» (входит в состав CSP) и выбрать хранилище HDImage.
- Выбрать созданный сертификат и нажать кнопку «Экспортировать ключи».
- Выбрать «Экспортировать PXF в файл», указать пароль и сохранить файл.
- При помощи утилиты «Инструменты КриптоПро» экспортировать сертификат (без закрытого ключа) для регистрации в ЕСИА, нажав кнопку «Экспортировать сертификаты».
- Войти в тестовую ЕСИА:
- Логин: EsiaTest031@yandex.ru;
- Пароль: 11111111.
- Найти зарегистрированную информационную систему (интерфейс позволяет выполнить поиск по названию или по мнемонике).
- Нажать для перехода в раздел управления сертификатами.
- Нажать кнопку «Загрузить сертификат» и указать путь до ранее созданного сертификата.
Утилита для генерации GUID
Основным методом борьбы с CSRF-атаками является использование анти-CSRF токенов, (например, посредством генерации GUID). В сценариях аутентификации через ЕСИА параметр state используется для защиты от атак CSRF и обеспечения целостности сессии. Для генерации данного параметра реализована утилита genguids, обеспечивающая получение случайных значений на базе сертифицированного СКЗИ «КриптоПро CSP». При формировании авторизационного запроса к ЕСИА ESIA Adapter вызывает утилиту genguids. Утилита genguids генерирует UUID v4 (random-based) в соответствии с RFC 4122. Полученное значение используется как значение параметра state. Значение state сохраняется в сессии и впоследствии сверяется при получении ответа от ЕСИА.
Рекомендуется использовать утилиту genguids с ОС Astra Linux Special Edition, совместимой с КриптоПро CSP 5.0 R3.
При развертывании следует выполнить тестовый пуск утилиты в консоли на целевой системе:
- Выполнить проверку зависимостей связанных библиотек:
ldd ./genguids
- Запустить утилиту, задав через пробел количество генерируемых значений (в приведенном примере
1):./genguids 1
- Убедиться в корректности результата: вывод результата в формате UUID (пример: 5f39e5c2-ffc0-4b17-ac2a-3187339b02e4) и полученный код возврата 0.
Значения кодов возврата:
- 0 – успешное выполнение;
- 1 – ошибка аргумента командной строки;
- 2 – ошибка инициализации API КриптоПро CSP;
- 3 – ошибка генерации случайных чисел.
- Для автоматического запуска genguids компонентом настроить переменные окружения GEN_GUIDS_BIN_PATH, GEN_GUIDS_BATCH_SIZE, GEN_GUIDS_SEPARATOR.
Приложение А. Пример настройки переменных окружения
Ниже приведен пример конфигурирования Avanpost ESIA IdP Adapter при помощи переменных окружения:
{
"DEBUG": "false",
"BASE_URL": "http://localhost:4010",
"HOST": "0.0.0.0",
"PORT": 4010,
"KEY": "key.pem",
"KEY_ID": 1,
"CLIENTS": "clients.json",
"EXTIDP": "extidp.json",
"EXTIDP_REQUEST_TTL": "1h",
"EXTIDP_REQUEST_CLEAN_UP": "1h",
"USERINFO_TTL": "1h",
"USERINFO_CLEAN_UP": "1h",
"SESSION_COOKIE_NAME": "sid",
"SESSION_COOKIE_LIFETIME": 3600,
"SESSION_COOKIE_SECURE": "true",
"SESSION_EXPIRED": 3600,
"CPROCSP_BIN_DIR": "/opt/cprocsp/bin/amd64"
}
Приложение Б. Пример файла clients.json
Пример JSON-файла, содержащего список доверенных OIDC-клиентов
[
{
"ID": "pkce-only-client",
"Domain": "localhost:9094"
},
{
"ID": "client-with-secret",
"Secret": "test-secret",
"Domain": "example.com"
}
]
Приложение В. Пример конфигурационного файла внешнего провайдера идентификации
Пример JSON-файла, содержащего конфигурацию внешнего провайдера идентификации (ЕСИА). Допускается использовать файл из DevTools браузера (доступен при просмотре деталей настроенного внешнего IdP).
Параметру synonym должно соответствовать значение esia.
{
"id": "db2b0bcf-92d5-4ab7-805a-2c3e9f444d4e",
"authorizeUri": "{{.extidp_details.baseUrl}}/aas/oauth2/ac",
"redirectMethod": 0,
"type": "esia",
"name": "esia",
"synonym": "esia",
"typeDetails": " {\n \"baseUrl\": \"https://esia-portal1.test.gosuslugi.ru\",\n \"clientCertHash\": \"\",\n \"clientID\": \"04QN02\",\n \"cryptoProvider\": {\n \"details\": {\n \"certPath\": \"/Users/michael/Downloads/esia/esia/TESIA GOST 2012 new.cer\",\n \"containerPIN\": \"123\",\n \"sha1Thumbprint\": \"7f159ecf770dfb58489c7ad9ef45132b7e181092\"\n },\n \"name\": \"cprocsp_cms\"\n },\n \"scope\": \"openid fullname email mobile\",\n \"scopeOrg\": \"\"\n }",
"redirectForm": {
"response_type": "code",
"client_id": "{{ .extidp_details.clientID }}",
"redirect_uri": "{{ .extidp_request.CallbackURI }}",
"scope": "{{ .extidp_details.scope }}",
"scope_org": "{{ .extidp_details.scopeOrg }}",
"client_secret": "{{ $ts := timeFormat \"2006.01.02 15:04:05 Z0700\" .process_started}}{{$clientSecretRaw := join .extidp_details.scope $ts .extidp_details.clientID .extidp_request.ID}}{{ cryptoSign .context $clientSecretRaw .extidp_details.cryptoProvider | base64 }}",
"client_certificate_hash": "{{ .extidp_details.clientCertHash }}",
"timestamp": "{{ timeFormat \"2006.01.02 15:04:05 Z0700\" .process_started }}",
"state": "{{ .extidp_request.ID }}",
"access_type": "offline"
},
"userInfoPipeline": [
{
"t": 0,
"r": "token",
"d": {
"client_certificate_hash": "{{.extidp_details.clientCertHash}}",
"client_id": "{{.extidp_details.clientID}}",
"client_secret": "{{$ts := timeFormat \"2006.01.02 15:04:05 Z0700\" .process_started}}{{$clientSecretRaw := join .extidp_details.scope $ts .extidp_details.clientID .extidp_request.ID}}{{ cryptoSign .context $clientSecretRaw .extidp_details.cryptoProvider | base64 }}",
"code": "{{.code}}",
"grant_type": "authorization_code",
"redirect_uri": "{{.extidp_request.CallbackURI}}",
"scope": "{{.extidp_details.scope}}",
"state": "{{.extidp_request.ID}}",
"timestamp": "{{timeFormat \"2006.01.02 15:04:05 Z0700\" .process_started}}",
"token_type": "Bearer"
},
"m": "POST",
"u": "{{.extidp_details.baseUrl}}/aas/oauth2/te"
},
{
"t": 1,
"d": {
"verify_id_token": "{{ cryptoVerifyJWT .context .token.id_token .extidp_details.cryptoProvider }}"
}
},
{
"t": 2,
"d": {
"id_token_claims": "jwt(token.id_token)"
}
},
{
"t": 1,
"d": {
"is_trusted": "{{ with index .id_token_claims \"urn:esia:sbj\" \"urn:esia:sbj:is_tru\" }}{{ if not . }}{{ fail \"user is not trusted\" }}{{ end }}{{ end }}"
}
},
{
"t": 0,
"r": "person",
"m": "GET",
"u": "{{.extidp_details.baseUrl}}/rs/prns/{{printf \"%.0f\" .id_token_claims.sub}}",
"h": {
"Authorization": "Bearer {{.token.access_token}}"
}
},
{
"t": 0,
"r": "contacts",
"d": {
"embed": "(elements)"
},
"m": "GET",
"u": "{{.extidp_details.baseUrl}}/rs/prns/{{printf \"%.0f\" .id_token_claims.sub}}/ctts",
"h": {
"Authorization": "Bearer {{.token.access_token}}"
}
},
{
"t": 2,
"d": {
"main_email": "email = \"\"; for (i = 0; i < contacts.elements.length; i++) {if (contacts.elements[i].type === \"EML\" && contacts.elements[i].vrfStu === \"VERIFIED\") {email = contacts.elements[i].value}} email;",
"main_phone": "phone = \"\"; for (i = 0; i < contacts.elements.length; i++) {if (contacts.elements[i].type === \"MBT\" && contacts.elements[i].vrfStu === \"VERIFIED\") {phone = contacts.elements[i].value}} phone;"
}
}
],
"attrMapping": {
"fn": "{{.person.firstName}}",
"ln": "{{.person.lastName}}",
"mn": "{{.person.middleName}}",
"un": "",
"e": "{{.main_email}}",
"p": "{{.main_phone}}",
"l": "",
"xid": "",
"rid": "state",
"x": {
"snils": "{{.snils}}"
}
},
"isActive": true
}
Приложение Г. Список эндпоинтов ЕСИА Адаптер
| Эндпоинт | Описание |
|---|---|
/oauth2/authorize | Запрос аутентификации. |
/oauth2/token | Запрос токена. |
/oauth2/logout | Запрос выхода из системы. |
/oauth2/userinfo | Возврат JSON с информацией о пользователе, идентичный данным в id_token (используется для старых версий клиентов, подключаемых к ESIA Adapter). |
/extidp/esia | Запрос перенаправления в ЕСИА. |
/extidp/esia/callback | Обработка перенаправления от ЕСИА. |
/extidp/esia/logout | Запрос перенаправления в ЕСИА для выхода. |
/health/live | Проверка, что адаптер запущен и отвечает на запросы:
|
/health/ready | Проверка готовности адаптера к обработке запросов:
|



