Что такое IDToken?

IDToken – объект, закодированный как JWT (JSON Web Token), содержащий идентификатор владельца номера (sub) и информацию о контексте аутентификации конечного пользователя.

Полезные ссылки:

  1. Спецификация rfc7519;
  2. Спецификация rfc7515;
  3. Онлайн инструмент для работы с JWT;
  4. Справочник библиотек для работы с JWT;

JWT — один из способов представления данных для передачи между двумя или более сторонами в виде JSON-объекта.

Структурно JWT состоит из трех частей:

  • header — заголовок;
  • payload — полезная нагрузка;
  • signature — подпись.

Заголовок и полезная нагрузка — обычные JSON-объекты, которые кодируются при помощи алгоритма base64url. Закодированные части соединяются друг с другом и на их основе вычисляется подпись. Полученное значение подписи также кодируется при помощи алгоритма base64url и присоединяется к остальным частям через знак “.”.

Структура JWT

JWT = base64UrlEncode(header) + "." + base64UrlEncode(payload) + "." + base64UrlEncode(signature)

Пример ID Token

eyJhbGciOiJSUzI1NiIsImtpZCI6InJzYTEiLCJ0eXAiOiJKV1QifQ.eyJzdWIiOiI3YTcxNjIxMC1mMmJmLTQ3YjItYWQ5Yy1lNmJmZjFkNzMxYTQiLCJhbXIiOlsiU0lNX09LIl0sImF0X2hhc2giOiJDMV9xNE84ZWJyZ3ZRdk9ZSXhlb0hBIiwiZXhwIjoxNjYzNzMzMzk5LCJoYXNoZWRfbG9naW5faGludCI6Ijc2YzVhMmZhODYwYTQyOTk5OTU5ZjNhMDk1ZWEwNDcwNDEzMmQxYTAwN2EyZjdhODg5NzJhM2EwZTZkNDM0MjUiLCJpYXQiOjE2NjM3MzI3OTksImlzcyI6Imh0dHBzOi8vaWRndy5tb2JpbGVpZC5tdHMucnUiLCJub25jZSI6IjAyYmMzMDY4LTc1ZjMtNGI1NS1hMzI3LTU2YmJjN2EwZDg2MyIsImF6cCI6Im10c190ZXN0X3NlcnZpY2UiLCJkaXNwbGF5ZWRfZGF0YSI6ItCf0L7QtNGC0LLQtdGA0LTQuNGC0LUg0LLRhdC-0LQg0LIgbXRzX3Rlc3Rfc2VydmljZSIsImF1dGhfdGltZSI6MTY2MzczMjc5OSwiYWNyIjoiMiIsImF1ZCI6WyJtdHNfdGVzdF9zZXJ2aWNlIl19.Ia-hfagE8Y2cmbL66Hrws3WVnVGj0ogbnOx1DtOAnLTWM5nYgIwQyUEqFIgQkHMAWLtAJJWi_ap0pim2UNbcwAdlNoHdE-RYwrCTfuyrQ0K5x4uCFFo8pDCRZUTEoIljsddYWmwB6YR6UGQMfB3vH04uk23SwqaQqg8RIc4jGTKgvsmhgDf3NVScoY2cE_4D02kC6llWMBbkSoqQ-fRsZxlG1dUkw85Z6eKfcwL3dK-9lAfhptlfFMw0nuwC35fYRp-Vo9g7v2R04EN-rqj4KuhS5Mo2-oiX8XtoMRY2nsroQOUxVsUnDM_7zThBPBdpX3eiE5_HdrdoWd4gNhpnaA

Пример Header+Payload

HEADER:ALGORITHM & TOKEN TYPE
 
{
  "alg": "RS256",
  "kid": "rsa1",
  "typ": "JWT"
}
 
PAYLOAD:DATA
 
{
  "sub": "7a716210-f2bf-47b2-ad9c-e6bff1d731a4",
  "amr": [
    "SIM_OK"
  ],
  "at_hash": "C1_q4O8ebrgvQvOYIxeoHA",
  "exp": 1663733399,
  "hashed_login_hint": "76c5a2fa860a42999959f3a095ea04704132d1a007a2f7a88972a3a0e6d43425",
  "iat": 1663732799,
  "iss": "https://idgw.mobileid.mts.ru",
  "nonce": "02bc3068-75f3-4b55-a327-56bbc7a0d863",
  "azp": "mts_test_service",
  "displayed_data": "Подтвердите вход в mts_test_service",
  "auth_time": 1663732799,
  "acr": "2",
  "aud": [
    "mts_test_service"
  ]
}

Заголовок

ПараметрОписаниеОбязательныйПример
algАлгоритм, с помощью которого защищен JWT.ДаRS256
kidИдентификатор ключа, с помощью которого выполнено формирование подписи.Значение совпадает с значением одноименного параметра в публичном ключе с меткой “use”:”sig”, опубликованным на jwks_endpoint.Даrsa1
typТип контента, которым является итоговый токен.ДаJWT

Полезная нагрузка

ПараметрОписаниеОбязательныйПример
subУникальный идентификатор абонента.Да7a716210-f2bf-47b2-ad9c-e6bff1d731a4
amrЗадействованный способ аутентификации:SEAM_OK – Seamless;SIM_OK – push;USSD_OK – USSD;SMS_OTP – SMS.ДаSIM_OK
at_hashЗакодированная при помощи алгоритма base64url первая половина хеш-значения от ASCII представления значения access_tokenДаy4EwJcN5t0WtskY3V1DCEQ
expЦелое число, показывающее время истечения срока действия id_token (в секундах, с 1970, UTC).Да1663733399
hashed_login_hintХэш идентификационных данных пользователя из исходного запроса.Да76c5a2fa860a42999959f3a095ea04704132d1a007a2f7a88972a3a0e6d43425
iatЦелое число, показывающее время, когда id_token был выдан (в секундах, с 1970, UTC).Да1663732799
issИздатель токенаДаhttps://idgw.mobileid.mts.ru
nonceУникальное значение для связи IDToken с исходным запросом авторизации.Да02bc3068-75f3-4b55-a327-56bbc7a0d863
azpИдентификатор ресурса СП, для которого выдан id_token. Нетmts_test_service
displayed_dataДанные, которые были отображены на устройстве пользователя в процессе аутентификацииНетПодтвердите вход в mts_test_service
auth_timeВремя проведения аутентификации пользователя (в секундах, с 1970, UTC).Да1663732799
acrЗадействованный уровень доверия к результатам аутентификации.Да2
audИдентификатор ресурса СП, для которого выдан id_token.Даmts_test_service

Рекомендации по обработке IDtoken

Полезные ссылки:

Связывание пользовательского аккаунта Мобильного ID с учетной записью пользователя на площадке

IDToken содержит уникальный идентификатор абонента (sub), который, при использовании сервиса Мобильный ID для аутентификации, должен использоваться площадкой для связывания его с аккаунтом своего пользователя (по аналогии, например, с googleid).

Мы настоятельно не рекомендуем использовать для этих целей сам номер телефона, т.к. Мобильный ID отслеживает связь номера с физическим лицом и, в случае изменения физического лица – владельца номера телефона, изменяет возвращаемое значение sub для исключения случаев предоставления доступа к “чужому” аккаунту.

Валидация

Перед тем, как использовать представленные в составе IDToken данные, рекомендуется произвести операции по его валидации для исключения негативных последствий в случае возможных атак.

  • Получить публичный ключ, парой которого подписан IDToken, и проверить подпись. Публичные ключи, которые использует сервис Мобильный ID, публикуются на https-ресурсе в формате JWKS. Актуальный адрес публикации ключей содержится в значении параметра “jwks_uri” в составе openid-конфигурации ресурсного сервера. Соответствующую конфигурацию можно получить, используя информацию о издателе токена: “%iss_value%” + “/.well-known/openid-configuration”  – https://idgw.mobileid.mts.ru/.well-known/openid-configuration. Задействованный алгоритм подписи и идентификатор ключа, которым подписан токен, всегда указываются в заголовках токена.
  • Проверить соответствие значения iss базовому URL сервиса Мобильный ID;
  • Проверить наличие параметра azp при наличии массива значений в параметре aud. Если параметр azp присутствует, то его значение должно соответствовать client_id;
  • Проверить, что значение aud содержит значение соответствующее client_id;
  • Проверить, что текущее время меньше значения exp;
  • Проверить, что значение nonce соответствует значению nonce из исходного запроса авторизации;
  • Проверить, что значение acr соответствует одному из представленных значений acr в исходном запросе;
  • Если планируется использовать полученный access_token, то:
    • Проверить, что значение at_hash соответствует значению = закодированная при помощи алгоритма base64url первая половина хеш-значения от ASCII представления значения access_token, где алгоритм хеширования соответствует алгоритму, указанному в хедере токена (RS256 → SHA256, RS512 → SHA512 и т.п.).