Библиотека Python 3 для подключения к ЕСИА — esia-connector

от автора

Все началось с того, что Минкомсвязи разрешило использовать портал госуслуг для идентификации и аутентификации пользователей на негосударственных веб-узлах. Это реализуется с помощью службы ЕСИА (Единая Система Идентификации и Аутентификации — 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 позволяет:

  • аутентифицироваться в ЕСИА, получить в ответ токен (который затем можно использовать для идентификации пользователя), проверить его;
  • получить личные данные пользователя: ФИО, данные удостоверяющих личность документов (паспорта, водительские права), контактные данные (номера телефонов, адрес электронной почты), ИНН, СНИЛС, адреса (проживания и регистрации).

Использование

Для того, чтобы подключиться к ЕСИА с помощью библиотеки вам нужно иметь на руках:

  1. Сертификат, выданный, либо самоподписанный в формате описанном в методических рекомендациях, загруженный на тестовый и боевой сервер ЕСИА.
    Выдержка из методических рекомендаций

    Выпустить ключевой контейнер и сертификат ключа квалифицированной электронной подписи для подключаемой информационной системы (должен содержать ОГРН ЮЛ, являющегося оператором информационной системы). Дополнительно поддерживается работа с ключевым контейнером и сертификатом ключа неквалифицированной электронной подписи в формате X.509 версии 3. В этом случае является допустимым самостоятельно сгенерировать (например, с помощью утилиты keytool из состава Java Development Kit) для своей системы ключевой контейнер и самоподписанный сертификат. Сертификат требуется для идентификации ИС при взаимодействии с ЕСИА. ЕСИА поддерживает алгоритмы формирования электронной подписи RSA с длиной ключа 2048 бит и алгоритмом криптографического хэширования SHA-256, а также алгоритм электронной подписи ГОСТ Р 34.10-2001 и алгоритм криптографического хэширования ГОСТ Р 34.11-94.
  2. Выданную службой поддержки ЕСИА учетную запись компании на боевом и тестовом серверах. Она, затем, должна быть указана при создании объекта EsiaSettings вместо строки “YOUR_SYSTEM_ID”.
  3. Учетные записи пользователей на тестовом и боевом серверах ЕСИА для отладки и тестирования.
  4. Публичные ключи ЕСИА (тестовый и боевой) для верификации полученного токена. В открытом доступе этих ключей нет, техподдержка высылает их электронной почтой по требованию.

Чтобы запустить тестовый пример (минимальное веб-приложение на Flask доступно в репозитории библиотеки) нужно
предварительно загруженный на сервер ЕСИА сертификат разместить в файле “esia-connector/examples/res/test.crt”. В этом же каталоге следует разместить ваш приватный ключ под именем “test.key”, а упомянутый выше публичный ключ разместить под именем “esia_pub.key”.
Затем запустить приложение Flask, из каталога examples выполнить:
python flask_app.py

На главной странице мы увидим правильно сформированную ссылку для обращения к ЕСИА, при переходе по ней сервер ЕСИА обработает данные в GET-запросе, запросит у пользователя логин и пароль к ЕСИА, затем после удачного введения запросит разрешение на доступ нашего приложения к ЕСИА и, в случае выдачи разрешения, редиректит на заданную в тестовом примере страницу, где мы с уже полученным токеном сделаем еще пару запросов на получение персональных данных пользователя от лица которого производим запрос, и отобразим эти данные на этой же странице.

Пример использования esia-connector

import 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-те, будем рады включить.

Что можно было бы сделать:

  1. Реорганизовать интерфейс библиотеки для упрощения использования.
  2. Заменить использование openssl на pyopenssl.
  3. Разработать функционал по получению других данных из ЕСИА.
  4. Поддержать альтернативный протокол обмена данных реализованный в ЕСИА (SAML).
  5. Реализовать обертки для популярных фреймворков, например: Django, Flask, возможно в рамках отдельных проектов.

Ссылки

  1. Методические рекомендации по использованию ЕСИА: minsvyaz.ru/ru/documents/4243
  2. Регламент информационного взаимодействия: www.minsvyaz.ru/ru/documents/4244
  3. Новость о возможности интеграции с ЕСИА: www.kommersant.ru/doc/2832483
  4. Открытая реализация на PHP: github.com/fr05t1k/esia

ссылка на оригинал статьи http://habrahabr.ru/post/271827/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *