JSON Web Token
JSON Web Token (JWT) — открытый стандарт (RFC 7519) для создания токенов доступа, основанный на формате JSON. Как правило, используется для передачи данных после аутентификации в клиент-серверных приложениях. Токены создаются сервером, подписываются секретным ключом и передаются клиенту, который в дальнейшем использует данный токен для подтверждения подлинности аккаунта.
История
В 2011 году была сформирована группа JOSE (JSON Object Signing and Encryption group), целью которой была стандартизация механизма защиты целостности, шифрования, а также формата ключей и алгоритмов идентификации для обеспечения совместимости служб безопасности, использующих формат JSON. К 2013 году в открытом доступе появились неофициальные наброски и примеры использования идей данной группы, которые позже стали стандартами RFC: JWT, JWS, JWE, JWK и JWA.
Официально JWT был стандартизован группой IETF в мае 2015 года.[1]
Структура
Токен 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»[2]
Полезная нагрузка
В данной секции указывается пользовательская информация (например, имя пользователя и уровень его доступа), а также могут быть использованы некоторые служебные ключи. Все они являются необязательными:
- iss: чувствительная к регистру строка или URI, которая является уникальным идентификатором стороны, генерирующей токен (issuer).
- sub: чувствительная к регистру строка или URI, которая является уникальным идентификатором стороны, о которой содержится информация в данном токене (subject). Значения с этим ключом должны быть уникальны в контексте стороны, генерирующей JWT.
- aud: массив чувствительных к регистру строк или URI, являющийся списком получателей данного токена. Когда принимающая сторона получает JWT с данным ключом, она должна проверить наличие себя в получателях — иначе проигнорировать токен (audience).
- exp: время в формате Unix Time, определяющее момент, когда токен станет невалидным (expiration).
- nbf: в противоположность ключу exp, это время в формате Unix Time, определяющее момент, когда токен станет валидным (not before).
- jti: строка, определяющая уникальный идентификатор данного токена (JWT ID).[3]
- iat: время в формате Unix Time, определяющее момент, когда токен был создан. iat и nbf могут не совпадать, например, если токен был создан раньше, чем время, когда он должен стать валидным (issued at).
Использование в клиент-серверных приложениях
Access- и refresh-токены
- Access-токен — это токен, который предоставляет доступ его владельцу к защищённым ресурсам сервера. Обычно он имеет короткий срок жизни и может нести в себе дополнительную информацию, такую как IP-адрес стороны, запрашивающей данный токен.
- Refresh-токен — это токен, позволяющий клиентам запрашивать новые access-токены по истечении их времени жизни. Данные токены обычно выдаются на длительный срок.
Схема работы
Как правило, при использовании JSON-токенов в клиент-серверных приложениях реализована следующая схема:
- Клиент проходит аутентификацию в приложении (к примеру, с использованием логина и пароля).
- В случае успешной аутентификации сервер отправляет клиенту access- и refresh-токены.
- При дальнейшем обращении к серверу клиент использует access-токен. Сервер проверяет токен на валидность и предоставляет клиенту доступ к ресурсам.
- В случае, если access-токен становится не валидным, клиент отправляет refresh-токен, в ответ на который сервер предоставляет два обновлённых токена.
- В случае, если refresh-токен становится не валидным, клиент опять должен пройти процесс аутентификации (п. 1).[4]
Преимущества
JWT имеет ряд преимуществ по сравнению с подходом хранения выданных сессий на сервере и в куки на стороне клиента:
- При использовании JWT не требуется хранение дополнительных данных о выданных сессиях: все, что должен сделать сервер — это проверить подпись.
- Сервер может не заниматься созданием токенов, а предоставить это внешним сервисам.
- В JSON-токенах можно хранить дополнительную полезную информацию о пользователях. Как следствие — более высокая производительность. В случае c куки иногда необходимо осуществлять запросы для получения дополнительной информации. При использовании JWT эта информация может быть передана в самом токене.[5]
- JWT делает возможным предоставление одновременного доступа к различным доменам и сервисам.[6][7]
Возможные атаки
Удаление подписи
JWT-токен состоит из трёх частей, которые кодируются независимо друг от друга. Таким образом, становится возможным удалить подпись из токена и изменить заголовок, сделав JWT неподписанным. Если на сервере не стоит проверка на наличие подписи у токена, то злоумышленник может указывать собственные значения в полезной нагрузке. Проблема решается простым отбрасыванием неподписанных объектов.[8]
CSRF
Одним из методов борьбы с CSRF является добавление специальных заголовков с зашифрованной информацией, подтверждающей отправку запроса с доверенного сервера. Таким образом, если JWT используется не в качестве cookie, CSRF-атака становится невозможной.[9]
XSS
JSON-токены могут храниться в браузере двумя способами: в DOM-хранилище или в cookie. В первом случае система может быть подвержена XSS-атаке, так как JavaScript имеет доступ к DOM-хранилищу и злоумышленник может извлечь оттуда токен для дальнейшего использования от имени пользователя. При использовании cookie можно выставить HttpOnly-флаг, который предотвращает доступ JavaScript к хранилищу. Таким образом, злоумышленник не сможет извлечь токен и приложение становится защищенным от XSS.[10]
JWS
Подписанные JSON-токены описываются JWS-спецификацией (RFC 7515).
Поддерживаемые алгоритмы подписи
Подпись заголовка и полезной нагрузки производится следующими алгоритмами:
Обязательный для поддержки всеми реализациями алгоритм:
Рекомендованные алгоритмы:
Также поддерживаются вариации рекомендованных алгоритмов с использованием SHA-384 и SHA-512 соответственно:
- HS384, HS512
- RS384, RS512
- ES384, ES512
Аббревиатуры курсивом — названия, использующиеся в JSON-токенах, описанные спецификацией JWA (RFC 7518)[11]
Структура заголовка
В случае подписанного 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).[12]
Реализации
Реализации JWT существуют в следующих языках программирования и фреймворках: Clojure, .NET, Go, Haskell, Python, Java, JavaScript, Lua, Perl, PHP, Ruby, Rust, Scala, D, C++, Delphi, Erlang, Common Lisp и Elixir.[13]
Примечания
- ↑ JWT Handbook v0.13.0, с.6-7 (англ.). auth0.com. Дата обращения: 11 декабря 2017. Архивировано 15 июля 2018 года.
- ↑ Bradley, John, Sakimura, Nat, Jones, Michael. JSON Web Token (JWT), с. 11 (англ.). tools.ietf.org. Дата обращения: 20 декабря 2017. Архивировано 16 июня 2019 года.
- ↑ Bradley, John, Sakimura, Nat, Jones, Michael. JSON Web Token (JWT), c. 9-10 (англ.). tools.ietf.org. Дата обращения: 20 декабря 2017. Архивировано 16 июня 2019 года.
- ↑ JWT Handbook v0.13.0, c. 18 (англ.). auth0.com. Дата обращения: 20 декабря 2017. Архивировано 15 июля 2018 года.
- ↑ Ryan Boyd. Getting Started with OAuth 2.0. — O'Reilly media, 2012. — С. 56.
- ↑ JWT Handbook v0.13.0, с. 9-11 (англ.). auth0.com. Дата обращения: 21 декабря 2017. Архивировано 15 июля 2018 года.
- ↑ Justin Richer and Antonio Sanso. OAuth 2 in Action. — Manning Publications, 2017. — С. 252—253. — 360 с. — ISBN 9781617293276.
- ↑ JWT Handbook v0.13.0, с. 9 (англ.). auth0.com. Дата обращения: 21 декабря 2017. Архивировано 15 июля 2018 года.
- ↑ JWT Handbook v0.13.0, с. 10 (англ.). auth0.com. Дата обращения: 21 декабря 2017. Архивировано 15 июля 2018 года.
- ↑ JWT Handbook v0.13.0, с. 11-12 (англ.). auth0.com. Дата обращения: 20 декабря 2017. Архивировано 15 июля 2018 года.
- ↑ Bradley, John, Sakimura, Nat, Jones, Michael. JSON Web Token (JWT), с. 16 (англ.). tools.ietf.org. Дата обращения: 20 декабря 2017. Архивировано 16 июня 2019 года.
- ↑ Bradley, John, Sakimura, Nat, Jones, Michael. JSON Web Signature (JWS), c. 9-14 (англ.). tools.ietf.org. Дата обращения: 20 декабря 2017. Архивировано 12 сентября 2017 года.
- ↑ auth0.com. JWT.IO (англ.). jwt.io. Дата обращения: 20 декабря 2017. Архивировано 25 октября 2017 года.
Ссылки
- jwt.io — specialized website about JWT with tools and documentation, maintained by Auth0
- IETF official website
- JWT Handbook by Sebastián Peyrott
Content Disclaimer
Informasi ini disarikan dari Wikipedia dan disajikan kembali untuk tujuan edukasi. Konten tersedia di bawah lisensi CC BY-SA 3.0. Kami tidak bertanggung jawab atas ketidakakuratan data yang bersumber dari kontribusi publik tersebut.
- The information displayed on this website is sourced in part or in whole from Wikipedia and has been adapted for the purpose of restating it. We strive to provide accurate and relevant information, however:
- There is no guarantee of absolute accuracy. Wikipedia is an open, collaborative project that can be edited by anyone, so information is subject to change.
- It is not intended to constitute professional advice. The content displayed is for informational and educational purposes only. For important decisions (e.g., medical, legal, or financial), please consult a professional.
- Content copyright. Wikipedia is licensed under the Creative Commons Attribution-ShareAlike License (CC BY-SA). This means that content may be reused with appropriate attribution and shared under a similar license.
- Responsible use. Any risk arising from the use of information from this website is entirely the responsibility of the user.