Это старая версия документа!
Содержание
Автор: Владимир Недорослев
Протокол работы ЕСИА
Все запросы в данном руководстве разделены построчно для удобства чтения.
Данный документ описывает конфигурацию работы ЕСИА.
Discovery document
Discovery document – это документ в формате JSON, показывающий информацию об ЕСИА - адреса Endpoint’ов, поддерживаемые scope, какую информацию о пользователе можно выдать и пр.
Его можно найти по адресу:
https://{Базовый адрес ЕСИА}/.well-known/openid-configuration
Содержит следующие поля:
- issuer – URL идентификатор ЕСИА. ЕСИА использует его для сравнения с полем iss в ID Token’е.
- jwks_uri – URL JWK документа. Содержит ключи, которые клиенты должны использовать при проверке подписей ЕСИА.
- authorization_endpoint – URL адрес Authorization Endpoint’а.
- token_endpoint – URL адрес Token Endpoint’а.
- userinfo_endpoint - URL адрес UserInfo Endpoint’а.
- end_session_endpoint- endpoint закрытия сессии.
- revocation_endpoint - endpoint отзыва Access Token'а.
- scopes_supported – JSON массив, содержащий список всех значений scope, поддерживаемых ЕСИА:
- openid – обязательный scope для всех запросов. Означает, что используется технология OpenID Connect.
- profile – включает в себя:
- pin - персональный номер.
- citizenship - гражданство. Для граждан Кыргызстана
KGZ. - name - полное имя (ФИО).
- family_name - фамилия.
- given_name - имя.
- middle_name - отчество.
- gender - пол (
maleилиfemale). - birthdate - дата рождения в формате
YYYY-MM-DD. (Например,1990-11-23).
- email – включает в себя email и email_verified.
- phone – включает в себя phone и phone_verified.
- offline_access – нужно ли получение Refresh Token'а.
- organizations - ИНН организаций (юридических лиц), в которых состоит пользователь.
- response_types_supported – JSON массив, содержащий список значений response_type, поддерживаемых ЕСИА.
- response_modes_supported – JSON массив, содержащий список поддерживаемх response_mode, основанный на OAuth 2.0.
- claims_supported – JSON массив, содержащий список данных, которые может выдавать ЕСИА:
- sub – идентификатор пользователя ЕСИА.
- pin – персональный номер.
- family_name – Фамилия.
- given_name – Имя.
- middle_name – Отчество.
- name – Полное имя (ФИО).
- citizenship – гражданство. Для граждан Кыргызстана – KGZ.
- gender – Пол (
maleилиfemale). - birthdate – Дата рождения.
- email – электронная почта.
- email_verified – подтверждена ли почта (true/false).
- phone_number – мобильный телефон в формате E164.
- phone_number_verified – подтвержден ли телефон (true/false).
- organizations - массив, содержащий ИНН организаций (юридических лиц), в которых состоит пользователь.
ID Token
Для аутентификации пользователя OpenID Connect вводит понятие ID Token’а. Это структура данных, которая хранит информацию об аутентификации пользователя ЕСИА. Представляется в виде JSON Web Token (JWT). ЕСИА выдаёт ID Token со следующими полями:
- iss – (Issuer) идентификатор ЕСИА. Это регистрозависимый URL, использующий https, содержащий схему и хост. Может содержать номер порта, путь. Не содержит параметров запроса.
- sub – (Subject) идентификатор пользователя. Уникальный, никогда неменяющийся идентификатор пользователя, который хранит ЕСИА. Например,
24400320. Является регистрозавсимой строкой, длиной не более 255 ASCII символов. - aud – (Audience) массив строк, содержащий идентификаторы клиентов (client_id), которым предназначен данный ID Token.
- exp – (Expiration) срок действия ID Token'a. Время, после которого ID Token не является валидным и не должен обрабатываться. При валидации ID Token'а текущее время должно быть до времени, указанного в этом поле. Значение представляется в виде JSON числа, показывающий количество секунд прошедших с 1970-01-01T0:0:0Z согласно UTC стандарту (см. RFC3339 для подробной информации насчёт времени в UTC).
- iat – (Issued at) время, когда ID Token был создан. Значение представляется в виде JSON числа, показывающий количество секунд прошедших с 1970-01-01T0:0:0Z согласно UTC стандарту.
- auth_time – (Authentication time) время, когда была произведена аутентификация пользователя. Значение представляется в виде JSON числа, показывающий количество секунд прошедших с 1970-01-01T0:0:0Z согласно UTC стандарту.
- nonce – регистрозависимая строка, ассоциирующая сессию клиента с ID Token’ом, чтобы избежать атак повторного воспроизведения (replay attacks). Клиенты должны проверять, чтобы это значение было равно значению nonce в authentication request'e.
- amr – (Authentication methods references) JSON массив строк, хранящий методы аутентификации, использованные при аутентификации пользователя. Например, может покаазть, что при аутентификации был использован пароль и OTP.
- at_hash – хэш Access Token’а. Хэш вычисляется по левой половине хэшей октетов Access Token“a в формате ASCII. Примененный хэш-алгоритм указан в головной части (header) ID Token’a в значении
alg.
Authentication request
Authentication request (Запрос на аутентификацию) — это GET или POST запрос клиента в Authorization Endpoint, который требует, чтобы пользователь аутентифицировался в ЕСИА.
В случае GET запроса, параметры запроса указывается непосредственно в самом запросе.
В случае POST запроса, параметры запроса указываются в теле запроса (Content-Type: application/x-www-form-urlencoded)
Параметры запроса
- scope (Обязательный) – разделенные пробелом значения, показывающие, какие данные необходимы клиенту. Обязательно должно содержать значение
openid. - response_type (Обязательный) – определяет способ процесса авторизации. В случае с ЕСИА используется значение
code. - client_id (Обязательный) – идентификатор клиента, выданный ЕСИА.
- redirect_uri (Обязательный) – URI, куда будет отправлен ответ ЕСИА после того, как пользователь пройдёт аутентификацию в ЕСИА. Он задаётся вместе с
client_idпри регистрации клиента. - nonce (Опциональный) – регистрозависимая строка ассоциирующая сессию клиента с ID Token’ом, чтобы избежать атак повторного воспроизведения (replay attacks).
- state (Опциональный) – значение для сохраниния состояние между запросом и callback’ом. Обычно для борьбы с CSRF это значение криптографически привязывается к куки браузера.
PKCE
Так как ЕСИА использует Authorization Code flow with PKCE (RFC7636), при запросе на авторизацию необходимо сделать следующее:
* Сформировать code verifier - криптографически случайная строка размером от 43 до 128 символов, и состоящая из символов a-z, A-Z, 0-9 -._~ * Сформировать code_challenge следующим образом:
base64url(sha256(code_verifier))
* Добавить в запрос следующий параметр:
code_challenge_method=S256
Валидация запроса
При получении запроса на аутентификацию ЕСИА проверит, чтобы все параметры запроса соответствовали стандарту OAuth 2.0 и OpenId Connect. Подразумевается наличие обязательных параметров scope, response_type, client_id, redirect_uri. В случае, если запрос составлен не верно, ЕСИА вернёт ошибку на указанный redirect_uri. Информация об ошибке будет представлена в виде параметров.
Возможны следующие параметры:
- error (Обязательный) – название ошибки. Может принимать следующие значения:
- invalid_request – неправильный запрос. Возникает, если в запросе отсутствует обязательный параметр, запрос содержит неправильное значение параметра, включает в себя одинаковый параметр более одного раза и пр.
- unauthorized_client – неавторизованный клиент. Клиент не авторизован и не может получить авторизационный код.
- access_denied – отказано в доступе. Пользователь либо ЕСИА отколнили запрос.
- unsupported_response_type – неподдерживаемый возвращаемый тип. ЕСИА не поддерживает получение авторизационного кода указанным методом.
- invalid_scope – неправильный scope. Запрашиваемое(-ые) значения scope неверны, неизвестны, либо составлены неправильно.
- server_error – ошибка сервера. Ошибка со стороны ЕСИА, которая не позволяет обработать запрос.
- temporarily_unavailable – временно недоступно. В данный момент ЕСИА не может обработать запрос из-за перегрузки либо технических работах на сервере.
- invalid_request_uri – неправильный redirect_uri. redirect_uri возвращает ошибку при перенаправлении либо содержит неправильные данные.
- error_description (Опциональный) – описание ошибки. Описание ошибки понятное человеку.
- error_uri (Опциональный) – URI ошибки. URI веб-страницы, на которой находится дополнительная информация об ошибке.
- state (Опциональный) – состояние согласно OAuth 2.0. Ставится значение, полученное от клиента.
Примеры
Примеры значений scope:
scope=openid profile email scope=openid profile notification_api phone
Пример ответа клиента, который перенаправляет браузер пользователя к Authorization endpoint для запроса на аутентификацию:
HTTP/1.1 302 Found
Location: https://{базовый-адрес-ЕСИА}/connect/authorize?
response_type=code
&scope=openid%20profile%20email
&client_id=s6BhdRkqt3
&state=af0ifjsldkj
&redirect_uri=https%3A%2F%2Fclient.example.org%2Fcb
Пример запроса, который отправит браузер пользователя к ЕСИА в ответ на redirect ответ клиента:
GET https://{базовый-адрес-ЕСИА}/connect/authorize?
response_type=code
&scope=openid%20profile%20email
&client_id=s6BhdRkqt3
&state=af0ifjsldkj
&redirect_uri=https%3A%2F%2Fclient.example.org%2Fcb HTTP/1.1
Пример ошибки:
HTTP/1.1 302 Found Location: https://client.example.org/cb? error=invalid_request &error_description=Unsupported%20response_type%20value &state=af0ifjsldkj
Пример ответа ЕСИА при успешной валидации запроса на аутентификацию:
HTTP/1.1 302 Found Location: https://client.example.org/cb? code=SplxlOBeZQQYbYS6WxSbIA &state=af0ifjsldkj
Token request
Для получения ID Token’а и Access Token’а клиент должен отправить POST запрос в Token Endpoint ЕСИА, предоставив полученный авторизационный код (code), свой client_id, client_secret и redirect_uri.
client_id и client_secret должны находится в заголовке запроса Authorization типа Basic в качестве имени пользователя и пароля соответственно.
В теле запроса должны находится следующие параметры (Content-Type: application/x-www-form-urlencoded):
grant_type=authorization_code
&code={ваш авторизационный код}
&redirect_uri={ваш redirect_uri}
Пример запроса к Token Endpoint
POST https://{базовый-адрес-ЕСИА}/connect/token
Content-Type: application/x-www-form-urlencoded
Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW
grant_type=authorization_code&code=SplxlOBeZQQYbYS6WxSbIA
&redirect_uri=https%3A%2F%2Fclient.example.org%2Fcb
Валидация запроса
ЕСИА валидирует запрос следующим образом:
- Аутентифицирует клиента по полученным client_id и client_secret.
- Проверит авторизационный код. Действительно ли он был выдан данному клиенту. Правильный ли он, не был ли он использован до этого, был ли выдан в результате запроса на аутентификацию.
- Сравнит полученный redirect_uri со значением redirect_uri полученном при запроса на аутентификацию.
При успешной валидации ЕСИА вернёт Id Token и Access Token в ответ в формате application/json, а также следующие поля:
- token_type – по стандарту всегда имеет значение
Bearer. - refresh_token – токен, позволяющий получить новый access token после того, как он истёк. Выдаётся в случае, если было указано значение scope
offline_accessво время authentication request. - expires_in – значение в секундах, показывающее через сколько access token станет недействительным.
При возникновении ошибки, информация о ней вернётся в том же формате, что и при запросе на аутентификацию.
Пример успешного ответа ЕСИА с ID Token'ом и Access Token'ом:
HTTP/1.1 200 OK
Content-Type: application/json
Cache-Control: no-store
Pragma: no-cache
{
"access_token": "eyJhbGciOiJSUzI1NiIsImtpZCI6ImNhZzBDYk1UYzh4d293MDVaVDRpRFEiLCJ0eXAiOiJhdCtqd3QifQ.eyJuYmYiOjE1ODQ0NDExNTAsImV4cCI6MTU4NDQ0NDc1MCwiaXNzIjoiaHR0cDovL2xvY2FsaG9zdDo3MDAwIiwiYXVkIjoibm90aWZpY2F0aW9uX2FwaSIsImNsaWVudF9pZCI6Im12Yy1jbGllbnQiLCJzdWIiOiIxMDAwMDAwIiwiYXV0aF90aW1lIjoxNTg0NDQxMTQ4LCJpZHAiOiJsb2NhbCIsInNjb3BlIjpbInByb2ZpbGUiLCJvcGVuaWQiLCJlbWFpbCIsInBob25lIiwibm90aWZpY2F0aW9uX2FwaSJdLCJhbXIiOlsibWZhIl19.KC-_Ua4k3rbRAVEkWF_NffnlGqInfSsSiD-zEk5dmLn5a7PAiiptDNqGpmSJbMhl2rbyFqTrBtUDxmkSbXALDWTAvuRqagTkEvlu2uUpJSQ9c_aYLsW4QdUdR2uAKliRlNAQFygWkN4xsXPSaB6E0B71YKmQcYutssBBcP3tBu_E4EDMW30Vky_osQeB8moHkPthMxXkpBxLSKieY77FOQDJzbaVmzrm9wmIor7OuwFtp0b9yKdpAsg9cGbgcmqW5pYNSa2GdhEzYrf6tkfF7tyuw-LYbJjCklfPwIQNk-RT1TicSwdZzsBWoAS8pWiBfwN4MAaA6TP4O6LA7hcdZw",
"token_type": "Bearer",
"refresh_token": "8xLOxBtZp8",
"expires_in": 3600,
"id_token": "eyJhbGciOiJSUzI1NiIsImtpZCI6ImNhZzBDYk1UYzh4d293MDVaVDRpRFEiLCJ0eXAiOiJKV1QifQ.eyJuYmYiOjE1ODQ0NDExNTAsImV4cCI6MTU4NDQ0MTQ1MCwiaXNzIjoiaHR0cDovL2xvY2FsaG9zdDo3MDAwIiwiYXVkIjoibXZjLWNsaWVudCIsIm5vbmNlIjoiNjM3MjAwMzc5MzYyNjEzMzE0LlkyTmtZVGN3T0dFdFl6Y3pNaTAwTURreUxUbGhPVFF0T0RJd1pXVmxPVGMxTURVeFpXUTJNemd3TXpJdE9XTmlZaTAwWVROakxUZzFaREV0WkdFMU1XVTJNbVJsWVRFNCIsImlhdCI6MTU4NDQ0MTE1MCwiYXRfaGFzaCI6ImhpOWItMURYanVtSWRCeFJ1VGRlb3ciLCJzX2hhc2giOiJFNXdOMzRlMFZkVl9jSVJQREZGS0h3Iiwic2lkIjoiMjc1SEtZRE1QS0EtRGt1NXJWdjNJdyIsInN1YiI6IjEwMDAwMDAiLCJhdXRoX3RpbWUiOjE1ODQ0NDExNDgsImlkcCI6ImxvY2FsIiwiYW1yIjpbIm1mYSJdfQ.dkcyzcRHrTZAGATA2p3Q8x7PMeQRQdWYq9h0ptMD0lx_2LvKNc9ItEncBFm1Kjjtq8oY2wiIGILJTBwiyO7IGCePHCLLXTy2csxcd-gL83nXL5aosIOxOjTiIc7Wo4mCVIsnk-fHdroHmfPmB-gAEAnoEpOTbN5IZ-lpAJl_WhB-utbiNVyEVrzm03usHppbu2-ev-9vWOuiQy6Ryg-GBWTkv0Hi3Q5mnG1FBA-ac-13JXBIhSEPtKWFw6Ck3-OVi4IoTzh5uz-IPFv_1H12ervVE7Qf9tv6sEbrGj2q1x3KbAkAEeaGpJWduJfHLNthxwk99Gbl8JL710cZGGCpdQ"
}
UserInfo request
Для получения информации о пользователе, клиенту необходимо отправить GET или POST запрос в UserInfo Endpoint с заголовком Authorization типа Bearer со значением полученного Access Token'а.
Рекомендуется использовать GET запрос.
Пример запроса:
GET https://{базовый-адрес-ЕСИА}connect/userinfo
Host: server.example.com
Authorization: Bearer eyJhbGciOiJSUzI1NiIsImtpZCI6ImNhZzBDYk1UYzh4d293MDVaVDRpRFEiLCJ0eXAiOiJhdCtqd3QifQ.eyJuYmYiOjE1ODQ0NDExNTAsImV4cCI6MTU4NDQ0NDc1MCwiaXNzIjoiaHR0cDovL2xvY2FsaG9zdDo3MDAwIiwiYXVkIjoibm90aWZpY2F0aW9uX2FwaSIsImNsaWVudF9pZCI6Im12Yy1jbGllbnQiLCJzdWIiOiIxMDAwMDAwIiwiYXV0aF90aW1lIjoxNTg0NDQxMTQ4LCJpZHAiOiJsb2NhbCIsInNjb3BlIjpbInByb2ZpbGUiLCJvcGVuaWQiLCJlbWFpbCIsInBob25lIiwibm90aWZpY2F0aW9uX2FwaSJdLCJhbXIiOlsibWZhIl19.KC-_Ua4k3rbRAVEkWF_NffnlGqInfSsSiD-zEk5dmLn5a7PAiiptDNqGpmSJbMhl2rbyFqTrBtUDxmkSbXALDWTAvuRqagTkEvlu2uUpJSQ9c_aYLsW4QdUdR2uAKliRlNAQFygWkN4xsXPSaB6E0B71YKmQcYutssBBcP3tBu_E4EDMW30Vky_osQeB8moHkPthMxXkpBxLSKieY77FOQDJzbaVmzrm9wmIor7OuwFtp0b9yKdpAsg9cGbgcmqW5pYNSa2GdhEzYrf6tkfF7tyuw-LYbJjCklfPwIQNk-RT1TicSwdZzsBWoAS8pWiBfwN4MAaA6TP4O6LA7hcdZw
Ответ от ЕСИА:
HTTP/1.1 200 OK
Content-type: application/json
{
"sub":"1000000",
"pin":"20101199012345",
"citizenship":"KGZ",
"family_name":"Андреев",
"given_name":"Андрей",
"middle_name":"Андреевич",
"name":"Андреев Андрей Андреевич",
"gender":"male",
"birthdate":"1990-01-01",
"email":"some.email@gmail.com",
"email_verified":"True",
"phone_number":"+996000123456",
"phone_number_verified":"True"
}
