Библиотека 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/eigenmethod/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
    • +10
    • 8,1k
    • 4
    Поделиться публикацией
    AdBlock похитил этот баннер, но баннеры не зубы — отрастут

    Подробнее
    Реклама
    Комментарии 4
    • +1
      А чем не подходило любое open source решение реализующее SAML в режиме Service Provider?
      • 0
        Ждал понедельника, чтобы уточнить информацию.
        1. Нам поступило требование поддержать именно OAuth 2.0 / OpenID Connect.
        2. В заявлении на подключение к ЕСИА для негосударственных учреждений не было возможности выбрать SAML. Как дело обстоит сейчас не знаю.

        Вполне вероятно, что ваша идея заработает, не могу ни подтвердить, ни опровергнуть.
      • 0
        А на каком сайте можно посмотреть в рабочем виде вашу либу?
        Мы тоже подключали нескольких профучастников. У них разные платформы были. Использовали коммерческие решения вот от сюда: esia.pro
        • 0
          Сайта нет, у нас мобильное приложение.
          В боевом режиме коннектор успешно работает на ограниченном круге пользователей, но продукт в продакшн не вышел, не могу поделиться большей информацией.

        Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.