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

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

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

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

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

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

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

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

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

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

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

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

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

person TheJediCowboy    schedule 17.08.2015    source источник


Ответы (3)


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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Как?

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

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

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

person qre0ct    schedule 29.03.2016
comment
Это отличный ответ, который вызывает у меня несколько вопросов. Каким образом Боб мог украсть токен доступа, если у него не было доступа к телефону Алисы, а токен был отправлен только по HTTPS? Вы говорите, что для каждого аутентифицированного пользователя (в случае мобильного приложения, как правило) приложению выдается один к одному сопоставленный токен обновления и пара токенов доступа. Означает ли это, что Алиса не может использовать один и тот же токен на своем мобильном телефоне и настольном компьютере? Если так, это было бы практически эквивалентно тому, что Боб использовал бы тот же токен на другой машине, верно? - person nomad; 24.06.2016
comment
@nomad - множество способов взлома токена доступа. 1. Потеря устройства. 2. В приложении была некоторая уязвимость, из-за которой токен передавался другим приложениям на устройстве. 3. Сама базовая версия ОС имеет дыры, может быть, а может и не быть нулевого дня. 4. Пользователь сам анализирует свой собственный трафик (HTTPS на самом деле не поможет) чтобы получить токен доступа и при отсутствии истечения срока действия, используйте токен даже после того, как, скажем, например, ей было запрещено использовать приложение и т. д. Для второго квеста предположите, что для каждого нового устройства весь процесс аутентификации будет повторяться оформить авторизацию. Открыт для обсуждения. - person qre0ct; 27.06.2016
comment
Это довольно хорошее объяснение. У меня есть вопрос: требуется ли для использования токена обновления по-прежнему указывать идентификатор / секрет? Я думаю, что видел примеры, когда секрет передается (точно так же, как вы изначально авторизуете себя) и другие примеры, где требуется только токен обновления. Если секрет не передан, как сервер аутентификации может узнать, как подписать новый действительный токен доступа? Однако, если секрет передан, не потребуется ли для этого какая-то обработка на стороне сервера (например, проверка базы данных) для проверки клиента и секрета? - person georaldc; 20.10.2016
comment
Кроме того, в следующем сценарии: как только Боб (злоумышленник) сделает запрос с новым сгенерированным токеном доступа, поскольку токен доступа Алисы (подлинного пользователя) все еще действителен, сервер будет рассматривать это как аномалию, потому что для однократного обновления токен может быть только один авторизованный токен доступа одновременно, как сервер узнает, что это аномалия? Поскольку срок действия существующего токена доступа еще не истек? Если да, то чем это отличается от законного вызова обновления до истечения срока действия? - person georaldc; 20.10.2016
comment
У авторизованного пользователя есть только один токен доступа и только один токен обновления. Если злоумышленник получает токен обновления и создает другой токен доступа, сервер аутентификации должен обнаружить наличие двух разных токенов доступа для пользователя и отозвать токен обновления и два токена доступа, заставив пользователя снова отправить свои учетные данные, чтобы получить новый токен доступа и новый токен обновления. - person Stephane; 21.08.2018
comment
потому что для одного токена обновления может быть только один авторизованный токен доступа одновременно. Обнаружив аномалию, сервер уничтожил бы токен обновления - это звучит неправильно. Жетоны доступа не могут быть уничтожены, их срок действия истекает. До этого времени они действительны и остаются на стороне клиента. - person aleemb; 22.10.2019
comment
Это отличный ответ. Одна нота. Пользователь Gmail может иметь несколько токенов обновления, потому что у них может быть несколько устройств. Хотя вы абсолютно правы. Один токен обновления нельзя использовать на двух устройствах. - person Honey; 08.03.2020
comment
Что, если Алиса какое-то время не входит в систему, чтобы обновить свой токен доступа? Допустим, Алиса выходит на ночь, и ее токен доступа естественным образом истекает, а ее токен обновления по-прежнему действителен в течение нескольких дней. Не мог ли Боб использовать токен обновления Алисы в этой ситуации для создания нового токена доступа? Поскольку они не являются действительным токеном доступа в паре в БД с токеном обновления из-за естественного истечения срока его действия. Я, вероятно, неправильно понимаю последнюю проверку, но похоже, что единственный способ узнать, получил ли кто-то ваш токен обновления, - это проверить, есть ли ТОЛЬКО действительный токен доступа во время запроса. - person BLang; 23.05.2020
comment
отличный ответ! Один вопрос: для токена доступа и токена обновления, если один был украден, то другой тоже должен быть украден, верно? - person frank; 04.08.2020
comment
Отличный ответ, но если вы разрешаете доступ к нескольким устройствам, аномалия токена обновления, указанная выше, недействительна. - person Gary; 09.08.2020
comment
Должен ли сервер поддерживать состояние токена обновления, чтобы найти аномалию? Если да, то использование токена обновления не является реализацией без сохранения состояния. Это текущее предположение? - person rakib; 10.09.2020
comment
@BLang Я считаю, что это причина, по которой вам следует создавать новый токен обновления каждый раз, когда вы создаете новый токен доступа. В этом случае, если Алиса войдет в систему после истечения срока действия токена доступа Боба, сервер будет знать, что ее токен доступа, возможно, был скомпрометирован, поскольку он отсутствует в базе данных, и он должен аннулировать все токены доступа и обновления для этого пользователя. Тем не менее Боб смог использовать этот ключ для получения несанкционированного доступа. См. Эту ссылку - person Bartosz Popiela; 15.01.2021
comment
Хороший ответ с некоторыми недостатками. Выявив аномалию, сервер уничтожит соответствующий токен обновления, и вместе со всем этим связанные с ним токены доступа также станут недействительными. Это не происходит автоматически. Признание недействительным токена обновления не означает, что токены доступа будут уничтожены. Токены доступа будут аннулированы по истечении срока их действия. поскольку для одного токена обновления может быть только один авторизованный токен доступа одновременно. Можно упреждающе запросить дополнительные токены доступа до истечения срока его действия. Так что это не выглядит правильным. - person bornfree; 03.04.2021
comment
Что касается аномалии, я думаю, что один токен обновления строго привязан к конкретному токену, а не к учетной записи, поэтому, вероятно, у нас может быть несколько активных токенов обновления для одной учетной записи \ - person Anas khan; 08.04.2021

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

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

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

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

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

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

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

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

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

  • Вашему клиенту никогда не нужно проверять время истечения срока действия или делать запросы на обновление токенов, все, что он делает, это проверяет заголовок X-JWT в ответах.
  • Вы можете добавить настраиваемую логику обновления на основе IP-адреса, пользовательского агента, максимального возраста токена или их комбинации.
  • Вы можете отозвать некоторые или все токены для пользователя.
person alexishevia    schedule 20.12.2016
comment
Боковое примечание: если мы делаем запросы CORS, настраиваемый заголовок X-JWT не будет доступен. - person tuler; 08.02.2017
comment
@tuler Если вы хотите предоставить настраиваемый заголовок X-JWT в CORS, вам необходимо включить его в заголовок Access-Control-Expose-Headers. Другой вариант - включить его в тело ответа как метаданные. - person alexishevia; 09.02.2017
comment
Зачем возвращать новый JWT (который, по сути, является копией истекшего JWT? Разве не весь смысл в том, чтобы изменить токен, чтобы дать пользователю новый? - person Nick; 10.07.2019
comment
@alexishevia Зачем возвращать новый JWT (который, по сути, является копией истекшего JWT? Разве весь смысл этого не в том, чтобы изменить токен, чтобы дать пользователю новый? - person Nick; 10.07.2019

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

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

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

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

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

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

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

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

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

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

person aleemb    schedule 22.10.2019
comment
Токены не могут быть уничтожены .. СПАСИБО. Не могу поверить, что за другой ответ было так много голосов. . . Вся суть JWT в том, что вам не нужна база данных, чтобы проверять, какие из них действительны или нет. Он должен быть без гражданства. . - person johnsimer; 27.07.2020
comment
На самом деле, я бы реализовал двойную проверку для доступа администратора. Если isManager истинно, это просто означает проверить базу данных на наличие доступа менеджера. Если флаг ложный, пользователю немедленно отказывают в ресурсе. - person Gary; 09.08.2020