Действительно ли необходимо обновить токен при использовании аутентификации токена JWT?

Я ссылаюсь на другой пост SO, в котором обсуждается использование токенов обновления с JWT.

JWT (JSON Web Token) автоматическое продление срока действия

У меня есть приложение с очень распространенной архитектурой, где мои клиенты (веб и мобильные) общаются с REST API, который затем общается с уровнем обслуживания и уровнем данных.

введите описание изображения здесь

Я понимаю аутентификацию токенов JWT, но меня немного смущает вопрос о том, как использовать токены обновления.

Я хочу, чтобы моя аутентификация JWT имела следующие свойства:

  1. Срок действия токена JWT составляет 2 часа.

  2. Токен обновляется клиентом каждый час.

  3. Если токен пользователя не обновлен (пользователь неактивен, а приложение не открыто) и срок его действия истечет, ему необходимо будет войти в систему всякий раз, когда он захочет возобновить работу.

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

Мои вопросы следующие:

  1. Если бы я БЫЛ использовать токен обновления, разве не было бы выгодно иметь долгосрочный срок годности для хорошей практики на этом токене?
  2. Если бы я использовал токен обновления, этот токен был бы сохранен с токеном userId и / или JWT?
  3. Когда я обновляю свой токен каждые 1 час, как это работает? Я хочу создать конечную точку, которая будет использовать мой токен JWT или мой токен обновления? Будет ли это обновлять дату истечения срока действия моего исходного токена JWT или создавать новый токен?
  4. Есть ли необходимость в токене обновления, учитывая эти детали? Похоже, что если пользователь просто использует токен JWT для получения нового токена (по ссылке выше), то токен обновления устарел.

4 ответа

Позвольте мне перейти к вашим вопросам чуть позже и начать с обсуждения сути всей цели обновления маркера.

Итак, ситуация такова:

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

Теперь, чтобы решить эту проблему, нам нужен способ узнать, что запросы поступают от авторизованного пользователя. Итак, мы сделали то, что назвали токен доступа. Поэтому теперь, когда пользователь успешно прошел аутентификацию, ему выдается токен доступа. Этот токен должен быть длинным и очень случайным токеном (чтобы его нельзя было угадать). Это где JWT входит в картину. Теперь вы можете (а можете и не захотеть) хранить какие-либо данные о пользователе в токене JWT. В идеале вы хотели бы просто хранить очень простые, чрезвычайно нечувствительные детали в JWT. Об манипулировании хешем JWT для получения других данных пользователя (IDOR и т. Д.) Занимается сама JWT (используемая библиотека).

Итак, на данный момент наша проблема авторизованного доступа решена.

Теперь поговорим о сценарии атаки. Допустим, используя всех вышеперечисленных пользователей, Алиса, используя приложение, имеет авторизованный токен доступа, и теперь ее приложение может отправлять запросы всем API и получать данные в соответствии с ее авторизацией.

Предположим, что НЕКОТОРЫЕ Алиса теряет токен доступа или, другими словами, противник Боб получает доступ к токену доступа Алисы. Теперь Боб, несмотря на то, что он не авторизован, на самом деле может отправлять запросы всем API, для которых Алиса была авторизована.

ЧТО-ТО МЫ ИДЕАЛЬНО НЕ ХОТИМ.

Теперь решение этой проблемы:

  1. Либо обнаружите, что происходит нечто подобное.
  2. Уменьшите само окно атаки.

Используя только один токен доступа, трудно выполнить условие 1, описанное выше, потому что, будь то Алиса или Боб, используется один и тот же авторизованный токен, и, следовательно, запросы от двух пользователей не различимы.

Поэтому мы пытаемся достичь значения 2 выше и, следовательно, добавляем срок действия к токену доступа, скажем, токен доступа действителен в течение "t" (недолгого) времени.

Как это помогает? Ну, даже если у Боба есть токен доступа, он может использовать его только до тех пор, пока он не станет действительным. Как только он истечет, ему придется вернуть его снова. Теперь, конечно, вы можете сказать, что он может получить это так же, как в первый раз. Но опять же, нет ничего лучше, чем 100% безопасность!

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

Решение: здесь появляется токен обновления. Это снова случайный непредсказуемый токен, который также выдается приложению вместе с токеном доступа в первую очередь. Этот токен обновления является очень долгоживущим специальным токеном, который гарантирует, что по истечении срока действия токена доступа он запрашивает у сервера новый токен доступа, что устраняет необходимость повторного ввода учетных данных для входа в систему для получения новый авторизованный токен доступа после истечения срока действия существующего.

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

Как?

Для каждого аутентифицированного пользователя (как правило, в случае мобильного приложения) приложению выдается пара сопоставленных токенов обновления и токена доступа один к одному. Таким образом, в любой данный момент времени для одного аутентифицированного пользователя будет только один токен доступа, соответствующий токену обновления. Теперь предположим, что если бы Боб скомпрометировал токен обновления, он использовал бы его для создания токена доступа (потому что токен доступа - это единственное, что авторизовано для доступа к ресурсам через API). Как только Боб (злоумышленник) делает запрос с вновь сгенерированным токеном доступа, поскольку токен доступа Алисы (подлинного пользователя) все еще действителен, сервер увидит это как аномалию, поскольку для одного токена обновления может быть только один авторизованный токен. токен доступа одновременно. Выявив аномалию, сервер уничтожит соответствующий токен обновления, и вместе с ним все связанные с ним токены доступа также будут признаны недействительными. Таким образом, предотвращение любого дальнейшего доступа, подлинного или злонамеренного, к любой авторизации, требующей ресурсов. Пользователь, Алиса, должен был бы еще раз подтвердить подлинность с ее учетными данными и получить действительную пару маркеров обновления и доступа.

Конечно, вы все еще можете утверждать, что Боб может снова получить доступ как к обновлению, так и к токенам доступа, и повторить весь рассказ выше, что потенциально может привести к DoS на Алисе, действительном подлинном клиенте, но опять же, нет ничего лучше 100% безопасности.

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

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

Вот как это будет работать:

  1. Когда ваш пользователь входит в систему с учетными данными (имя пользователя / пароль), вы возвращаете недолговечный JWT. Вы также создаете запись БД, в которой храните:

    • JWT ID
    • Идентификатор пользователя
    • айпи адрес
    • пользовательский агент
    • valid флаг (по умолчанию TRUE)
    • создан в
    • updatedAt
  2. Ваш клиент отправляет JWT в каждом запросе. Пока JWT не истек, у него есть доступ к ресурсам. Если срок действия JWT истек, вы обновляете его за кулисами и возвращаете как ресурс, так и дополнительный X-JWT заголовок с новым JWT.

  3. Когда клиент получает ответ с X-JWT заголовок, он отбрасывает старый JWT и использует новый для будущих запросов.

Как работает обновление JWT на сервере

  1. Найдите соответствующую запись в БД, используя идентификатор JWT.
  2. Проверьте, если valid флаг все еще true, в противном случае отклонить.
  3. При желании вы можете сравнить IP-адрес запроса и пользовательский агент с сохраненным IP-адресом и пользовательским агентом и принять решение отклонить, если что-то выглядит подозрительно.
  4. При желании вы можете проверить поля createAt или updatedAt записи БД и принять решение не обновлять, если прошло слишком много времени.
  5. Обновите updatedAt поле в записи БД.
  6. Вернуть новый JWT (который в основном является копией JWT с истекшим сроком действия, но с увеличенным сроком действия).

Этот дизайн также даст вам возможность отозвать все токены для пользователя (например, если пользователь потеряет свой телефон или обновит свой пароль).

Выгоды:

  • Ваш клиент никогда не должен проверять время истечения или обновлять запросы токенов, все, что он делает, это проверяет X-JWT заголовок по ответам.
  • Вы можете добавить пользовательскую логику обновления, основанную на IP-адресе, пользовательском агенте, максимальном возрасте токена или их комбинации.
  • Вы можете отозвать некоторые или все токены для пользователя.

Если бы я БЫЛ использовать токен обновления, разве не было бы выгодно иметь длительный срок действия для хорошей практики и с этим токеном?

Жетоны обновления долговечны, жетоны доступа недолговечны.

Если я БЫЛ использовать токен обновления, будет ли этот токен сохраняться с userId и / или токеном JWT?

Он будет сохраняться как отдельный токен на клиенте вместе с JWT, но не внутри JWT. UserID/UID может храниться внутри самого токена JWT.

Когда я обновляю свой токен каждые 1 час, как это работает? Я хочу создать конечную точку, которая принимает мой токен JWT или токен обновления? Обновит ли это дату истечения срока действия моего исходного токена JWT или создаст новый токен?

Да, вам нужен отдельный сервис, который выдает и обновляет токены. Он не обновит срок действия существующего токена JWT. Токен - это просто пары значений поля JSON, закодированные в base64. Таким образом, изменение данных изменяет вывод. У токена также есть дата выпуска, которая будет как минимум изменяться при каждой новой проблеме (обновлении). Так что каждый токен будет уникальным и новым. Срок действия старых токенов истечет автоматически, поэтому вам нужно истечь срок действия всех токенов доступа, иначе они останутся навсегда.

Другой ответ здесь гласит, что старые токены уничтожаются, когда вы выпускаете новый токен. Это просто не так. Жетоны нельзя уничтожить. Фактически, вы можете собирать сотни токенов, постоянно связываясь с сервером аутентификации и запрашивая новые свежие токены, используя свой токен обновления. Каждый из этих токенов доступа будет действителен до истечения срока их действия. Так что истечение срока действия обязательно, и оно должно быть коротким.

Действительно ли нужен токен обновления, учитывая эти детали? Кажется, что если пользователь просто использует токен JWT для получения нового токена (по ссылке выше), то токен обновления устарел.

У токенов JWT есть претензии клиентов. Напримерis_manager:trueЗаявка на токен JWT может разрешить доступ к функциям уровня менеджера. Теперь, если вы решите понизить роль пользователя с менеджера до подрядчика, это не вступит в силу немедленно. Пользователь все еще может использовать старый токен. Наконец, когда это истекает, он обращается к серверу аутентификации, чтобы обновить свой токен. Сервер аутентификации выдает новый токен без запроса на управление, и пользователь больше не сможет получить доступ к функциям управления. Это создает окно, в течение которого утверждения пользователя не синхронизируются с сервером. Это еще раз объясняет, почему токены доступа должны быть недолговечными, чтобы синхронизация могла происходить часто.

По сути, вы обновляете проверки авторизации каждые 15 минут, вместо того, чтобы проверять их при каждом запросе (как обычно работает аутентификация на основе сеанса). Если вам нужны разрешения в реальном времени, а не обновления каждые 15 минут, то JWT может не подойти.

Зависит от сценария

Анатомия JWT


  • Должен содержать неконфиденциальную информацию
  • Должен иметь временной интервал
  • Должен иметь уникальный ключ

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

С сохранением состояния (безопасность) и без сохранения состояния (удобство и производительность)

Токены с отслеживанием состояния

Вы хотите сохранить состояние своих токенов на случай, если они утекут или попадут в чужие руки. Существуют разные желания сохранить состояние токенов.

  • Белый список: сохраните идентификатор токена в базе данных или системе кэширования, напримерили, с настройкой времени автоматического выселения. Каждый раз, когда вы получаете запрос, вы проверяете токен, а затем проверяете хранилище на наличие соответствующегоценить. Если не найден, отклоните запрос. Это дает вам больший контроль над токеном. Вы можете отозвать токены в любой момент, удалив их из хранилища. Но, как видите, при посещении хранилища по каждому запросу могут возникнуть накладные расходы.

  • Черный список: навсегда сохраните идентификаторы токенов в каком-либо постоянном хранилище, и если идентификатор токена будет найден там, отклоните токен.

Токены без гражданства

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

Поток аутентификации


Одиночный токен: токен доступа

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

Несколько токенов: токен доступа и обновления

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

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

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