Я разрабатывал приложение, которое будет поддерживать многих пользователей. Дело в том, что я не могу понять, как аутентифицировать клиента / пользователя.
Я создаю приложение, такое как http://quickblox.com/, где я предоставляю учетные данные своим пользователям, и они будут использовать их для создания N приложений, в которых они не смогут ввести свое имя пользователя и пароль для аутентификации.
Давайте предположим, что это идет следующим образом. (Так же, как QuickBlox)
1. Пользователь создает учетную запись на моем сайте.
2. Пользователь может создавать N API ключей и секретных учетных данных. (Для нескольких приложений)
3. Пользователь будет использовать эти учетные данные в своих приложениях (Android, iOS, Javascript и т. Д.), Чтобы общаться с моими REST API.
(API REST имеют доступ для чтения и записи.)
Моя забота?
Пользователи будут помещать свои учетные данные (ключ API и секретный ключ) в создаваемые ими приложения. Что если кто-то получит эти ключи и попытается имитировать пользователя? (Декомпилируя APK или напрямую просматривая код JavaScript.
Я где то не прав?
Я запутался, чтобы спроектировать этот трехуровневый пользовательский механизм.
Ответы:
Последние несколько лет я разрабатывал REST API. Вы слишком беспокоитесь. Недавно другой пользователь на этом форуме задал вопрос, где он беспокоился о сохранении конечных точек URI в своем клиентском коде JavaScript .
К вам применяются те же правила, что и к разработчику JavaScript. Если вы позволяете сторонним разработчикам интегрировать ваш API, ваш API будет отображаться так же, как обычный веб-сайт, и вы должны обращаться с ним точно так же.
Цитата из оригинального ответа:
Вы должны спроектировать токены доступа вашего приложения, чтобы разрешить только те операции, которые вы хотите разрешить. У вас может быть два типа токенов доступа:
Но что кто-то деконструирует исходный код, извлекает токены из приложения, узнает, что такое публичные конечные точки, и использует ваш веб-сервис?
Если вы непосредственно не управляете разработкой приложений, использующих ваш API, ничто на самом деле не запрещает людям злоупотреблять вашим API таким же образом непосредственно из приложения.
источник
filtered data
(B) только своего пользователя . Теперь это возможно, или есть ли обходной путь, чтобы третий пользователь не мог украсть все данные (A + B) моего пользователя . Имеет ли это смысл?Ваша проблема не столько техническая, сколько деловая.
Допустим, у вас есть API, который вы продаете своим клиентам (разработчикам приложений) по фиксированной ставке 100 фунтов стерлингов в год, неограниченный доступ.
Ну тогда, очевидно, я могу купить вашу услугу за 100 фунтов и продать ее 10 людям по 50 долларов каждая. Вы этого не хотите! поэтому вы пытаетесь придумать ограничение, которое позволит вам продавать свой API без возможности его арбитража.
Если вы просто ограничите количество приложений, клиент может создать одно приложение, которое будет принимать соединения от других приложений и передавать их.
Если вы ограничите количество пользователей, клиент снова сможет скрыть пользователей за своей собственной аутентификацией и выглядеть как одиночный пользователь.
Что вам нужно сделать, это передать стоимость каждого вызова API для вашего клиента. т.е. плата за вызов API или установить квоту вызовов в год.
Это выдвигает ту же проблему арбитража на ваших клиентов. Это вынуждает их принимать меры для предотвращения кражи ключей пользователями. В этом случае вы прячете свой API-интерфейс за собственным API-интерфейсом, прошедшим аутентификацию.
источник
Все остальные ответы, похоже, предполагают, что проблема хранения секрета в приложении на пользовательских устройствах не решаема.
Конечно да.
Два принципа (подробности реализации будут следовать):
Учитывая, что, если клиент делает запрос к конечной точке аутентификации с учетными данными, а сервер аутентифицирует его, сервер может сгенерировать динамический временный токен (временное значение на основе времени). Этот токен должен быть запомнен в клиенте и отправлен с последующими запросами.
Вам понадобится механизм, чтобы периодически «обновлять» токен, то есть получать новый. Просто создайте конечную точку REST, которая позволяет генерировать новый токен из существующего, чтобы избежать необходимости повторной аутентификации из учетных данных.
Если вы пытаетесь избежать повторной аутентификации конечного пользователя, тогда эта аутентификация может быть первоначальной единовременной установкой в приложении при его установке.
Это решение просто избавляет от необходимости хранить статический токен, встроенный в двоичный файл приложения. Токен генерируется на лету сервером только в ответ на успешную аутентификацию. Чтобы злоумышленник проверил ваше приложение и попытался получить несанкционированный доступ к API, ему все равно нужно было бы пройти аутентификацию, как и все остальные.
источник
Если у вас есть уникальные ключи для каждого приложения, вы можете использовать их только во время первоначальной аутентификации соединения, инициированной клиентом, после чего вы переключаетесь на непрерывный уникальный маркер аутентификации для каждого приложения.
Ваш сервер время от времени меняет (катит) токен для каждого клиентского приложения (например, периодически плюс / минус некоторая случайная нечеткая / случайная задержка). Скользящий токен известен только между сервером и аутентифицированным клиентом.
Новые жетоны возвращаются в виде регулярных ответов. Всякий раз, когда ответ содержит новый токен, принимающее приложение должно переключиться на использование его в последующих запросах.
Всякий раз, когда обмен с клиентом выходит из синхронизации (какая-то ошибка протокола), ваш сервер будет запрашивать повторную аутентификацию (через ответ об ошибке на следующий клиентский запрос, или в сочетании с действительным ответом на клиентский запрос, для пример).
Первоначальная аутентификация, инициированная клиентами, когда активно используется скользящий токен, должна восприниматься с подозрением - это вполне может быть попыткой подражания. Я бы допустил это только в том случае, если обмен переходит в режим ожидания в течение более длительного, чем ожидалось, интервала, который может, например, быть вызван отключением / перезапуском клиента с новым экземпляром, у которого нет текущего маркера.
Было бы еще лучше сохранить маркер на стороне клиента, чтобы перезапущенный клиент мог продолжить работу с того места, где ушел его предшественник, что значительно сужает отверстие для имитации.
Такая схема сделала бы подражание, по крайней мере, довольно трудным - клиент подражания должен был бы точно предсказать окно, когда авторизованный клиент прекратит посылать запросы достаточно долго, чтобы сервер мог решить, что можно принять новую аутентификацию клиента с заданным ключом. Такие запросы за пределами разрешенного окна могут использоваться как обнаружение попыток подражания и, возможно, инициировать некоторые контрмеры (внесение в черный список IP и т. Д.).
источник
Из того, что я знаю, то, что вы упомянули, является единственным способом сделать это. Приложение, хранящее ключ, безусловно, представляет собой риск, но существуют различные способы его обойти. Вы всегда можете использовать хранилище ключей для хранения ключа, чем жесткое кодирование, тем самым форсируя одноразовый вход в систему.
Кроме того, вы должны рассмотреть возможность привязки ключа к клиенту, поэтому, если кто-то имитирует, у вас должен быть уровень безопасности для проверки клиента, ключа и пользовательских агентов для немедленной блокировки запроса. Имейте сценарий использования, чтобы переиздать или заверить, что ключи не имитируются.
источник
Если вы зависите от предоставления токенов авторизации своим клиентам для добавления в свои приложения, теоретически всегда будет кто-то, кто сможет перепроектировать приложение и извлечь их. Чтобы предотвратить это, вам нужен механизм, который не требует секрета в клиентском приложении. Это сложно. Я могу предложить несколько вариантов для размышления.
У вас возникли проблемы после выдачи учетных данных, вы не можете контролировать, насколько надежно они хранятся. Кроме того, если вам требуется, чтобы пользователь отправил вам учетные данные, тогда кто-то может MITM-соединение и напрямую украсть токены, не беспокоясь об обратном проектировании приложения.
Один из способов усложнить извлечение вашего токена авторизации - это запутать его. Это просто поднимает планку, но не делает это невозможным, и для этого вам нужно сохранить контроль над секретом. Вы могли бы реализовать библиотеку, которая содержит секретную информацию и специфична для каждого клиента. Вы можете использовать библиотеку для связи с вашими серверами, и вам даже не придется сообщать пользователю секретную информацию, она может быть просто встроена в библиотеку. Это не решает проблему того, как кто-то обратный инжиниринг вашей библиотеки, но дает вам контроль над уровнем запутывания. Недостатком является то, что, как только один человек нарушил запутывание в библиотеке, он может атаковать любую вашу библиотеку, если вы не напишите код, который существенно отличает каждую библиотеку. Это создает свой собственный набор проблем.
Это может немного отклоняться от объема вашего вопроса, но это связано с безопасностью вашего токена, поэтому я упомяну об этом. Чтобы предотвратить тривиальную кражу токена по сети, вы, вероятно, не хотите отправлять токен напрямую, вместо этого вы можете подписать трафик, используя функцию HMAC. Вы можете проверить достоверность сообщения, рассчитав HMAC сообщения на сервере и сравнив его с HMAC, отправленным клиентом. Вы можете использовать токен в качестве ключа для функции HMAC, чтобы только тот, кто знает токен, мог подписывать трафик. Это лучше для безопасности вашего токена, потому что вы никогда не отправляете его напрямую на сервер, поэтому его нельзя перехватить и украсть напрямую. Для получения дополнительной информации о HMACS см. Этот вопрос: /security/20129/how-and-when-do-i-use-hmac/20301
Ни одно решение по обеспечению безопасности не будет неприступным, вам нужно решить, сколько это будет стоить для реализации, в зависимости от вероятности и стоимости взлома.
источник
Цитирую себя:
Это немного противоречит, не так ли? ;)
Как говорили другие, вы не можете. Если приложение использует ключ API, его можно декомпилировать, как вы говорите, чтобы получить ключ (ы) и использовать его тоже.
Помимо необходимости дополнительной надлежащей аутентификации пользователя, вы можете ограничить только ущерб:
источник