http://habrahabr.ru/post/271827/
Все началось с того, что Минкомсвязи разрешило использовать портал госуслуг для идентификации и аутентификации пользователей на негосударственных веб-узлах. Это реализуется с помощью службы ЕСИА (Единая Система Идентификации и Аутентификации —
esia.gosuslugi.ru). Заказчик нашего проекта входил в число первых 5 участников, которые подали заявки на интеграцию с ЕСИА, что выразилось для нас задачей эту интеграцию поддержать.
В свободном доступе мы не нашли открытого бесплатного решения подходящего для своего стека технологий, поэтому после разработки, с благословления заказчика, решили поделиться собственным (BSD license).
Итак, представляем вам проект esia-connector, написан на Python 3, использует утилиту openssl, проверялся в работе только в Debian-based системах.
Пакет:
pypi.python.org/pypi/esia-connector
Проект:
github.com/saprun/esia-connector
Что такое ЕСИА, какие она возможности предоставляет рассказывать не стану, только о возможностях текущей реализации нашей библиотеки.
esia-connector позволяет:
- аутентифицироваться в ЕСИА, получить в ответ токен (который затем можно использовать для идентификации пользователя), проверить его;
- получить личные данные пользователя: ФИО, данные удостоверяющих личность документов (паспорта, водительские права), контактные данные (номера телефонов, адрес электронной почты), ИНН, СНИЛС, адреса (проживания и регистрации).
Использование
Для того, чтобы подключиться к ЕСИА с помощью библиотеки вам нужно иметь на руках:
- Сертификат, выданный, либо самоподписанный в формате описанном в методических рекомендациях, загруженный на тестовый и боевой сервер ЕСИА.
Выдержка из методических рекомендацийВыпустить ключевой контейнер и сертификат ключа квалифицированной электронной подписи для подключаемой информационной системы (должен содержать ОГРН ЮЛ, являющегося оператором информационной системы). Дополнительно поддерживается работа с ключевым контейнером и сертификатом ключа неквалифицированной электронной подписи в формате X.509 версии 3. В этом случае является допустимым самостоятельно сгенерировать (например, с помощью утилиты keytool из состава Java Development Kit) для своей системы ключевой контейнер и самоподписанный сертификат. Сертификат требуется для идентификации ИС при взаимодействии с ЕСИА. ЕСИА поддерживает алгоритмы формирования электронной подписи RSA с длиной ключа 2048 бит и алгоритмом криптографического хэширования SHA-256, а также алгоритм электронной подписи ГОСТ Р 34.10-2001 и алгоритм криптографического хэширования ГОСТ Р 34.11-94.
- Выданную службой поддержки ЕСИА учетную запись компании на боевом и тестовом серверах. Она, затем, должна быть указана при создании объекта EsiaSettings вместо строки “YOUR_SYSTEM_ID”.
- Учетные записи пользователей на тестовом и боевом серверах ЕСИА для отладки и тестирования.
- Публичные ключи ЕСИА (тестовый и боевой) для верификации полученного токена. В открытом доступе этих ключей нет, техподдержка высылает их электронной почтой по требованию.
Чтобы запустить тестовый пример (минимальное веб-приложение на Flask доступно в репозитории библиотеки) нужно
предварительно загруженный на сервер ЕСИА сертификат разместить в файле “esia-connector/examples/res/test.crt”. В этом же каталоге следует разместить ваш приватный ключ под именем “test.key”, а упомянутый выше публичный ключ разместить под именем “esia_pub.key”.
Затем запустить приложение Flask, из каталога examples выполнить:
python flask_app.py
На главной странице мы увидим правильно сформированную ссылку для обращения к ЕСИА, при переходе по ней сервер ЕСИА обработает данные в GET-запросе, запросит у пользователя логин и пароль к ЕСИА, затем после удачного введения запросит разрешение на доступ нашего приложения к ЕСИА и, в случае выдачи разрешения, редиректит на заданную в тестовом примере страницу, где мы с уже полученным токеном сделаем еще пару запросов на получение персональных данных пользователя от лица которого производим запрос, и отобразим эти данные на этой же странице.
Пример использования esia-connectorimport os
from flask import Flask, request
from esia_connector.client import EsiaSettings, EsiaAuth
def get_test_file(name):
return os.path.join(os.path.dirname(__file__), 'res', name)
TEST_SETTINGS = EsiaSettings(esia_client_id='YOUR SYSTEM ID',
redirect_uri='http://localhost:5000/info',
certificate_file=get_test_file('test.crt'),
private_key_file=get_test_file('test.key'),
esia_token_check_key=get_test_file('esia_pub.key'),
esia_service_url='https://esia-portal1.test.gosuslugi.ru',
esia_scope='openid http://esia.gosuslugi.ru/usr_inf')
assert TEST_SETTINGS.esia_client_id != 'YOUR SYSTEM ID', "Please specify real system id!"
assert os.path.exists(TEST_SETTINGS.certificate_file), "Please place your certificate in res/test.crt !"
assert os.path.exists(TEST_SETTINGS.private_key_file), "Please place your private key in res/test.key!"
assert os.path.exists(TEST_SETTINGS.esia_token_check_key), "Please place ESIA public key in res/esia_pub.key !"
app = Flask(__name__)
esia_auth = EsiaAuth(TEST_SETTINGS)
@app.route("/")
def hello():
url = esia_auth.get_auth_url()
return 'Start here: <a href="{0}">{0}</a>'.format(url)
@app.route("/info")
def process():
code = request.args.get('code')
state = request.args.get('state')
esia_connector = esia_auth.complete_authorization(code, state)
inf = esia_connector.get_person_main_info()
return "%s" % inf
if __name__ == "__main__":
app.run()
Реализация
Устройство библиотеки тривиальное, комментариев не требует, после написания стало понятно, что можно было бы спроектировать и лучше, чтобы пользователю библиотеки требовалось выполнять меньше действий с ее интерфейсом.
Стоит отметить, что используется утилита openssl для подписи, в связи с этим есть лишняя операция создания временного файла.
Нас устраивает текущая реализация, но лучше было бы использовать pyopenssl.
У нас нет планов развития библиотеки, пока не будет требований в проекте, а их в ближайшей перспективе нет.
Если используете esia-connector в ваших проектах и попутно что-то добавите/исправите — PR-те, будем рады включить.
Что можно было бы сделать:
- Реорганизовать интерфейс библиотеки для упрощения использования.
- Заменить использование openssl на pyopenssl.
- Разработать функционал по получению других данных из ЕСИА.
- Поддержать альтернативный протокол обмена данных реализованный в ЕСИА (SAML).
- Реализовать обертки для популярных фреймворков, например: Django, Flask, возможно в рамках отдельных проектов.
Ссылки
- Методические рекомендации по использованию ЕСИА: minsvyaz.ru/ru/documents/4243
- Регламент информационного взаимодействия: www.minsvyaz.ru/ru/documents/4244
- Новость о возможности интеграции с ЕСИА: www.kommersant.ru/doc/2832483
- Открытая реализация на PHP: github.com/fr05t1k/esia