img3

© 2014 - 2024 esia.pro

Инструкция по интеграции модуля авторизации через ЕСИА (Python)

1 Общее описание

Библиотека содержит набор функций реализованных на языке программирования Python позволяющих организовать взаимодействие с сервисами Единой системы идентификации и аутентификации (ЕСИА) по протоколу OAuth 2.0. Подробную информацию о данном протоколе и принципах взаимодействия с ЕСИА можно получить в методических рекомендациях по использованию ЕСИА

2 Перечень поставляемых файлов

В состав поставляемых файлов входят следующие:

  • crypto - директория, в которой содержаться модули для работы с криптопровайдерами: native.py - использует криптографию на основе cryptography; openssl.py - использует криптографические возможности openssl; signer.py - пустой модуль. В нём планируется реализация функций для взаимодействия с сервисом подписания запросов (Signer);
  • logger - директория, в которой содержаться модули реализующие функционал логирования: esia_logger.py - содержит базовый функционал логирования; tf_logger.py - реализует запись лога в файл;
  • oauth2 - директория, в которой содержатся модули с необходимыми моделями и функционалом для взаимодействия с ЕСИА в рамках OAuth протокола: scope/usr.py - модуль, содержащий модели для представления данных пользователя и связанных с ним объектов (документов, транспортных средств, адресов, контактов, сведений о детях); scope/org.py - модуль, содержащий модель для представления данных организации; api/v1/login.py - модуль, реализующий взаимодействие с сервисом авторизации ЕСИА ac/ по API v1; api/v1/token.py - модуль, реализующий взаимодействие с сервисом получения токена доступа/обновления/идентификации ЕСИА te/ по API v1; api/v2/login.py - модуль, реализующий взаимодействие с сервисом авторизации ЕСИА ac/ по API v2; api/v2/token.py - модуль, реализующий взаимодействие с сервисом получения токена доступа/обновления/идентификации ЕСИА te/ по API v2; info.py - модуль, реализующий взаимодействие с сервисами ЕСИА для получения данных пользователей; logout.py - модуль, реализующий логаут (завершение пользовательской сессии) на стороне ЕСИА; requester.py - модуль, реализующий запросов в адреса сервисов ЕСИА;
  • utils - директория, в которой содержатся модули, реализующие вспомогательный функционал; helpers.py - модуль, содержащий функции работы со словарём, функции чтения/записи файлов, загрузки публичного/приватного ключа, кодирования; struct.py - содержит класс, который создает объект с именованными атрибутами на основе словаря; state.py - содержит описание класса, инстансы которого хранят информацию о выданном авторизационном коде, токене доступа, токене обновления, времени истичения токена доступа; config.py - модуль, содержащий класс конфигурации и класс, задающий набор необходимых параметров, передаваемых в запросах.

3 Основные функции

Основными функциями модуля авторизации являются:

  • получение авторизационного кода ЕСИА;
  • обмен авторизационного кода на маркер доступа;
  • получение данных пользователя из ЕСИА (в приложении Б перечислены скоупы, которые может получать библиотека);
  • выход (логаут) на стороне ЕСИА.

4 Интеграция библиотеки

Перед началом интеграции необходимо:

  • выполнить конфигурирование OpenSSL, подключив gost-engine с поддержкой алгоритмов ГОСТ Р 34.10-2012 и ГОСТ Р 34.11- 2012.
  • выполнить экспорт ключевой пары (сформированной по ГОСТ2012) из криптоконтейнера (экспорт можно сделать с помощью нашей утилиты);
  • настроить для вашей системы HTTPS (это обязательное требование, поскольку данные между вашей системой и ЕСИА передаются в открытом виде); настроить систему на технологическом портале тестовой/промышленной ЕСИА. На технологическом портале в окне редактирования параметров системы (см. рисунок 1) указать URL возврата после авторизации и логаута, а также установить алгоритм подписания запросов GOST3410_2012_256.

img1

img2

Поскольку библиотека поставляется в виде модулей с открытым исходным кодом она может быть интегрирована в кодовую базу любого проекта на Python (при соблюдении требований к зависимостям, которые описаны в разделе 5). Ниже будет рассмотрен пример интеграции библиотеки в проект, разработанный с использованием фреймворка Django. Для интеграции библиотеки необходимо выполнить следующие шаги:

Шаг 0. Установить необходимые зависимости, описанные в разделе 5. Шаг 1. Создать директорию для библиотеки авторизации и распаковать в неё архив, содержащий модули библиотеки. Шаг 2. Создать директории для хранения сертификатов и логов (для простоты, только в рамках примера, эти директории можно создать в директории проекта Django. Например, это может быть директория cert/ и log/). Шаг 3. ВАЖНО!!! Настроить доступ к директориям для размещения файлов сертификата, ключа и логов таким образом, чтобы их файлы нельзя было получить извне.

Шаг 4. В директорию для хранения сертификатов положить ключ и сертификат клиентской системы и сертификат ЕСИА. Шаг 5. Импортировать классы библиотеки в код проекта, там, где это необходимо и вызвать методы, обеспечивающие формирования запросов и обработку ответов ЕСИА. Шаг 5.1. Создать объект конфигурации для последующей его передачи в методы классов библиотеки. В Django приложении создание объекта конфигурации можно вынести в файл настроек esia_oauth2/settings.py, в котором импортируем класс OAuth2Configuration

from lib.esia.utils.config import OAuth2Configuration
...
DEFAULT_ESIA_OAUTH2_CONFIG = OAuth2Configuration(
    site="https://esia-portal1.test.gosuslugi.ru",
    issuer="RNDS",
    scope="openid fullname id_doc",
    access_type="online",
    login_redirect_uri="http://localhost:8080/oauth2/login_response/",
    logout_redirect_uri="http://localhost:8080/oauth2/logout_success/",
    cert_file_name=os.path.join(BASE_DIR, "cert/cert.crt"),
    pkey_file_name=os.path.join(BASE_DIR, "cert/secret.key"),
    esiakey_file_name=os.path.join(BASE_DIR, "cert/esia-test.pem"),
    path_to_openssl="openssl",
    check_token_signature=True,
    log_file_name=os.path.join(BASE_DIR, "log/esia-oauth2-python.log"),
    use_gost=True,
    crypto_provider="openssl",
    esia_api_version="v2"
)

Конфигурационные параметры описаны в приложении А.

Шаг 5.2. Вызвать метод формирования авторизационного запроса и передать его в адрес сервиса ЕСИА. Для этого в Django-приложении необходимо добавить метод oauth2_login и в роутинге (esia_oauth2/urls.py) в urlpatterns прописать соответствующий путь

re_path(r"^oauth2/login/$", views.oauth2_login, name="oauth2login"),

Далее, в sampleapp/views.py импортировать settings и классы OAuth2Login, OAuth2Info, OAuth2Logout, OAuth2ServiceState

from esia_oauth2 import settings
from lib.esia.oauth2.api.v2.login import OAuth2Login
from lib.esia.oauth2.info import OAuth2Info
from lib.esia.oauth2.logout import OAuth2Logout
from lib.esia.utils.state import OAuth2ServiceState

и написать реализацию метода oauth2_login

def oauth2_login(request):
    # вызов метода формирования авторизационного запроса
    login_obj = OAuth2Login(settings.DEFAULT_ESIA_OAUTH2_CONFIG)
    url = login_obj.create_login_url()
    # переход на url запроса
    return HttpResponseRedirect(url.login_url)

Шаг 5.3. Добавить код обработки запроса от ЕСИА, получаемого после авторизации пользователя на портале. Для этого в Django-приложении необходимо добавить метод oauth2_login_response и в роутинге (esia_oauth2/urls.py) в urlpatterns прописать соответствующий путь

re_path(r"^oauth2/login_response/$", views.oauth2_login_response)

Далее, в sampleapp/views.py написать реализацию метода oauth2_login_response

def oauth2_login_response(request):
    # анализ запроса
    params = get_request_parameters(request)
    
    # если в запросе ЕСИА ошибка
    if "error" in params:
        render_error(request, params["error"], params["error_description"])

    # если в запросе ЕСИА отсутствует state значение
    if not "state" in params:
        render_error(request, "Ошибка обработки запроса", "В запросе отсутствует обязательный параметр state")

    # если полученное state значение не соответствует сохранённому в сессии 
    if params["state"] != request.session["esia_oauth_state"]:
        render_error(request, "Ошибка обработки запроса", "Значение параметра state неверно")

    access_code = params["code"]
    # если в запросе ЕСИА отсутствует авторизационный код (code)
    if not access_code:
        render_error(request, "Неверный код доступа", "Получен неверный (пустой) код доступа")

    # получение данных пользователя из защищённого хранилища ЕСИА 
    service = OAuth2Info(settings.DEFAULT_ESIA_OAUTH2_CONFIG, OAuth2ServiceState(access_code))
    person_info = service.get_person_info()    # основная информация о пользователе
    contacts = service.get_person_contacts()   # контакты пользователя
    documents = service.get_person_documents() # документы пользователя
    addresses = service.get_person_addresses() # адреса пользователя
    vehicles = service.get_person_vehicles()   # транспортные средства пользователя
    orgs = service.get_person_orgs()           # организации пользователя
    
    kids = service.get_person_kids()           # информация о детях пользователя
    for kid in kids:
        kid_docs = service.get_person_kid_documents(kid.id)
        kid.docCount = len(kid_docs)
    
    # подготовка данных для вывода
    context = {
        "personal": person_info,
        "contacts": contacts,
        "documents": documents,
        "vehicles": vehicles,
        "orgs": orgs,
        "kids": kids,
        "addresses": [
            {
                "type": adr.type,
                "value":
              "Индекс: {zip_code}; Ид.страны: {country_id}; Регион: {region}; "
              "Город: {city}; Адрес: {address}; Улица: {street}; Строение: {building}; "
                    "Корпус: {frame}; Дом: {house}; Квартира: {flat}".format(
                        zip_code=adr.zipCode,
                        country_id=adr.countryId,
                        region=adr.region,
                        city=adr.city,
                        address=adr.addressStr,
                        street=adr.street,
                        building=adr.building,
                        frame=adr.frame,
                        house=adr.house,
                        flat=adr.flat
                    )
            } for adr in addresses
        ]
    }
    
    return render(request, "sampleapp/personal_info.html", context)

ВНИМАНИЕ!!! Авторизовать пользователей в клиентской системе можно лишь в случае, когда значение поля trusted в объекте person_info имеет значение true. Это означает, что пользователь имеет подтверждённую учётную запись ЕСИА. В противном случае, данным учётной записи доверять нельзя.

Шаг 5.4. Добавить код формирования запроса на логаут в ЕСИА. Для этого в Django-приложении необходимо добавить метод oauth2_logout и в роутинге (esia_oauth2/urls.py) в urlpatterns прописать соответствующий путь

re_path(r"^oauth2/logout/$", views.oauth2_logout, name="oauth2logout")

Далее, в sampleapp/views.py написать реализацию метода oauth2_logout

def oauth2_logout(request):
    # вызов метода формирования запроса на логаут
    logout_obj = OAuth2Logout(settings.DEFAULT_ESIA_OAUTH2_CONFIG)
    url = logout_obj.create_logout_url(settings.DEFAULT_ESIA_OAUTH2_CONFIG)
    # переход на url запроса
    return HttpResponseRedirect(url)

5 Зависимости

Библиотека авторизации предъявляет следующие языковые требования

Python 3.8 или выше

В окружении библиотеки авторизации должна присутствовать утилита

OpenSSL v.1.1.x

которую можно вызвать посредством системного вызова. OpenSSL должна поддерживать алгоритмы ГОСТ2012. Для этого необходимо установить расширение

Gost-engine

Для работы библиотеки авторизации необходимо наличие компонент, перечень которых приведён в таблице 1.

Наименование Описание
os os
base64 base64
json json
requests requests
tempfile tempfile
uuid uuid
cryptography cryptography
datetime datetime
urllib.parse urllib.parse
abc abc
binascii binascii
datetime datetime
collections collections

ПРИЛОЖЕНИЕ А
Описание конфигурационных параметров

Библиотека авторизации принимает на вход набор параметров, описанных в таблице А.1.

Таблица А.1 - Описание параметров

Наименование параметра Описание параметра
site URL системы - поставщика услуг (ЕСИА)
issuer Мнемоника, полученная при регистрации ИС в минкомсвязи
scope Перечень областей данных, к которым предоставляется доступ для ИС после авторизации (перечень скоупов необходимо указывать в соответствии с заявкой на подключение к промышленной/тестовой ЕСИА)
access_type Определяет тип доступа к защищенному хранилищу ЕСИА предоставляемому для ИС (допустимые значения “offline” и “online”)
login_redirect_uri Адрес возврата в ИС после авторизации пользователя в ЕСИА
logout_redirect_uri Адрес возврата в ИС после логаута пользователя в ЕСИА
cert_file_name Путь к файлу сертификата, содержащему публичный ключ ИС
pkey_file_name Путь к файлу, содержащему закрытый ключ ИС
esiakey_file_name Путь к файлу, содержащему сертификат ЕСИА
path_to_openssl Полный путь к утилите OpenSSL (указывается под Windows, в Linux достаточно указать openssl, поскольку утилита прописывается в окружении)
check_token_signature Признак необходимости проверять подпись токена доступа, получаемого от ЕСИА (true - проверять подпись, false - не проверять)
log_file_name Путь к лог файлу
use_gost Признак необходимости подписывать и проверять запросы с помощью ГОСТ34.10-2012 (true - использовать ГОСТ, false - использовать RSA)
esia_api_version Определяет версию API, используемой для взаимодействия с ЕСИА. Допустимые значения v1 и v2. Значение по умолчанию v2 (актуальная версия).

ПРИЛОЖЕНИЕ Б
Перечень запрашиваемых областей доступа

Библиотека авторизации запрашивает доступ к наборам областей данных (scope), в соответствии с перечнем приведённым в таблице Б.1.

Таблица Б.1 - Перечень запрашиваемых областей доступа

Название scope Состав набора данных Запрашивается(+)/Не запрашивается(-)
1. fullname Просмотр фамилии, имени и отчества:
- фамилия;
- имя;
- отчество.
+
2. birthdate дата рождения, указанная в учетной записи +
3. gender пол, указанный в учетной записи +
4. snils СНИЛС, указанный в учетной записи +
5. inn ИНН, указанный в учетной записи +
6. id_doc Просмотр данных о документе, удостоверяющем личность:
- серия и номер документа, удостоверяющего личность;
- дата выдачи;
- кем выдан;
- код подразделения;
- гражданство.
+
7. birthplace место рождения. +
8. medical_doc Просмотр данных полиса ОМС:
- номер полиса ОМС;
- срок действия.
+
9. military_doc Просмотр данных военного билета:
- серия и номер военного билета;
- дата выдачи;
- орган, выдавший документ.
+
10. foreign_passport_doc Просмотр данных заграничного паспорта:
- фамилия, имя, отчество буквами латинского алфавита;
- серия и номер заграничного паспорта;
- дата выдачи;
- срок действия;
- орган, выдавший документ;
- гражданство.
+
11. drivers_licence_doc Просмотр данных водительского удостоверения:
- серия и номер водительского удостоверения;
- дата выдачи;
- срок действия.
+
12. birth_cert_doc Просмотр данных свидетельства о рождении:
- серия и номер свидетельства;
- дата выдачи;
- место государственной регистрации.
+
13. residence_doc Просмотр данных вида на жительство:
- серия и номер вида на жительство;
- дата выдачи.
+
14. temporary_residence_doc Просмотр данных разрешения на временное проживание:
- серия и номер разрешения на временное проживание;
- дата выдачи.
+
15. vehicles Просмотр данных транспортных средств:
- государственный регистрационный знак;
- серия и номер свидетельства о регистрации.
+
16. email адрес электронной почты, указанный в учетной записи +
17. mobile номер мобильного телефона +
18. contacts Просмотр данных о контактах и адресах:
- номер домашнего телефона;
- номер мобильного телефона;
- адрес электронной почты;
- адрес регистрации;
- адрес места проживания.
+
19. usr_org список организаций пользователя. +
20. usr_avt Просмотр изображения (аватара) пользователя:
- получения изображения (аватара);
- создание и обновление изображения (аватара);
- получение исходного изображения (аватара)
-
21. self_employed Просмотр данных о самозанятых
- признак самозанятого;
- категория (вид деятельности).
-
22. kid_fullname Просмотр фамилии, имени и отчества:
- фамилия;
- имя;
- отчество.
+
23. kid_birthdate дата рождения ребенка +
24.. kid_gender Пол ребенка +
25. kid_snils СНИЛС ребенка +
26. kid_inn ИНН ребенка +
27. kid_birth_cert_doc Просмотр данных свидетельства о рождении:
- серия свидетельства;
- номер свидетельства;
- дата выдачи свидетельства;
- кем выдано свидетельство.
+
28. kid_medical_doc Просмотр данных полиса ОМС:
- номер полиса ОМС;
- действителен до ОМС.
+
1. org_shortname Сокращенное наименованиеорганизации -
2. org_fullname Полное наименованиеорганизации -
3. org_type Тип организации -
4. org_ogrn ОГРН организации -
5. org_inn ИНН организации -
6. org_leg ОПФ организации -
7. org_kpp КПП организации -
8. org_agencyterrange Территориальнаяпринадлежность ОГВ -
9. org_agencytype Тип ОГВ -
10. org_oktmo ОКТМО организации -
11. org_ctts Контакты организации: номер телефона, номер факса, адрес электронной почты -
12. org_addrs Адреса организации (почтовый адрес, юридический адрес): индекс, идентификатор страны, адрес в виде строки (не включая дом, строение, корпус, номер квартиры), строение, корпус, дом, квартира, код ФИАС, регион,город, внутригородской район, район, поселение, доп. территория, улица на доп. территории, улица -
13. org_vhls Транспортные средства организации: название, государственный регистрационный знак, серия и номер свидетельства орегистрации -
14. org_grps Группы, владельцемкоторых является организация -
15. org_emps Данные о сотрудникахорганизации -
16. org_brhs Данные о филиалах организации (название, КПП, ОПФ, контакты,адреса) -
17. org_brhs_ctts Контакты филиаловорганизации -
18. org_brhs_addrs Адреса филиаловорганизации -
19. org_rcs Центры регистрацииорганизации -
20. org_stms Системы, владельцемкоторых является организация -
21. org_invts Приглашения, направленныеорганизацией -
22. categories Данные присвоенных организации видовдеятельности -
  • Инструкция по интеграции модуля авторизации через ЕСИА (Python)
  • 1 Общее описание
  • 2 Перечень поставляемых файлов
  • 3 Основные функции
  • 4 Интеграция библиотеки
  • 5 Зависимости
  • ПРИЛОЖЕНИЕ А Описание конфигурационных параметров
  • ПРИЛОЖЕНИЕ Б Перечень запрашиваемых областей доступа