© 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.
Поскольку библиотека поставляется в виде модулей с открытым исходным кодом она может быть интегрирована в кодовую базу любого проекта на 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. | адрес электронной почты, указанный в учетной записи | + | |
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 | Данные присвоенных организации видовдеятельности | - |