Создание API для мобильных приложений - Аутентификация и Авторизация - PullRequest
185 голосов
/ 19 октября 2010

Обзор

Я ищу, чтобы создать (REST) ​​API для моего приложения.Первоначальное / основное назначение будет предназначаться для мобильных приложений (iPhone, Android, Symbian и т. Д.).Я изучал различные механизмы аутентификации и авторизации для веб-интерфейсов API (изучая другие реализации).Я обернул голову вокруг большинства фундаментальных понятий, но все еще ищу руководство в нескольких областях.Последнее, что я хочу сделать, - это заново изобрести колесо, но я не нахожу никаких стандартных решений, которые бы соответствовали моим критериям (однако мои критерии могут быть ошибочными, поэтому не стесняйтесь критиковать и это).Кроме того, я хочу, чтобы API был одинаковым для всех платформ / приложений, использующих его.

oAuth

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

Требования

  1. Пользователь вводит имя пользователя / пароль в приложение.
  2. Каждый вызов API идентифицируется вызывающим приложением.
  3. Издержки сводятся к минимуму, а аспект аутентификации интуитивно понятен для разработчиков.
  4. Механизм безопасен как для конечного пользователя.(их учетные данные не раскрываются), а также разработчик (их учетные данные приложения не предоставляются).
  5. Если возможно, не требуется https (ни в коем случае не жесткое требование).

Мои текущие мысли о реализации

Внешний разработчик запросит учетную запись API.Они получат apikey и apisecret.Для каждого запроса требуется как минимум три параметра.

  • apikey - предоставляется разработчику при регистрации
  • timestamp - дублируется как уникальный идентификатор для каждого сообщения для данного apikey
  • hash - хэш метки времени + apisecret

Apikey требуется для идентификации приложения, отправляющего запрос.Временная метка действует аналогично oauth_nonce и предотвращает / смягчает атаки воспроизведения.Хеш гарантирует, что запрос был действительно выдан владельцем данного apikey.

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

Заключение

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

Случайные мысли / Бонусные вопросы

Для API, которым требуется только apikey как часть запроса, как вы препятствуете тому, чтобы кто-то, кроме владельца apikey, мог видеть apikey (с момента его отправки в открытом виде) и делать чрезмерные запросы, чтобы вывести их за пределы использования?Может быть, я просто обдумываю это, но не должно ли быть что-то, что могло бы подтвердить, что запрос был подтвержден владельцу apikey?В моем случае это было целью apisecret, он никогда не показывается / не передается без хэширования.

Говоря о хешах, как насчет md5 против hmac-sha1?Действительно ли имеет значение, когда все значения хэшируются с достаточно длинными данными (например, apisecret)?

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

Ответы [ 5 ]

43 голосов
/ 19 октября 2010

Я думаю о том, как выполнить входную часть этого в моих проектах:

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

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

  3. Сервер проверяет, что login_token это то, что он сгенерировал, удаляя его из спискадействительных login_token с.Затем сервер объединяет свой сохраненный хэш пароля пользователя с login_token и гарантирует, что он соответствует представленному комбинированному токену.Если он совпадает, вы аутентифицировали своего пользователя.

Преимущества этого состоят в том, что вы никогда не сохраняете пароль пользователя на сервере, пароль никогда не передается в открытом виде, хэш пароля толькопередается в открытом виде при создании учетной записи (хотя могут быть способы обойти это), и она должна быть защищена от атак воспроизведения, поскольку login_token удаляется из БД при использовании.

13 голосов
/ 29 октября 2010

Это много вопросов в одном, я думаю, что многим людям не удалось прочесть весь путь до конца:)

Мой опыт проверки подлинности веб-службы состоит в том, что люди обычно перерабатывают ее, и проблемы только те, с которыми вы столкнулись бы на веб-странице. Возможные очень простые опции будут включать https для шага входа в систему, возвращать токен, требовать его включения в будущие запросы. Вы также можете использовать http обычную аутентификацию и просто передавать вещи в заголовок. Для дополнительной безопасности часто поворачивайте / истекайте токены, проверяйте, что запросы поступают от одного и того же блока IP (хотя это может привести к путанице, когда мобильные пользователи перемещаются между ячейками), в сочетании с ключом API или аналогичным. В качестве альтернативы, сделайте шаг oauth «ключ запроса» (кто-то предложил это уже в предыдущем ответе, и это хорошая идея) перед аутентификацией пользователя и используйте его в качестве необходимого ключа для генерации токена доступа.

Альтернатива, которую я еще не использовал, но о которой я слышал много как альтернатива oAuth, удобной для устройств, - xAuth . Посмотрите на это, и если вы используете его, мне было бы очень интересно услышать ваши впечатления.

Для хеширования sha1 немного лучше, но не зацикливайтесь на этом - все, что устройства могут легко (и быстро в плане производительности) реализовать, вероятно, подойдет.

Надеюсь, это поможет, удачи:)

9 голосов
/ 29 октября 2010

Twitter решил проблему с внешним приложением в oAuth, поддержав вариант, который они называют xAuth .К сожалению, уже существует множество других схем с таким именем, поэтому сортировка может быть затруднена.

Протокол имеет значение oAuth, за исключением того, что он пропускает фазу маркера запроса и просто немедленно выдает доступпара токенов при получении имени пользователя и пароля.(Начиная с шаг E здесь .) Этот начальный запрос и ответ должны быть защищены - он отправляет имя пользователя и пароль в виде открытого текста и получает обратно токен доступа исекретный токенКак только пара токенов доступа настроена, то, был ли начальный обмен токеном с помощью модели oAuth или модели xAuth, не имеет значения как для клиента, так и для сервера до конца сеанса.Это дает преимущество в том, что вы можете использовать существующую инфраструктуру oAuth и иметь практически такую ​​же реализацию для мобильных / веб / настольных приложений.Основным недостатком является то, что приложению предоставляется доступ к имени пользователя и паролю клиента, но, похоже, ваши требования требуют такого подхода.

В любом случае, я бы хотел согласиться с вашей интуицией инесколько других отвечающих здесь: не пытайтесь создавать что-то новое с нуля.Протоколы безопасности могут быть легко запущены, но их всегда сложно сделать хорошо, и чем более запутанными они становятся, тем меньше вероятность того, что сторонние разработчики смогут внедрить против них.Ваш гипотетический протокол очень похож на o (x) Auth - api_key / api_secret, nonce, sha1 hash - но вместо того, чтобы использовать одну из множества существующих библиотек, которые ваши разработчики должны будут развернуть самостоятельно.

8 голосов
/ 28 октября 2010

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

Если предположить, что это так, то я подхожу к этому следующим образом (но только потому, что я Java-разработчик, поэтому парень на C # сделает это по-другому):

TheRESTful-сервис аутентификации и авторизации

  1. Это будет работать только через HTTPS для предотвращения перехвата.
  2. Он будет основан на комбинации RESTEasy , Spring Security и CAS (для единого входа в несколько приложений).
  3. Он будет работать как с браузерами, так и с веб-клиентскими приложениями
  4. Будет веб-интерфейс управления учетными записями, позволяющий пользователям редактировать свои данные, а администраторам (для определенных приложений) менять полномочия.уровни

Клиентская библиотека / приложение безопасности

  1. Для каждой поддерживаемой платформы (например, Symbian, Android, iOS и т. д.) создайте подходящую реализациюбиблиотека безопасности на родном языке платформы (например, Java, ObjectiveC, C и т. д.)
  2. Библиотека должна управлять формированием HTTPS-запроса с использованием доступных API для данной платформы (например, Java использует URLConnection и т. д.)
  3. Потребители общей библиотеки аутентификации и авторизации («потому что это все, что есть») будут кодировать определенный интерфейс и выигрывать »будьте счастливы, если он когда-нибудь изменится, поэтому убедитесь, что он очень гибкий.Следуйте существующим проектным решениям, таким как Spring Security.

Итак, теперь, когда вид с высоты 30 000 футов завершен, как вы поступите?Что ж, не так сложно создать систему аутентификации и авторизации на основе перечисленных технологий на стороне сервера с клиентом браузера.В сочетании с HTTPS платформы будут обеспечивать безопасный процесс на основе общего токена (обычно представляемого в виде cookie), сгенерированного процессом аутентификации и используемого всякий раз, когда пользователь желает что-то сделать.Этот токен предоставляется клиентом серверу всякий раз, когда происходит любой запрос.

В случае локального мобильного приложения кажется, что вы ищете решение, которое выполняет следующее:

  1. Клиентское приложение имеет определенный список контроля доступа (ACL), контролирующий доступ во время выполнения к вызовам методов.Например, данный пользователь может читать коллекцию из метода, но его ACL-список разрешает доступ только к объектам, у которых в имени есть символ Q, поэтому некоторые данные в коллекции спокойно обрабатываются перехватчиком безопасности.В Java это просто, вы просто используете аннотации Spring Security в вызывающем коде и реализуете подходящий процесс ответа ACL.На других языках вы сами по себе и, вероятно, должны будете предоставить стандартный код безопасности, который вызывает вашу библиотеку безопасности.Если язык поддерживает AOP (Аспектно-ориентированное программирование), используйте его в полной мере для этой ситуации.
  2. Библиотека безопасности кэширует полный список авторизаций в свою личную память для текущего приложения, чтобы она не имелаоставаться на связи.В зависимости от продолжительности сеанса входа в систему это может быть одноразовая операция, которая никогда не повторяется.

Что бы вы ни делали, не пытайтесь придумать свой собственный протокол безопасности или используйте безопасность по неизвестности.Вы никогда не сможете написать лучший алгоритм для этого, чем те, которые в настоящее время доступны и бесплатны.Также люди доверяют хорошо известным алгоритмам.Поэтому, если вы скажете, что ваша библиотека безопасности обеспечивает авторизацию и аутентификацию для локальных мобильных приложений, использующих комбинацию зашифрованных токенов SSL, HTTPS, SpringSecurity и AES, вы сразу же получите авторитет на рынке.

Надеюсь, это поможет, и удачи в вашем предприятии. Если вам нужна дополнительная информация, дайте мне знать - я написал довольно много веб-приложений на основе Spring Security, ACL и тому подобного.

5 голосов
/ 24 января 2017

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

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

В предлагаемом решении вы упоминаете, что потребуется минимум три параметра:

  • apikey - передается разработчику при регистрации
  • метка времени - удваивается как уникальный идентификатор для каждого сообщения для данного apikey
  • хэш - хэш метки времени + apisecret

Следствием этого является то, что для некоторых вызовов API имя пользователя / пароль не требуется.Это может быть полезно для приложений, в которых вы не хотите принудительно входить в систему (например, просматриваете интернет-магазины).

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

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

ДругойЧтобы избежать чрезмерного использования API, который не требует входа в систему, необходимо ограничить трафик и потенциально идентифицировать и заблокировать подозрительные IP-адреса.Количество усилий, на которые вы хотите пойти, будет во многом зависеть от того, насколько ценны ваши данные.

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

...