Безопасность API REST Сохраненный токен против JWT против OAuth

104

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

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

Позвольте мне рассказать, как я понимаю все эти вещи. Если я что-то неправильно понимаю, пожалуйста, дайте мне знать.

Поскольку REST API не имеет состояния, а также WEB в целом, нам необходимо отправлять некоторые данные аутентификации в каждом запросе (куки, токен ....). Я знаю три широко используемых механизма аутентификации пользователя

  1. Токен с HTTPS. Я использовал этот подход много раз, он достаточно хорош с HTTPS. Если пользователь предоставит правильный пароль и логин, он получит токен в ответ и будет использовать его для дальнейших запросов. Токен генерируется сервером и сохраняется, например, в отдельной таблице или там же, где хранится информация о пользователе. Таким образом, для каждого сервера запросов проверяется, есть ли у пользователя токен, и он такой же, как в базе данных. Все довольно просто.

  2. JWT Token. Этот токен является информативным, он содержит всю необходимую информацию о самом токене, пользователь не может изменить, например, дату истечения срока действия или любую другую заявку, поскольку этот токен генерируется (подписывается) сервером с секретным ключевым словом. Это тоже понятно. Но одна большая проблема, лично для меня, как аннулировать токен.

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

Рассмотрим мобильный клиент для интернет-магазина.

Первый вопрос: я должен предпочесть JWT токену первого типа? Поскольку мне нужно войти / выйти из системы на мобильном клиенте, мне нужно где-то хранить токен или, в случае JWT, токен должен быть аннулирован при выходе из системы. Для аннулирования токена используются разные подходы. Одним из них является создание списка недействительных токенов (черный список). Хм. Таблица / файл будет иметь гораздо больший размер, чем если бы токен хранился в таблице и был связан с пользователем и был удален при выходе из системы.

Так каковы преимущества токена JWT?

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

CROSP
источник
Спасибо, мне было интересно это недавно. Я пошел с управлением сессиями (Beaker) и удалял токены сессий через час. Оут, казалось, не подходил.
JasTonAChair

Ответы:

86

Рассмотрим первый случай. Каждый клиент получает случайный идентификатор, который длится на протяжении сеанса - который может быть несколько дней, если хотите. Затем вы сохраняете информацию, относящуюся к этому сеансу где-то на стороне сервера. Это может быть в файле или базе данных. Предположим, вы передаете идентификатор через cookie, но можете использовать URL-адрес или заголовок HTTP.

Идентификаторы сессии / файлы cookie

Плюсы:

  • Легко кодировать как клиента, так и сервера.
  • Легко уничтожить сеанс, когда кто-то выходит из системы.

Минусы:

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

JSON Web Tokens (JWT)

Во втором случае данные хранятся в JWT, который передается, а не на сервере.

Плюсы:

  • Проблемы хранения на стороне сервера исчезли.
  • Код на стороне клиента прост.

Минусы:

  • Размер JWT может быть больше, чем идентификатор сеанса. Это может повлиять на производительность сети, поскольку оно включается в каждый HTTP-запрос.
  • Данные, хранящиеся в JWT, читаются клиентом. Это может быть проблемой.
  • На стороне сервера необходим код для генерации, проверки и чтения JWT. Это не сложно, но есть некоторая кривая обучения, и от этого зависит безопасность.

    Любой, кто получит копию ключа подписи, может создать JWT. Вы можете не знать, когда это произойдет.

    Была (есть?) Ошибка в некоторых библиотеках, которые принимали любой JWT, подписанный с помощью алгоритма «none», чтобы любой мог создать JWT, которому сервер доверял бы.

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

OAuth

Часто OAuth используется для аутентификации (т. Е. Идентификации), но его можно использовать для обмена другими данными, такими как список контента, который пользователь приобрел и имеет право на скачивание. Он также может быть использован для предоставления доступа для записи данных, хранящихся третьей стороной. Вы можете использовать OAuth для аутентификации пользователей, а затем использовать серверное хранилище или JWT для данных сеанса.

Плюсы:

  • Нет кода для пользователей, чтобы зарегистрироваться или сбросить свой пароль.
  • Нет кода для отправки электронного письма со ссылкой для проверки и последующего подтверждения адреса.
  • Пользователям не нужно изучать / записывать другое имя пользователя и пароль.

Минусы:

  • Вы зависите от третьей стороны, чтобы ваши пользователи могли пользоваться вашим сервисом. Если их обслуживание выходит из строя или они прекращают его, вам нужно выяснить что-то еще. Например: как вы переносите данные учетной записи пользователя, если их личность меняется с "foo@a.com" на "bar@b.com"?
  • Обычно вы должны написать код для каждого поставщика. например, Google, Facebook, Twitter.
  • Вы или ваши пользователи могут иметь проблемы с конфиденциальностью. Поставщики знают, кто из их пользователей использует ваш сервис.
  • Вы доверяете провайдеру. Поставщик может выдавать токены, действительные для одного пользователя, другому. Это может быть в законных целях или нет.

Разнообразный

  • И идентификаторы сеансов, и JWT могут быть скопированы и использованы несколькими пользователями. Вы можете сохранить IP-адрес клиента в JWT и проверить его, но это не позволяет клиентам перемещаться от Wi-Fi к сотовой связи.
Чед Кларк
источник
Чтобы добавить к своему ответу, oAuth может быть бесполезен, если пользователь хочет зарегистрироваться, используя учетные записи своей компании, которые обычно не связаны или связаны с какими-либо социальными сетями или Google.
Афтаб Навид
5
Я не знаю, почему это принятый ответ? он не отвечает на реальный вопрос, просто реформировать вопрос другим способом
драм
1
Вы говорите: «Данные , сохраненные в JWT читается клиентом Это может быть вопрос .. Почему бы не использовать JWE , если это является проблемой.?
Серебро
Этот ответ смущает яблоки и апельсины. Не следует сравнивать их с OAuth 2.0 (спецификация «авторизация»). О чем нужно знать OP: «Поток паролей владельца ресурса» - это аутентификация как грант.
Онур Йылдырым
5

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

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

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

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

Я сам не думаю, что стоит беспокоиться. Если кто-то перехватывает и декодирует ваши зашифрованные данные https, тогда у вас гораздо большие проблемы.

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

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

Cerad
источник
2
Если вы предполагаете, что некоторые из ваших клиентов являются вредоносными, легко заметить, что сеанс будет скопирован и повторно использован, и вам необходимо противостоять этому на сервере.
Майкл Шоу
1
Плохая идея, это может быть использовано хакером позже, или просто грубым принуждением ...
CROSP
2
Представьте, что пользователь хочет выйти из всех других устройств, использование JWT невозможно.
драмы
@ амд не возможно? Что если я добавлю nonce = (random) и если пользователь выйдет из системы, замените nonce. Кажется простым и эффективным.
Саймон Б.
3

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

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

RibaldEddie
источник
4
Но, опять же, в этом случае он становится заполненным состоянием, поэтому для создания соли или использования любого другого подхода вы можете просто сохранить токен в таблице и удалить его, когда он должен быть признан недействительным
CROSP
2
Вы также можете сделать недействительным в зависимости от времени.
Рибальд Эдди
Какая разница между временем истечения в этом случае? Как сделать токен недействительным в зависимости от времени, когда пользователь хочет выйти из мобильного клиента? Кажется, что в этом случае API не может быть без сохранения состояния. Что является наиболее подходящим и безопасным решением, чем?
CROSP
2
Наиболее подходящим для выхода с одного устройства является обеспечение того, чтобы вы использовали clientId в дополнение к соли. Я предлагаю вам взглянуть на спецификацию токена на предъявителя Oauth-JWT для понимания.
Рибальд Эдди
Спасибо за ответ, но я не понимаю, зачем вообще использовать OAuth в этом случае.
CROSP