Interested Article - JSON Web Token

JSON Web Token ( JWT ) — это открытый стандарт ( ) для создания токенов доступа, основанный на формате JSON . Как правило, используется для передачи данных для аутентификации в клиент-серверных приложениях. Токены создаются сервером, подписываются секретным ключом и передаются клиенту, который в дальнейшем использует данный токен для подтверждения подлинности аккаунта.

История

В 2011 году была сформирована группа JOSE (JSON Object Signing and Encryption group), целью которой была стандартизация механизма защиты целостности, шифрования, а также формата ключей и алгоритмов идентификации для обеспечения совместимости служб безопасности, использующих формат JSON. К 2013 году в открытом доступе появились неофициальные наброски и примеры использования идей данной группы, которые позже стали стандартами RFC : JWT, JWS, JWE, JWK и JWA.

Официально JWT был стандартизован группой IETF в мае 2015 года.

Структура

Токен JWT состоит из трех частей: заголовка (header), полезной нагрузки (payload) и подписи или данных шифрования. Первые два элемента — это JSON-объекты определенной структуры. Третий элемент вычисляется на основании первых и зависит от выбранного алгоритма (в случае использования неподписанного JWT может быть опущен). Токены могут быть перекодированы в компактное представление (JWS/JWE Compact Serialization): к заголовку и полезной нагрузке применяется алгоритм кодирования Base64-URL , после чего добавляется подпись и все три элемента разделяются точками («.»).

К примеру, для заголовка и полезной нагрузки, которые выглядят следующим образом:

{
  "alg": "HS512",
  "typ": "JWT"
}
{
  "sub": "12345",
  "name": "John Gold",
  "admin": true
}

получим следующее компактное представление (переводы строки добавлены для наглядности):

eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9.
eyJzdWIiOiIxMjM0NSIsIm5hbWUiOiJKb2huIEdvbGQiLCJhZG1pbiI6dHJ1ZX0K.
LIHjWCBORSWMEibq-tnT8ue_deUqZx1K0XxCOXZRrBI

Заголовок

В заголовке указывается необходимая информация для описания самого токена.

Обязательный ключ здесь только один:

  • alg: алгоритм, используемый для подписи / шифрования (в случае неподписанного JWT используется значение « none »).

Необязательные ключи:

  • typ: тип токена ( type ). Используется в случае, когда токены смешиваются с другими объектами, имеющими JOSE заголовки. Должно иметь значение « JWT ».
  • cty: тип содержимого ( content type ). Если в токене помимо зарегистрированных служебных ключей есть пользовательские, то данный ключ не должен присутствовать. В противном случае должно иметь значение « JWT »

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

В данной секции указывается пользовательская информация (например, имя пользователя и уровень его доступа), а также могут быть использованы некоторые служебные ключи. Все они являются необязательными:

  • iss: чувствительная к регистру строка или URI , которая является уникальным идентификатором стороны, генерирующей токен ( issuer ).
  • sub: чувствительная к регистру строка или URI, которая является уникальным идентификатором стороны, о которой содержится информация в данном токене ( subject ). Значения с этим ключом должны быть уникальны в контексте стороны, генерирующей JWT.
  • aud: массив чувствительных к регистру строк или URI, являющийся списком получателей данного токена. Когда принимающая сторона получает JWT с данным ключом, она должна проверить наличие себя в получателях — иначе проигнорировать токен ( audience ).
  • exp: время в формате Unix Time , определяющее момент, когда токен станет невалидным ( expiration ).
  • nbf: в противоположность ключу exp, это время в формате Unix Time , определяющее момент, когда токен станет валидным ( not before ).
  • jti: строка, определяющая уникальный идентификатор данного токена ( JWT ID ).
  • iat: время в формате Unix Time , определяющее момент, когда токен был создан. iat и nbf могут не совпадать, например, если токен был создан раньше, чем время, когда он должен стать валидным ( issued at ).

Использование в клиент-серверных приложениях

Access- и refresh-токены

  • Access-токен — это токен, который предоставляет доступ его владельцу к защищённым ресурсам сервера. Обычно он имеет короткий срок жизни и может нести в себе дополнительную информацию, такую как IP-адрес стороны, запрашивающей данный токен.
  • Refresh-токен — это токен, позволяющий клиентам запрашивать новые access-токены по истечении их времени жизни. Данные токены обычно выдаются на длительный срок.

Схема работы

Как правило, при использовании JSON-токенов в клиент-серверных приложениях реализована следующая схема:

  1. Клиент проходит аутентификацию в приложении (к примеру, с использованием логина и пароля).
  2. В случае успешной аутентификации сервер отправляет клиенту access- и refresh-токены.
  3. При дальнейшем обращении к серверу клиент использует access-токен. Сервер проверяет токен на валидность и предоставляет клиенту доступ к ресурсам.
  4. В случае, если access-токен становится невалидным, клиент отправляет refresh-токен, в ответ на который сервер предоставляет два обновлённых токена.
  5. В случае, если refresh-токен становится невалидным, клиент опять должен пройти процесс аутентификации (п. 1).

Преимущества

JWT имеет ряд преимуществ по сравнению с подходом хранения выданных сессий на сервере и в куки на стороне клиента:

  • При использовании JWT не требуется хранение дополнительных данных о выданных сессиях: все, что должен сделать сервер — это проверить подпись.
  • Сервер может не заниматься созданием токенов, а предоставить это внешним сервисам.
  • В JSON-токенах можно хранить дополнительную полезную информацию о пользователях. Как следствие — более высокая производительность. В случае c куки иногда необходимо осуществлять запросы для получения дополнительной информации. При использовании JWT эта информация может быть передана в самом токене.
  • JWT делает возможным предоставление одновременного доступа к различным доменам и сервисам.

Возможные атаки

Удаление подписи

JSON-токен состоит из трех частей, которые кодируются независимо друг от друга. Таким образом, становится возможным удалить подпись из токена и изменить заголовок, сделав JWT неподписанным. Если на сервере не стоит проверка на наличие подписи у токена, то злоумышленник может указывать собственные значения в полезной нагрузке. Проблема решается простым отбрасыванием неподписанных объектов.

CSRF

Одним из методов борьбы с CSRF является добавление специальных заголовков с зашифрованной информацией, подтверждающей отправку запроса с доверенного сервера. Таким образом, если JWT используется не в качестве куки, CSRF-атака становится невозможной.

XSS

JSON-токены могут храниться в браузере двумя способами: в DOM-хранилище или в куки . В первом случае система может быть подвержена XSS -атаке, так как JavaScript имеет доступ к DOM-хранилищу и злоумышленник может извлечь оттуда токен для дальнейшего использования от имени пользователя. При использовании куки можно выставить HttpOnly-флаг, который предотвращает доступ JavaScript к хранилищу. Таким образом, злоумышленник не сможет извлечь токен и приложение становится защищенным от XSS.

JWS

Подписанные JSON-токены описываются JWS-спецификацией ( ).

Поддерживаемые алгоритмы подписи

Подпись заголовка и полезной нагрузки производится следующими алгоритмами:

Обязательный для поддержки всеми реализациями алгоритм:

Рекомендованные алгоритмы:

Также поддерживаются вариации рекомендованных алгоритмов с использованием SHA-384 и SHA-512 соответственно:

  • HS384, HS512
  • RS384 , RS512
  • ES384 , ES512

Аббревиатуры курсивом — названия, использующиеся в JSON-токенах, описанные спецификацией JWA ( )

Структура заголовка

В случае подписанного JWT в заголовок могут быть добавлены дополнительные ключи:

  • jku: URI на набор открытых ключей в JSON-формате, используемых для подписи данного токена ( JSON Web Key Set URL ).
  • jwk: Ключ, используемый для подписи данного токена ( JSON Web Key ).
  • kid: Уникальный идентификатор используемого ключа для случая, когда указывается набор ключей ( Key ID).
  • x5u : URI на набор сертификатов X.509 . Первый сертификат в наборе должен являться тем, который использовался для подписи данного токена ( X.509 URL) .
  • x5c: Массив сертификатов X.509 в формате JSON, использованных для подписи данного токена ( X.509 certifcate chain) .
  • x5t: Цифровой отпечаток SHA1 сертификата X.509 ( X.509 certificate SHA-1 fingerprint).
  • crit: Массив строк с названиями ключей данного заголовка, которые должны обрабатываться парсером JWT. Если должны быть обработаны все ключи, то не используется ( critical ).

Реализации

Реализации JWT существуют в следующих языках программирования и фреймворках: Clojure , .NET , Go , Haskell , Python , Java , JavaScript , Lua , Perl , PHP , Ruby , Rust , Scala , D , Erlang , Common Lisp и Elixir .

Примечания

  1. (англ.) . auth0.com. Дата обращения: 11 декабря 2017. 15 июля 2018 года.
  2. Bradley, John, Sakimura, Nat, Jones, Michael. (англ.) . tools.ietf.org. Дата обращения: 20 декабря 2017. 16 июня 2019 года.
  3. Bradley, John, Sakimura, Nat, Jones, Michael. (англ.) . tools.ietf.org. Дата обращения: 20 декабря 2017. 16 июня 2019 года.
  4. (англ.) . auth0.com. Дата обращения: 20 декабря 2017. 15 июля 2018 года.
  5. Ryan Boyd. . — O'Reilly media, 2012. — С. .
  6. (англ.) . auth0.com. Дата обращения: 21 декабря 2017. 15 июля 2018 года.
  7. Justin Richer and Antonio Sanso. OAuth 2 in Action. — Manning Publications, 2017. — С. 252—253. — 360 с. — ISBN 9781617293276 .
  8. (англ.) . auth0.com. Дата обращения: 21 декабря 2017. 15 июля 2018 года.
  9. (англ.) . auth0.com. Дата обращения: 21 декабря 2017. 15 июля 2018 года.
  10. (англ.) . auth0.com. Дата обращения: 20 декабря 2017. 15 июля 2018 года.
  11. Bradley, John, Sakimura, Nat, Jones, Michael. (англ.) . tools.ietf.org. Дата обращения: 20 декабря 2017. 16 июня 2019 года.
  12. Bradley, John, Sakimura, Nat, Jones, Michael. (англ.) . tools.ietf.org. Дата обращения: 20 декабря 2017. 12 сентября 2017 года.
  13. auth0.com. (англ.) . jwt.io. Дата обращения: 20 декабря 2017. 25 октября 2017 года.

Ссылки

  • — specialized website about JWT with tools and documentation, maintained by
  • - IETF official website
  • - JWT Handbook by Sebastián Peyrott
Источник —

Same as JSON Web Token