Удалить JWT при выходе из приложения Spring

Мы пытаемся следовать этой кодовой базе для нашего приложения на основе Spring REST. пружинно-загрузочные-jwts

Проблема в том, что мы не можем удалить токен JWT во время выхода с сервера. Когда мы проверили в сети, мы узнали, что единственный подход к этому - это внесение в черный список токенов JWT, как указано в этом черном списке. Это так?

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

3 ответа

Длинная история shortнеобходимо создать механизм для удаления или аннулирования токена manually на выходе.

Должен ли я хранить токен JWT или нет?


Вопрос, который вы должны задать себе:

  • Нужно ли хранить токен JWT в базе данных? Если так, то почему?

Приведенный выше вопрос не обязательно решит ваш logout проблема, потому что вам все еще нужен механизм для invalidate токен, который хранится или не хранится в database,

Одно из преимуществ not storing маркер в базе данных заключается в том, что вам не нужно беспокоиться о deleting их когда (без обслуживания или некоторого процесса очистки)

  • Они токен истекает
  • Изменяются их области применения
  • Пользователь (в случае password поток, давайте не будем покрывать другие flows) роли и разрешения понижены или обновлены в базе данных и, следовательно, что внутри jwt устарело
  • Пользователь удален
  • Пользователь вышел из системы (интересно, если это достаточно веская причина для удаления токена)
  • Жетоны скомпрометированы (хитрый)
  • [Добавить другие случаи]

Проверка правильности токена?


Я уверен, что вы используете verify конечная точка, и ее цель состоит в том, чтобы проверить, является ли токен valid или нет, но не обязательно проверять все вышеописанные сценарии, что означает, что вы должны либо

  • Настроить verify рабочий процесс, чтобы добавить больше custom checks ИЛИ ЖЕ
  • До того, как токен verified за signature validity, expiry timeи некоторые другие default checks вы можете запустить свой собственный custom checks и если ваш custom checks прошло, то действуй иначе you shall not pass!

Каковы ваши варианты тогда?


Ну кроме того blacklisting Вы могли бы сделать что-то, как следует

Используйте хранилище в памяти

Просто сохраните uniquely-identifying-metadata токена JWT в Redis в качестве ключа и дать ему expiry time это так же, как JWT время истечения токена, чтобы оно self-destruct когда токен истек.

set key {replace_with_jwt_unique_identifier} ex {jwt_expiry_timestamp}

Риск: Redis хранится в памяти, и записи не сохраняются.

Использовать базу данных

Не используйте Redis или не хотите рисковать. Вы можете использовать базу данных с пользовательской таблицей базы данных. Отдельная таблица, которая либо

  • Связанный с записью JWT и имеет ON DELETE CASCADE
  • Не связано с записью JWT, и вы должны вести ее самостоятельно

При выдаче токена также заполните эту новую таблицу базы данных.

Общие оставшиеся шаги

Когда normal запрос приходит с JWT, используйте JWT для запроса in-memory магазин или database таблица, чтобы увидеть, если запись существует. В случае in-memory хранить простой existence чек более чем достаточно. В случае database table вам нужно сделать больше проверок (т.е. существуют и не просрочены и т. д.), и если проверки прошли, пропустите запрос, иначе you shall not pass!

Когда logout request приходит, в случае in-memory магазин просто удалите key и продолжить (если найден) и в случае database Вы можете удалить JWT запись, которая будет каскадно спускаться к новой таблице.

Когда делать пользовательские проверки?

Ну, вы можете сделать это

  • Прежде всего, используя пользовательский фильтр верхнего уровня или
  • Вы можете расширить verify рабочий процесс конечной точки, чтобы также сделать эти дополнительные проверки

Проекты, с которыми я работаю, не требуют, чтобы токен был признан недействительным logout поэтому мне не пришлось пересекать этот мост. Я должен был расширить verify конечная точка, чтобы убедиться, что токен действителен, если все мои custom checks Прошло.

Дополнительные материалы для чтения

В дополнение к учебнику, который вы указали. Есть некоторые другие вопросы SO, которые также обсуждают аналогичную проблему. Увидеть

Что делать, если JWT украден?
Как уничтожить JWT при выходе?
Подробнее как удалить токен JWT?
Как включить JWT при смене пароля
Github проблема - как сделать недействительным JWT
И, наконец, лучшее для последнего - аннулирование веб-токенов JWT

Мы столкнулись с подобной проблемой и решили ее следующим способом:

  1. Мы добавляем идентификатор запроса к каждому токену JWT вместе со сроком действия.
  2. Когда сеанс создан, мы сохраняем этот идентификатор запроса в базе данных против других значений токена и его срока действия.
  3. Когда сервер инициирует выход из системы, мы помечаем этот запрос как просроченный.
  4. В следующий раз, если используется тот же токен, мы точно знаем, что это токен с истекшим сроком действия, проверив идентификатор запроса.

Теперь проверка идентификатора запроса в базе данных является дорогостоящей, поэтому мы также используем кэш в памяти.

Преимущество токена JWT заключается в том, что он обеспечивает автономный способ безопасной передачи информации между сторонами в виде объекта JSON. Эта информация может быть проверена и надежна, потому что она имеет цифровую подпись.

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

Теперь, если ваше требование состоит в том, чтобы сделать токен недействительным, я предлагаю изучить хранилище JDBC TokenStore, которое предлагает Spring-Security. Таким образом, все выданные токены будут храниться в БД, и вы можете сделать их недействительными, когда пользователь выйдет из вашего приложения. Для этого вы можете предоставить сервис для отзыва токена и соответствующего вызова

@Resource(name="tokenServices")
ConsumerTokenServices tokenServices;

@RequestMapping(method = RequestMethod.POST, value = "/tokens/revoke/{tokenId:.*}")
@ResponseBody
public String revokeToken(@PathVariable String tokenId) {
    tokenServices.revokeToken(tokenId);
    return tokenId;
}

Все ваши серверы ресурсов должны будут выполнить поиск в БД, чтобы проверить правильность токена

Другие вопросы по тегам