Время на прочтение
6 мин
Количество просмотров 15K
Привет, Хабр! В одном из постов блога мой коллега Иван писал о нашем блокчейн-сервисе для онлайн-голосований WE.Vote. Он подробно разобрал, как работает WE.Vote с точки зрения технологий. Но чтобы сервисы удаленного голосования можно было использовать для принятия официальных решений юрлиц, не хватает еще одного важного компонента — достоверной верификации участников. В России для этого можно провести интеграцию с ЕСИА (Единой Системой Идентификации и Аутентификации) — проще говоря, с Госуслугами. Интеграция эта заметно отличается от интеграции с другими OAuth2-сервисами, как, например, Google или VK. В этом посте мы постараемся помочь тем, кто захочет интегрировать ЕСИА в свой сервис через стек, подобный нашему, а также дадим несколько полезных ссылок по ЕСИА в принципе.
Зачем нам ЕСИА?
Согласно Федеральному закону № 225-ФЗ от 28.06.2021 «О внесении изменений в часть первую Гражданского кодекса Российской Федерации», многие организаций в РФ получили право проводить официальные собрания и голосования по корпоративным вопросам дистанционно.
Ранее решения с юридической силой требовали очных собраний или голосований по почте. Голосования по почте не отличаются надежностью, а собрать много руководителей со всей России в одном месте — это кошмар с точки зрения затрат.
Чтобы проводить мероприятия принятия решения дистанционно в соответствии с новым федеральным законом, необходимо предоставить возможность достоверного установления личности участников. В России это возможно через проверку доступа к верифицированному аккаунту на Госуслугах.
Стек и схема интеграции
Для интеграции мы используем:
-
Typescript, ReactJS, NestJS
-
КриптоПро CSP 4
-
Docker, Kubernetes
Формирование подписи
Прежде чем разбирать все по порядку, кое о чем стоит подумать заранее. В отличие от других интеграций, запросы к ЕСИА должны сопровождаться подписью ГОСТ Р 34.10/11-2012, а не просто API key. Создать такую подпись можно с помощью утилиты КриптоПро CSP. Для нас основная задача здесь — правильно обернуть эту утилиту в Docker, чтобы с ней можно было работать как с отдельным сервисом в рамках нашей инфраструктуры. Получившийся сервис мы выложили в открытый доступ на гитхабе. Инструкция по запуску есть в README.md.
В процесс сборки Docker образа сервиса с утилитой КриптоПро мы встроили:
-
Установку утилиты КриптоПро СSP 4 из .deb пакета
-
Установку лицензии КриптоПро
-
Загрузку корневого сертификата тестовой или основной среды ЕСИА
-
Загрузку пользовательского сертификата с PIN кодом
-
REST-сервер с методом, позволяющим создавать подписи
Таким образом вся криптография собрана в отдельном самостоятельном компоненте, который можно использовать, когда необходимо что-нибудь подписать. Вот как это выглядит на бэкенде:
private async signParams(params: Record<string, string>) {
const time = moment().format('YYYY.MM.DD HH:mm:ss ZZ')
const state = uuid()
const clientId = this.clientId
const scope = this.scope
const { data: { result: clientSecret } } = await axios.post<{ result: string }>(
`${this.cryptoProServiceAddress}/cryptopro/sign`,
{ text: [scope, time, clientId, state].join('') },
)
return {
...params,
timestamp: time,
client_id: clientId,
scope,
state,
client_secret: clientSecret.replace(/n/g, ''),
}
}
С созданием подписей разобрались, теперь последовательно разберем, как реализовать схему выше.
Создание ссылки для редиректа на страницу ЕСИА
Все начинается с того, что пользователь решает пройти авторизацию через ЕСИА. Создаем на бэкенде ссылку для перехода с использованием нашего инструмента формирования подписей.
async getAuthLink(redirectLink: string) {
const params = await this.signParams({
redirect_uri: redirectLink,
response_type: 'code',
access_type: 'offline',
})
const authQuery = new URLSearchParams(params)
const authURL = `${this.esiaHost}/aas/oauth2/ac`
return `${authURL}?${authQuery}`
}
В redirectLink необходимо указать адрес страницы, на которую ЕСИА перенаправит пользователя после успешной аутентификации. Созданную ссылку возвращаем на фронтенд и перенаправляем на нее пользователя.
Получение авторизационного токена ЕСИА
Запрос токена идентификации
После успешной аутентификации на странице ЕСИА пользователь возвращается на фронтенд приложения по указанному нами адресу. ЕСИА передаёт авторизационный токен в виде get-параметра code. Этот токен необходимо передать на бэкенд и запросить с его помощью идентификационный токен пользователя.
async getTokens(code: string) {
try {
const params = await this.signParams({
grant_type: 'authorization_code',
token_type: 'Bearer',
redirect_uri: 'no',
code,
})
const authURL = `${this.host}/aas/oauth2/te`
const authQuery = new URLSearchParams(params)
const { data: tokens } = await axios.post(`${authURL}?${authQuery}`)
return {
idToken: tokens.id_token,
accessToken: tokens.access_token,
refreshToken: tokens.refresh_token,
}
} catch (e) {
const status = e.response ? e.response.status : 500
const message = e.response ? e.response.data.error_description : e.message
throw new HttpException('Failed to get auth tokens: ' + message, status)
}
}
Получение данных о пользователе
Идентификационный токен пользователя необходимо проверить с помощью публичного RSA ключа от ЕСИА и получить из него id пользователя. С помощью этого id и accessToken, который мы получили в предыдущем шаге, мы уже наконец можем запросить персональные данные пользователя.
getUserIdFromToken(idToken: string) {
const decodedIdToken = verify(idToken, this.esiaPublicKey, {
algorithms: ['RS256'],
audience: 'WE_VOTE',
}) as EsiaParsedToken
return decodedIdToken['urn:esia:sbj']['urn:esia:sbj:oid']
}
async getUserInfo(tokens: EsiaTokens) {
const { idToken, accessToken } = tokens
const oId = this.getUserIdFromToken(idToken)
const [{ data: mainInfo }, { data: contactsInfo }] = await Promise.all([
axios.get(`${this.esiaHost}/rs/prns/${oId}`, {
headers: {
Authorization: `Bearer ${accessToken}`,
},
}),
axios.get(`${this.esiaHost}/rs/prns/${oId}/ctts?embed=(elements)`, {
headers: {
Authorization: `Bearer ${accessToken}`,
},
}),
])
const email = contactsInfo.elements.find(({ type }: { type: string }) => type === 'EML')
return {
id: oId,
firstName: mainInfo.firstName,
lastName: mainInfo.lastName,
surName: mainInfo.middleName,
trusted: mainInfo.trusted,
email: email ? {
value: email.value.toLowerCase(),
verified: email.vrfStu === 'VERIFIED',
} : null,
}
}
На этом шаге мы уже имеем все необходимые данные о пользователе. Остается только занести их в свою систему и закончить авторизацию.
Полный код интеграционного модуля на бэкенде
import { HttpException } from '@nestjs/common'
import * as moment from 'moment'
import { v4 as uuid } from 'uuid'
import { URLSearchParams } from 'url'
import axios from 'axios'
import { verify } from 'jsonwebtoken'
type EsiaTokens = {
idToken: string,
accessToken: string,
}
type EsiaParsedToken = {
'urn:esia:sbj': {
'urn:esia:sbj:oid': string,
},
}
export class EsiaApiService {
private readonly clientId = 'WE_VOTE'
private readonly scope = ['openid', 'email', 'fullname'].join(' ')
constructor(
private readonly esiaHost: string, // 'https://esia-portal1.test.gosuslugi.ru' или 'https://esia.gosuslugi.ru'
private readonly esiaPublicKey: string, // можно взять из http://esia.gosuslugi.ru/public/esia.zip
private readonly cryptoProServiceAddress: string, // адрес сервиса по созданию подписей e.g 'http://127.0.0.1:3037'
) {
}
async getAuthLink(redirectLink: string) {
const params = await this.signParams({
redirect_uri: redirectLink,
response_type: 'code',
access_type: 'offline',
})
const authQuery = new URLSearchParams(params)
const authURL = `${this.esiaHost}/aas/oauth2/ac`
return `${authURL}?${authQuery}`
}
private async signParams(params: Record<string, string>) {
const time = moment().format('YYYY.MM.DD HH:mm:ss ZZ')
const state = uuid()
const clientId = this.clientId
const scope = this.scope
const { data: { result: clientSecret } } = await axios.post<{ result: string }>(
`${this.cryptoProServiceAddress}/cryptopro/sign`,
{ text: [scope, time, clientId, state].join('') },
)
return {
...params,
timestamp: time,
client_id: clientId,
scope,
state,
client_secret: clientSecret.replace(/n/g, ''),
}
}
async getTokens(code: string) {
try {
const params = await this.signParams({
grant_type: 'authorization_code',
token_type: 'Bearer',
redirect_uri: 'no',
code,
})
const authURL = `${this.esiaHost}/aas/oauth2/te`
const authQuery = new URLSearchParams(params)
const { data: tokens } = await axios.post(`${authURL}?${authQuery}`)
return {
idToken: tokens.id_token,
accessToken: tokens.access_token,
refreshToken: tokens.refresh_token,
}
} catch (e) {
const status = e.response ? e.response.status : 500
const message = e.response ? e.response.data.error_description : e.message
throw new HttpException('Failed to get auth tokens: ' + message, status)
}
}
getUserIdFromToken(idToken: string) {
const decodedIdToken = verify(idToken, this.esiaPublicKey, {
algorithms: ['RS256'],
audience: this.clientId,
}) as EsiaParsedToken
return decodedIdToken['urn:esia:sbj']['urn:esia:sbj:oid']
}
async getUserInfo(tokens: EsiaTokens) {
const { idToken, accessToken } = tokens
const oId = this.getUserIdFromToken(idToken)
const [{ data: mainInfo }, { data: contactsInfo }] = await Promise.all([
axios.get(`${this.esiaHost}/rs/prns/${oId}`, {
headers: {
Authorization: `Bearer ${accessToken}`,
},
}),
axios.get(`${this.esiaHost}/rs/prns/${oId}/ctts?embed=(elements)`, {
headers: {
Authorization: `Bearer ${accessToken}`,
},
}),
])
const email = contactsInfo.elements.find(({ type }: { type: string }) => type === 'EML')
return {
id: oId,
firstName: mainInfo.firstName,
lastName: mainInfo.lastName,
surName: mainInfo.middleName,
trusted: mainInfo.trusted,
email: email ? {
value: email.value.toLowerCase(),
verified: email.vrfStu === 'VERIFIED',
} : null,
}
}
}
Надеюсь, статья оказалась для вас полезной. Желаю, чтобы у вас все получилось без особых проблем!
Полезные материалы по теме
-
Наш сервис по созданию подписей с использованием КриптоПро
-
MVP-проект с Криптопро в докере
-
Методические указания по интеграции от ЕСИА
-
Инструкция по работе с тестовой средой ЕСИА
-
КриптоПро CSP
-
Интеграция на Java
-
Второй вариант интеграции на Java
-
Описание процесса OAuth2-интеграции
Данный документ описывает порядок регистрации портала записи пациента на прием к врачу, далее ИС (информационная система) в системе ЕСИА.
Применимо для регистрации других ИС с поправками на специфику.
Нормативные документы
- Руководство пользователя ЕСИА
https://digital.gov.ru/ru/documents/6182/ - Руководство пользователя технологического портала ЕСИА
https://digital.gov.ru/ru/documents/6190/ - Методические рекомендации по использованию ЕСИА
https://digital.gov.ru/ru/documents/6186/ - Регламент информационного взаимодействия Участников с Оператором ЕСИА и оператором эксплуатации инфраструктуры электронного правительства
https://digital.gov.ru/ru/documents/4244/
Ресурсы:
Технологический портал (ПРОМЫШЛЕННАЯ СРЕДА): http://esia.gosuslugi.ru/console/tech
Технологический портал (ТЕСТОВАЯ СРЕДА): https://esia-portal1.test.gosuslugi.ru/console/tech
1) Зарегистрируйте вашу организацию в ЕСИА
Необходимо получить квалифицированную электронную подпись (КЭП) на руководителя организации и зарегистрировать юридическое лицо или орган государственной власти в профиле ЕСИА (п.3 Руководства пользователя ЕСИА). Вам потребуется КЭП юридического лица (в т.ч. это может быть подпись ЭП-СП). За получением средства КЭП нужно обратиться в один из аккредитованных Минкомсвязью России удостоверяющих центров вашего региона.
!
Если у вашей организации уже есть доступ к ЕСИА сразу перейти к п.2
2) Зарегистрируйте информационную систему в ЕСИА
Ответственном сотруднику необходимо предоставить доступ к технологическому порталу (п. 3.5.2.3 Руководства пользователя). В результате регистрации через технологический портал ваша информационная система заносится в реестр ИС, взаимодействующих с ЕСИА. Для ИС присваивается буквенно-цифровой код — мнемоника.
Сотрудник должен быть привязан к организации!
3) Сертификаты ИС
В ЕСИА создан механизм аутентификации пользователей, основанный на спецификациях OAuth 2.0 и расширении OpenID Connect 1.0.
Необходимо сгенерировать закрытый ключ и сертификат открытого ключа, зарегистрировать его в технологическом портале.
Подробно необходимые действия описаны в разделе 3.1. Методических рекомендаций.
ВАЖНО
С ноября 2019 года подключение ИС в ЕСИА осуществляется только с сертификатами, поддерживащими алгоритмы шифрования ГОСТ-2012.
Портал записи на прием на данный момент работает только с ключами криптопровайдера КриптоПРО.
4) Подключитесь к тестовой среде ЕСИА
Необходимо отправить форму заявки на адрес sd@sc.minsvyaz.ru. Актуальная форма размещена в Регламенте взаимодействия — ПРИЛОЖЕНИЕ Е. ФОРМА ЗАЯВКИ НА СОГЛАСОВАНИЕ ПРАВА ИСПОЛЬЗОВАНИЯ ЕСИА И НА ПОДКЛЮЧЕНИЕ ИНФОРМАЦИОННОЙ СИСТЕМЫ К ЕСИА С ЦЕЛЬЮ ИСПОЛЬЗОВАНИЯ ПРОГРАММНЫХ ИНТЕРФЕЙСОВ ЕСИА ДЛЯ ИДЕНТИФИКАЦИИ И АУТЕНТИФИКАЦИИ ЗАЯВИТЕЛЕЙ
!
К заявке прилагаются файлы открытого (сертификата) и закрытого ключа в формате DER.
SCOPE
В заявке необходимо перечислить следующие SCOPE (типы запрашиваемых персональных данных гражданина)
Scope:
— openid
— fullname
— birthdate
— gender
— snils
— inn
— id_doc
— birthplace
— medical_doc
— drivers_licence_doc
— birth_cert_doc
— email
— mobile
— contacts
— usr_org
— kid_fullname
— kid_birthdate
— kid_gender
— kid_snils
— kid_inn
— kid_birth_cert_doc
— kid_medical_doc
Пример заполнения заявки:
После получения доступа в тестовую среду необходимо произвести настройку сервиса подписи на портале.
Для этого понадобится:
- сертификат в формате DER
- пароль от сертификата
- контейнер закрытых ключей
- лицензионный ключ КриптоПРО
Данные ключи необходимо передать ответственному сотруднику СТП. Или настроить сервис подписи самостоятельно.
После настройки и проверки тестовой среды можно переходить к регистрации в промышленной среде.
5) Подключитесь к промышленной среде ЕСИА
Необходимо отправить форму заявки на адрес sd@sc.minsvyaz.ru. Форма заявки как при подключении к тестовой среде.
Проверить наличие ИС на технологическом портале ПРОМЫШЛЕННОЙ СРЕДЫ, а так же наличие и актуальность прикрепленных там сертификатов.
После получения доступа в промышленную среду, необходимо настроить сервис подписи портала для подписи запросов в ЕСИА.
Для этого понадобится:
- сертификат в формате DER
- пароль от сертификата
- контейнер закрытых ключей
- лицензионный ключ КриптоПРО
Данные ключи необходимо передать ответственному сотруднику СТП. Или настроить сервис подписи самостоятельно.
Проверить работоспособность портала — авторизоваться на портале записи на прием под учетной записью реального гражданина.
6) Доменные имена
Согласно ФЗ №8 «ОБ ОБЕСПЕЧЕНИИ ДОСТУПА К ИНФОРМАЦИИ О ДЕЯТЕЛЬНОСТИ ГОСУДАРСТВЕННЫХ ОРГАНОВ И ОРГАНОВ МЕСТНОГО САМОУПРАВЛЕНИЯ» информационные ресурсы (сайты) принадлежащие государственным или муниципальным организациям должны располагаться на доменах принадлежащих этим организациям.
В связи с этим МИАЦ региона должен зарегистрировать доменное имя любого уровня для портала записи пациентов, а так же обеспечить доступ к сайту по защищенному протоколу HTTPS, для чего потребуется https сертификат.
Cертификаты SSL (HTTPS)
Текущие доменные имена вида код_региона.2dr.ru остаются в рабочем состоянии как резервные.
Единая система идентификации и авторизации (ЕСИА) – это единственный способ верифицировать личность пользователя. Если продукт работает с деньгами, решает юридические задачи или работает с медицинскими данными, без интеграции с ЕСИА не обойтись. Рассказываем, что нужно знать, чтобы работать с этой инфраструктурой.
ЕСИА появилась в 2010 году и изначально использовалась для авторизации на Портале госуслуг. За прошедшее время возможности системы постоянно развивались, и сегодня коммерческие организации используют её, чтобы связывать учётные записи пользователя с их оффлайн-личностью.
То есть если компании нужно удостовериться, что по ту сторону экрана действительно тот человек, которым представился пользователь, ЕСИА предоставляет такую возможность. И самое главное – эта идентификация имеет юридическую значимость.
Какие возможности открывает такая идентификация
1. Клиент может подписывать юридически значимые электронные документы, получать защищённый доступ к конфиденциальной информации, медицинским данным и т.д.
2. Появляется возможность автоматически заполнять в анкетах и заявках персональные данные клиента: ФИО, данные паспорта, ИНН, информация о детях и др. При этом компания может быть уверена, что эти данные абсолютно верны и правдивы.
3. Страховые компании и банки могут продавать через приложение свои продукты. И никаких расходов, которые связаны с традиционными, оффлайновыми каналами продаж – не нужно собирать документы, приглашать человека в офис, достаточно разработать скрипт для колл-центра.
4. Для пользователя верификация с ЕСИА повышает доверие к сервису и делает саму процедуру удобнее – не нужно помнить дополнительные пароли, просто нажимаешь знакомую кнопку и всё.
В наших проектах интеграция ЕСИА активно используется в продуктах страховых компаний. Это позволяет клиентам покупать полисы ОСАГО, отправлять извещения о ДТП при оформлении заявок на урегулирование убытков. Это критически важная функция для сценариев заявления о страховых случаях по ОСАГО, когда пользователь не является клиентом данной страховой компании.
Хотя сейчас к ЕСИА могут подключиться не все организации, можно ожидать, что такая авторизация скоро станет де-факто стандартом для пользовательских сервисов. Просто потому, что это надёжно и удобно для клиентов – вместо отдельной учётной записи для каждого ресурса можно использовать единый аккаунт «Госуслуг» и бесшовно пользоваться любыми нужными услугами. Поэтому задумываться об интеграции стоит всем компаниям.
Как информационная система работает с ЕСИА
ЕСИА является прослойкой между стандартным содержанием приложения и его защищёнными данными. Если пользователю не требуются услуги, которые требуют верификации личности, он может не проходить дополнительную авторизацию. Когда же он захочет попасть в этот раздел, приложение переадресует его на Портал госуслуг, а после успешной авторизации – вернёт обратно.
Технически процесс выглядит так:
1. Пользователь обращается к защищённому ресурсу информационной системы (например, при онлайн-покупке полиса ОСАГО).
2. Информационная система направляет в ЕСИА запрос на аутентификацию.
3. ЕСИА проверяет, есть ли у пользователя открытая сессия, т.е. авторизовался ли он уже ранее. Если такой сессии нет, ЕСИА направляет пользователя на веб-страницу, чтобы он ввёл свой логин и пароль.
4. После успешной аутентификации ЕСИА передаёт в информационную систему пакет с идентификационными данными пользователя, информацию об уровне его учётной записи и контексте аутентификации.
5. На основании этой информации система открывает пользователю доступ.
Как организации подключиться к ЕСИА
Процедура подключения занимает около месяца. Это время включает регистрацию необходимых аккаунтов, получение данных от Минцифры, работы по интеграции ИС.
1. Зарегистрируйте руководителя организации на Портале госуслуг. Регистрировать компании в ЕСИА могут только те их представители, которые вправе действовать без доверенности. Им понадобится подтверждённая учётная запись физического лица – т.е. нужно будет не только указать свои данные, но и обратиться в банк или МФЦ для верификации. В последнее время многие банки позволяют сделать это онлайн, через их приложения.
2. Зарегистрируйте вашу организацию.
a. Получите квалифицированную электронную подпись (КЭП) на руководителя организации.
b. Зарегистрируйте юридическое лицо в профиле ЕСИА.
c. Оформите КЭП для юридического лица.
Оформлением КЭП занимаются аккредитованные удостоверяющие центры. Подробная инструкция по этому процессу здесь.
3. Зарегистрируйте информационную систему в ЕСИА.
Регистрация системы происходит через технологический портал. Доступ к нему может получить один из сотрудников компании – действовать через аккаунт представителя уже не обязательно. Этот процесс подробно расписан в Руководстве пользователя технологического портала ЕСИА. В результате регистрации информационная система заносится в реестр ИС и получает мнемонический буквенно-цифровой код.
4. Доработайте систему для обмена данными с ЕСИА.
Аутентификация пользователей в ЕСИА происходит по OAuth 2.0 и OpenID Connect 1.0. Компании необходимо сгенерировать закрытый ключ и сертификат открытого ключа, зарегистрировать его на технологическом портале. Стоит отметить, что ЕСИА поддерживает только российские алгоритмы шифрования ГОСТ Р 34.10-2012 и ГОСТ Р 34.11-2012.
Стоит отдельно отметить, что если в компании уже используются средства верификации пользователей посредством Single Sign-On, то особых технических трудностей при подключении к ЕСИА не будет.
5. Подключитесь к тестовой среде ЕСИА
На этом этапе нужно отправить на адрес [email protected] заявку по форме, которая приводится в Регламенте взаимодействия заявителей с операторами ЕСИА. Когда администраторы откроют доступ, компании нужно подключить свою систему к ЕСИА, чтобы она могла принимать и отправлять запросы. Для этого используются специальные коннекторы, и Минцифры не даст разрешение на полноценный запуск, пока коннекторы не заработают стабильно в тестовом режиме.
6. Подключитесь к промышленной среде ЕСИА
Когда всё готово, вы отправляете ещё одну заявку на [email protected]. Остаётся проверить работоспособности интеграции – и готово.
Полезные ссылки
Ludmila Tihonova |
|
Статус: Advanced Member Группы: Registered Сказал(а) «Спасибо»: 41 раз |
Начинается поэтапное тестирование функционала суперсервиса с использованием тестового ЕПГУ (тестовый кабинет госуслуг). Презентация для вузов: Для тестирования необходимо выполнить следующие условия: 1. Убедиться в наличии подключения к Сервису приема. 7. Функционал тестированию на данном этапе: 8. Цель проведения тестирования: проверка полноты и корректности отображения данных, внесённых в тестовый Сервис приёма. |
|
|
Пользователи, просматривающие эту тему |
Гость |
Быстрый переход
Вы не можете создавать новые темы в этом форуме.
Вы не можете отвечать в этом форуме.
Вы не можете удалять Ваши сообщения в этом форуме.
Вы не можете редактировать Ваши сообщения в этом форуме.
Вы не можете создавать опросы в этом форуме.
Вы не можете голосовать в этом форуме.
Время на прочтение
6 мин
Количество просмотров 12K
Привет, Хабр! В одном из постов блога мой коллега Иван писал о нашем блокчейн-сервисе для онлайн-голосований WE.Vote. Он подробно разобрал, как работает WE.Vote с точки зрения технологий. Но чтобы сервисы удаленного голосования можно было использовать для принятия официальных решений юрлиц, не хватает еще одного важного компонента — достоверной верификации участников. В России для этого можно провести интеграцию с ЕСИА (Единой Системой Идентификации и Аутентификации) — проще говоря, с Госуслугами. Интеграция эта заметно отличается от интеграции с другими OAuth2-сервисами, как, например, Google или VK. В этом посте мы постараемся помочь тем, кто захочет интегрировать ЕСИА в свой сервис через стек, подобный нашему, а также дадим несколько полезных ссылок по ЕСИА в принципе.
Зачем нам ЕСИА?
Согласно Федеральному закону № 225-ФЗ от 28.06.2021 «О внесении изменений в часть первую Гражданского кодекса Российской Федерации», многие организаций в РФ получили право проводить официальные собрания и голосования по корпоративным вопросам дистанционно.
Ранее решения с юридической силой требовали очных собраний или голосований по почте. Голосования по почте не отличаются надежностью, а собрать много руководителей со всей России в одном месте — это кошмар с точки зрения затрат.
Чтобы проводить мероприятия принятия решения дистанционно в соответствии с новым федеральным законом, необходимо предоставить возможность достоверного установления личности участников. В России это возможно через проверку доступа к верифицированному аккаунту на Госуслугах.
Стек и схема интеграции
Для интеграции мы используем:
-
Typescript, ReactJS, NestJS
-
КриптоПро CSP 4
-
Docker, Kubernetes
Формирование подписи
Прежде чем разбирать все по порядку, кое о чем стоит подумать заранее. В отличие от других интеграций, запросы к ЕСИА должны сопровождаться подписью ГОСТ Р 34.10/11-2012, а не просто API key. Создать такую подпись можно с помощью утилиты КриптоПро CSP. Для нас основная задача здесь — правильно обернуть эту утилиту в Docker, чтобы с ней можно было работать как с отдельным сервисом в рамках нашей инфраструктуры. Получившийся сервис мы выложили в открытый доступ на гитхабе. Инструкция по запуску есть в README.md.
В процесс сборки Docker образа сервиса с утилитой КриптоПро мы встроили:
-
Установку утилиты КриптоПро СSP 4 из .deb пакета
-
Установку лицензии КриптоПро
-
Загрузку корневого сертификата тестовой или основной среды ЕСИА
-
Загрузку пользовательского сертификата с PIN кодом
-
REST-сервер с методом, позволяющим создавать подписи
Таким образом вся криптография собрана в отдельном самостоятельном компоненте, который можно использовать, когда необходимо что-нибудь подписать. Вот как это выглядит на бэкенде:
private async signParams(params: Record<string, string>) {
const time = moment().format('YYYY.MM.DD HH:mm:ss ZZ')
const state = uuid()
const clientId = this.clientId
const scope = this.scope
const { data: { result: clientSecret } } = await axios.post<{ result: string }>(
`${this.cryptoProServiceAddress}/cryptopro/sign`,
{ text: [scope, time, clientId, state].join('') },
)
return {
...params,
timestamp: time,
client_id: clientId,
scope,
state,
client_secret: clientSecret.replace(/n/g, ''),
}
}
С созданием подписей разобрались, теперь последовательно разберем, как реализовать схему выше.
Создание ссылки для редиректа на страницу ЕСИА
Все начинается с того, что пользователь решает пройти авторизацию через ЕСИА. Создаем на бэкенде ссылку для перехода с использованием нашего инструмента формирования подписей.
async getAuthLink(redirectLink: string) {
const params = await this.signParams({
redirect_uri: redirectLink,
response_type: 'code',
access_type: 'offline',
})
const authQuery = new URLSearchParams(params)
const authURL = `${this.esiaHost}/aas/oauth2/ac`
return `${authURL}?${authQuery}`
}
В redirectLink необходимо указать адрес страницы, на которую ЕСИА перенаправит пользователя после успешной аутентификации. Созданную ссылку возвращаем на фронтенд и перенаправляем на нее пользователя.
Получение авторизационного токена ЕСИА
Запрос токена идентификации
После успешной аутентификации на странице ЕСИА пользователь возвращается на фронтенд приложения по указанному нами адресу. ЕСИА передаёт авторизационный токен в виде get-параметра code. Этот токен необходимо передать на бэкенд и запросить с его помощью идентификационный токен пользователя.
async getTokens(code: string) {
try {
const params = await this.signParams({
grant_type: 'authorization_code',
token_type: 'Bearer',
redirect_uri: 'no',
code,
})
const authURL = `${this.host}/aas/oauth2/te`
const authQuery = new URLSearchParams(params)
const { data: tokens } = await axios.post(`${authURL}?${authQuery}`)
return {
idToken: tokens.id_token,
accessToken: tokens.access_token,
refreshToken: tokens.refresh_token,
}
} catch (e) {
const status = e.response ? e.response.status : 500
const message = e.response ? e.response.data.error_description : e.message
throw new HttpException('Failed to get auth tokens: ' + message, status)
}
}
Получение данных о пользователе
Идентификационный токен пользователя необходимо проверить с помощью публичного RSA ключа от ЕСИА и получить из него id пользователя. С помощью этого id и accessToken, который мы получили в предыдущем шаге, мы уже наконец можем запросить персональные данные пользователя.
getUserIdFromToken(idToken: string) {
const decodedIdToken = verify(idToken, this.esiaPublicKey, {
algorithms: ['RS256'],
audience: 'WE_VOTE',
}) as EsiaParsedToken
return decodedIdToken['urn:esia:sbj']['urn:esia:sbj:oid']
}
async getUserInfo(tokens: EsiaTokens) {
const { idToken, accessToken } = tokens
const oId = this.getUserIdFromToken(idToken)
const [{ data: mainInfo }, { data: contactsInfo }] = await Promise.all([
axios.get(`${this.esiaHost}/rs/prns/${oId}`, {
headers: {
Authorization: `Bearer ${accessToken}`,
},
}),
axios.get(`${this.esiaHost}/rs/prns/${oId}/ctts?embed=(elements)`, {
headers: {
Authorization: `Bearer ${accessToken}`,
},
}),
])
const email = contactsInfo.elements.find(({ type }: { type: string }) => type === 'EML')
return {
id: oId,
firstName: mainInfo.firstName,
lastName: mainInfo.lastName,
surName: mainInfo.middleName,
trusted: mainInfo.trusted,
email: email ? {
value: email.value.toLowerCase(),
verified: email.vrfStu === 'VERIFIED',
} : null,
}
}
На этом шаге мы уже имеем все необходимые данные о пользователе. Остается только занести их в свою систему и закончить авторизацию.
Полный код интеграционного модуля на бэкенде
import { HttpException } from '@nestjs/common'
import * as moment from 'moment'
import { v4 as uuid } from 'uuid'
import { URLSearchParams } from 'url'
import axios from 'axios'
import { verify } from 'jsonwebtoken'
type EsiaTokens = {
idToken: string,
accessToken: string,
}
type EsiaParsedToken = {
'urn:esia:sbj': {
'urn:esia:sbj:oid': string,
},
}
export class EsiaApiService {
private readonly clientId = 'WE_VOTE'
private readonly scope = ['openid', 'email', 'fullname'].join(' ')
constructor(
private readonly esiaHost: string, // 'https://esia-portal1.test.gosuslugi.ru' или 'https://esia.gosuslugi.ru'
private readonly esiaPublicKey: string, // можно взять из http://esia.gosuslugi.ru/public/esia.zip
private readonly cryptoProServiceAddress: string, // адрес сервиса по созданию подписей e.g 'http://127.0.0.1:3037'
) {
}
async getAuthLink(redirectLink: string) {
const params = await this.signParams({
redirect_uri: redirectLink,
response_type: 'code',
access_type: 'offline',
})
const authQuery = new URLSearchParams(params)
const authURL = `${this.esiaHost}/aas/oauth2/ac`
return `${authURL}?${authQuery}`
}
private async signParams(params: Record<string, string>) {
const time = moment().format('YYYY.MM.DD HH:mm:ss ZZ')
const state = uuid()
const clientId = this.clientId
const scope = this.scope
const { data: { result: clientSecret } } = await axios.post<{ result: string }>(
`${this.cryptoProServiceAddress}/cryptopro/sign`,
{ text: [scope, time, clientId, state].join('') },
)
return {
...params,
timestamp: time,
client_id: clientId,
scope,
state,
client_secret: clientSecret.replace(/n/g, ''),
}
}
async getTokens(code: string) {
try {
const params = await this.signParams({
grant_type: 'authorization_code',
token_type: 'Bearer',
redirect_uri: 'no',
code,
})
const authURL = `${this.esiaHost}/aas/oauth2/te`
const authQuery = new URLSearchParams(params)
const { data: tokens } = await axios.post(`${authURL}?${authQuery}`)
return {
idToken: tokens.id_token,
accessToken: tokens.access_token,
refreshToken: tokens.refresh_token,
}
} catch (e) {
const status = e.response ? e.response.status : 500
const message = e.response ? e.response.data.error_description : e.message
throw new HttpException('Failed to get auth tokens: ' + message, status)
}
}
getUserIdFromToken(idToken: string) {
const decodedIdToken = verify(idToken, this.esiaPublicKey, {
algorithms: ['RS256'],
audience: this.clientId,
}) as EsiaParsedToken
return decodedIdToken['urn:esia:sbj']['urn:esia:sbj:oid']
}
async getUserInfo(tokens: EsiaTokens) {
const { idToken, accessToken } = tokens
const oId = this.getUserIdFromToken(idToken)
const [{ data: mainInfo }, { data: contactsInfo }] = await Promise.all([
axios.get(`${this.esiaHost}/rs/prns/${oId}`, {
headers: {
Authorization: `Bearer ${accessToken}`,
},
}),
axios.get(`${this.esiaHost}/rs/prns/${oId}/ctts?embed=(elements)`, {
headers: {
Authorization: `Bearer ${accessToken}`,
},
}),
])
const email = contactsInfo.elements.find(({ type }: { type: string }) => type === 'EML')
return {
id: oId,
firstName: mainInfo.firstName,
lastName: mainInfo.lastName,
surName: mainInfo.middleName,
trusted: mainInfo.trusted,
email: email ? {
value: email.value.toLowerCase(),
verified: email.vrfStu === 'VERIFIED',
} : null,
}
}
}
Надеюсь, статья оказалась для вас полезной. Желаю, чтобы у вас все получилось без особых проблем!
Полезные материалы по теме
-
Наш сервис по созданию подписей с использованием КриптоПро
-
MVP-проект с Криптопро в докере
-
Методические указания по интеграции от ЕСИА
-
Инструкция по работе с тестовой средой ЕСИА
-
КриптоПро CSP
-
Интеграция на Java
-
Второй вариант интеграции на Java
-
Описание процесса OAuth2-интеграции
Единая система идентификации и авторизации (ЕСИА) – это единственный способ верифицировать личность пользователя. Если продукт работает с деньгами, решает юридические задачи или работает с медицинскими данными, без интеграции с ЕСИА не обойтись. Рассказываем, что нужно знать, чтобы работать с этой инфраструктурой.
ЕСИА появилась в 2010 году и изначально использовалась для авторизации на Портале госуслуг. За прошедшее время возможности системы постоянно развивались, и сегодня коммерческие организации используют её, чтобы связывать учётные записи пользователя с их оффлайн-личностью.
То есть если компании нужно удостовериться, что по ту сторону экрана действительно тот человек, которым представился пользователь, ЕСИА предоставляет такую возможность. И самое главное – эта идентификация имеет юридическую значимость.
Какие возможности открывает такая идентификация
1. Клиент может подписывать юридически значимые электронные документы, получать защищённый доступ к конфиденциальной информации, медицинским данным и т.д.
2. Появляется возможность автоматически заполнять в анкетах и заявках персональные данные клиента: ФИО, данные паспорта, ИНН, информация о детях и др. При этом компания может быть уверена, что эти данные абсолютно верны и правдивы.
3. Страховые компании и банки могут продавать через приложение свои продукты. И никаких расходов, которые связаны с традиционными, оффлайновыми каналами продаж – не нужно собирать документы, приглашать человека в офис, достаточно разработать скрипт для колл-центра.
4. Для пользователя верификация с ЕСИА повышает доверие к сервису и делает саму процедуру удобнее – не нужно помнить дополнительные пароли, просто нажимаешь знакомую кнопку и всё.
В наших проектах интеграция ЕСИА активно используется в продуктах страховых компаний. Это позволяет клиентам покупать полисы ОСАГО, отправлять извещения о ДТП при оформлении заявок на урегулирование убытков. Это критически важная функция для сценариев заявления о страховых случаях по ОСАГО, когда пользователь не является клиентом данной страховой компании.
Хотя сейчас к ЕСИА могут подключиться не все организации, можно ожидать, что такая авторизация скоро станет де-факто стандартом для пользовательских сервисов. Просто потому, что это надёжно и удобно для клиентов – вместо отдельной учётной записи для каждого ресурса можно использовать единый аккаунт «Госуслуг» и бесшовно пользоваться любыми нужными услугами. Поэтому задумываться об интеграции стоит всем компаниям.
Как информационная система работает с ЕСИА
ЕСИА является прослойкой между стандартным содержанием приложения и его защищёнными данными. Если пользователю не требуются услуги, которые требуют верификации личности, он может не проходить дополнительную авторизацию. Когда же он захочет попасть в этот раздел, приложение переадресует его на Портал госуслуг, а после успешной авторизации – вернёт обратно.
Технически процесс выглядит так:
1. Пользователь обращается к защищённому ресурсу информационной системы (например, при онлайн-покупке полиса ОСАГО).
2. Информационная система направляет в ЕСИА запрос на аутентификацию.
3. ЕСИА проверяет, есть ли у пользователя открытая сессия, т.е. авторизовался ли он уже ранее. Если такой сессии нет, ЕСИА направляет пользователя на веб-страницу, чтобы он ввёл свой логин и пароль.
4. После успешной аутентификации ЕСИА передаёт в информационную систему пакет с идентификационными данными пользователя, информацию об уровне его учётной записи и контексте аутентификации.
5. На основании этой информации система открывает пользователю доступ.
Как организации подключиться к ЕСИА
Процедура подключения занимает около месяца. Это время включает регистрацию необходимых аккаунтов, получение данных от Минцифры, работы по интеграции ИС.
1. Зарегистрируйте руководителя организации на Портале госуслуг. Регистрировать компании в ЕСИА могут только те их представители, которые вправе действовать без доверенности. Им понадобится подтверждённая учётная запись физического лица – т.е. нужно будет не только указать свои данные, но и обратиться в банк или МФЦ для верификации. В последнее время многие банки позволяют сделать это онлайн, через их приложения.
2. Зарегистрируйте вашу организацию.
a. Получите квалифицированную электронную подпись (КЭП) на руководителя организации.
b. Зарегистрируйте юридическое лицо в профиле ЕСИА.
c. Оформите КЭП для юридического лица.
Оформлением КЭП занимаются аккредитованные удостоверяющие центры. Подробная инструкция по этому процессу здесь.
3. Зарегистрируйте информационную систему в ЕСИА.
Регистрация системы происходит через технологический портал. Доступ к нему может получить один из сотрудников компании – действовать через аккаунт представителя уже не обязательно. Этот процесс подробно расписан в Руководстве пользователя технологического портала ЕСИА. В результате регистрации информационная система заносится в реестр ИС и получает мнемонический буквенно-цифровой код.
4. Доработайте систему для обмена данными с ЕСИА.
Аутентификация пользователей в ЕСИА происходит по OAuth 2.0 и OpenID Connect 1.0. Компании необходимо сгенерировать закрытый ключ и сертификат открытого ключа, зарегистрировать его на технологическом портале. Стоит отметить, что ЕСИА поддерживает только российские алгоритмы шифрования ГОСТ Р 34.10-2012 и ГОСТ Р 34.11-2012.
Стоит отдельно отметить, что если в компании уже используются средства верификации пользователей посредством Single Sign-On, то особых технических трудностей при подключении к ЕСИА не будет.
5. Подключитесь к тестовой среде ЕСИА
На этом этапе нужно отправить на адрес [email protected] заявку по форме, которая приводится в Регламенте взаимодействия заявителей с операторами ЕСИА. Когда администраторы откроют доступ, компании нужно подключить свою систему к ЕСИА, чтобы она могла принимать и отправлять запросы. Для этого используются специальные коннекторы, и Минцифры не даст разрешение на полноценный запуск, пока коннекторы не заработают стабильно в тестовом режиме.
6. Подключитесь к промышленной среде ЕСИА
Когда всё готово, вы отправляете ещё одну заявку на [email protected]. Остаётся проверить работоспособности интеграции – и готово.
Полезные ссылки
Данный документ описывает порядок регистрации портала записи пациента на прием к врачу, далее ИС (информационная система) в системе ЕСИА.
Применимо для регистрации других ИС с поправками на специфику.
Нормативные документы
- Руководство пользователя ЕСИА
https://digital.gov.ru/ru/documents/6182/ - Руководство пользователя технологического портала ЕСИА
https://digital.gov.ru/ru/documents/6190/ - Методические рекомендации по использованию ЕСИА
https://digital.gov.ru/ru/documents/6186/ - Регламент информационного взаимодействия Участников с Оператором ЕСИА и оператором эксплуатации инфраструктуры электронного правительства
https://digital.gov.ru/ru/documents/4244/
Ресурсы:
Технологический портал (ПРОМЫШЛЕННАЯ СРЕДА): http://esia.gosuslugi.ru/console/tech
Технологический портал (ТЕСТОВАЯ СРЕДА): https://esia-portal1.test.gosuslugi.ru/console/tech
1) Зарегистрируйте вашу организацию в ЕСИА
Необходимо получить квалифицированную электронную подпись (КЭП) на руководителя организации и зарегистрировать юридическое лицо или орган государственной власти в профиле ЕСИА (п.3 Руководства пользователя ЕСИА). Вам потребуется КЭП юридического лица (в т.ч. это может быть подпись ЭП-СП). За получением средства КЭП нужно обратиться в один из аккредитованных Минкомсвязью России удостоверяющих центров вашего региона.
!
Если у вашей организации уже есть доступ к ЕСИА сразу перейти к п.2
2) Зарегистрируйте информационную систему в ЕСИА
Ответственном сотруднику необходимо предоставить доступ к технологическому порталу (п. 3.5.2.3 Руководства пользователя). В результате регистрации через технологический портал ваша информационная система заносится в реестр ИС, взаимодействующих с ЕСИА. Для ИС присваивается буквенно-цифровой код — мнемоника.
Сотрудник должен быть привязан к организации!
3) Сертификаты ИС
В ЕСИА создан механизм аутентификации пользователей, основанный на спецификациях OAuth 2.0 и расширении OpenID Connect 1.0.
Необходимо сгенерировать закрытый ключ и сертификат открытого ключа, зарегистрировать его в технологическом портале.
Подробно необходимые действия описаны в разделе 3.1. Методических рекомендаций.
ВАЖНО
С ноября 2019 года подключение ИС в ЕСИА осуществляется только с сертификатами, поддерживащими алгоритмы шифрования ГОСТ-2012.
Портал записи на прием на данный момент работает только с ключами криптопровайдера КриптоПРО.
4) Подключитесь к тестовой среде ЕСИА
Необходимо отправить форму заявки на адрес sd@sc.minsvyaz.ru. Актуальная форма размещена в Регламенте взаимодействия — ПРИЛОЖЕНИЕ Е. ФОРМА ЗАЯВКИ НА СОГЛАСОВАНИЕ ПРАВА ИСПОЛЬЗОВАНИЯ ЕСИА И НА ПОДКЛЮЧЕНИЕ ИНФОРМАЦИОННОЙ СИСТЕМЫ К ЕСИА С ЦЕЛЬЮ ИСПОЛЬЗОВАНИЯ ПРОГРАММНЫХ ИНТЕРФЕЙСОВ ЕСИА ДЛЯ ИДЕНТИФИКАЦИИ И АУТЕНТИФИКАЦИИ ЗАЯВИТЕЛЕЙ
!
К заявке прилагаются файлы открытого (сертификата) и закрытого ключа в формате DER.
SCOPE
В заявке необходимо перечислить следующие SCOPE (типы запрашиваемых персональных данных гражданина)
Scope:
— openid
— fullname
— birthdate
— gender
— snils
— inn
— id_doc
— birthplace
— medical_doc
— drivers_licence_doc
— birth_cert_doc
— email
— mobile
— contacts
— usr_org
— kid_fullname
— kid_birthdate
— kid_gender
— kid_snils
— kid_inn
— kid_birth_cert_doc
— kid_medical_doc
Пример заполнения заявки:
После получения доступа в тестовую среду необходимо произвести настройку сервиса подписи на портале.
Для этого понадобится:
- сертификат в формате DER
- пароль от сертификата
- контейнер закрытых ключей
- лицензионный ключ КриптоПРО
Данные ключи необходимо передать ответственному сотруднику СТП. Или настроить сервис подписи самостоятельно.
После настройки и проверки тестовой среды можно переходить к регистрации в промышленной среде.
5) Подключитесь к промышленной среде ЕСИА
Необходимо отправить форму заявки на адрес sd@sc.minsvyaz.ru. Форма заявки как при подключении к тестовой среде.
Проверить наличие ИС на технологическом портале ПРОМЫШЛЕННОЙ СРЕДЫ, а так же наличие и актуальность прикрепленных там сертификатов.
После получения доступа в промышленную среду, необходимо настроить сервис подписи портала для подписи запросов в ЕСИА.
Для этого понадобится:
- сертификат в формате DER
- пароль от сертификата
- контейнер закрытых ключей
- лицензионный ключ КриптоПРО
Данные ключи необходимо передать ответственному сотруднику СТП. Или настроить сервис подписи самостоятельно.
Проверить работоспособность портала — авторизоваться на портале записи на прием под учетной записью реального гражданина.
6) Доменные имена
Согласно ФЗ №8 «ОБ ОБЕСПЕЧЕНИИ ДОСТУПА К ИНФОРМАЦИИ О ДЕЯТЕЛЬНОСТИ ГОСУДАРСТВЕННЫХ ОРГАНОВ И ОРГАНОВ МЕСТНОГО САМОУПРАВЛЕНИЯ» информационные ресурсы (сайты) принадлежащие государственным или муниципальным организациям должны располагаться на доменах принадлежащих этим организациям.
В связи с этим МИАЦ региона должен зарегистрировать доменное имя любого уровня для портала записи пациентов, а так же обеспечить доступ к сайту по защищенному протоколу HTTPS, для чего потребуется https сертификат.
Cертификаты SSL (HTTPS)
Текущие доменные имена вида код_региона.2dr.ru остаются в рабочем состоянии как резервные.
Ludmila Tihonova |
|
Статус: Advanced Member Группы: Registered
Зарегистрирован: 29.07.2018(UTC) Сказал(а) «Спасибо»: 41 раз |
Начинается поэтапное тестирование функционала суперсервиса с использованием тестового ЕПГУ (тестовый кабинет госуслуг). Презентация для вузов: Для тестирования необходимо выполнить следующие условия: 1. Убедиться в наличии подключения к Сервису приема. 7. Функционал тестированию на данном этапе: 8. Цель проведения тестирования: проверка полноты и корректности отображения данных, внесённых в тестовый Сервис приёма. |
|
|
Пользователи, просматривающие эту тему |
Гость |
Быстрый переход
Вы не можете создавать новые темы в этом форуме.
Вы не можете отвечать в этом форуме.
Вы не можете удалять Ваши сообщения в этом форуме.
Вы не можете редактировать Ваши сообщения в этом форуме.
Вы не можете создавать опросы в этом форуме.
Вы не можете голосовать в этом форуме.
Как и обещал
Предварительные условия
Для работы требуется наличие публичного и приватного ключа в соответствии с методическими рекомендациями по работе с ЕСИА. Допускается использование самоподписного сертифката, который можно сгенерировать следующей командой:
openssl req -x509 -nodes -days 3650 -newkey rsa:2048 -sha1 -keyout my_private.key -out my_public_cert.crt
Полученный в результате файл my_public_cert.crt должен быть привязан к информационной системе вашей организации на сайте Госуслуг, а также направлен вместе с заявкой на доступ к ЕСИА (подробнее см. документы http://minsvyaz.ru/ru/documents/?words=ЕСИА).
Для валидации ответов от ЕСИА потребуется публичный ключ, который можно запросить в технической поддержке ЕСИА, уже после регистрации информационной системы и получения доступа к тестовой среде ЕСИА. Валидация опциональна.