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

184

Обзор

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

OAuth

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

Требования

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

Мои текущие мысли о внедрении

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

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

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

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

Заключение

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

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

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

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

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

  • 1
    Надеюсь получить еще несколько комментариев / предложений. Вопрос слишком расплывчатый / двусмысленный?
  • 6
    вопрос идеален, но даже спустя почти 2 года реализации oauth кажутся загадочными ... мне труднее всего добиться именно того, что вы обсуждали выше. у меня есть дополнительное измерение: я не хочу использовать пару loginName / password - я хочу использовать проверку личности Google на Android / IOS (Symbian был объявлен WWF "почти исчезнувшим видом"), и я отказываюсь разрабатывать для Windows Mobile (как они называют это в наши дни).
Показать ещё 3 комментария
Теги:
authentication
rest
oauth
mobile-application

5 ответов

40

То, как я собираюсь сделать часть входа в этом в моих проектах, это:

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

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

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

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

  • 0
    Спасибо, я забыл добавить часть о хешировании пароля на стороне приложения. Я не храню пароли своих пользователей в открытом виде (хеширую перед сохранением).
  • 2
    Я вижу обратную сторону этого метода: вы не можете хранить соленые пароли в БД. Если злоумышленники возложат руки на вашу БД, им не нужно будет ничего расшифровывать. Поскольку хэш пароля является реальным паролем в этой схеме.
Показать ещё 2 комментария
12

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

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

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

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

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

  • 0
    Спасибо за ответ. Я изучал xAuth, и это может быть путь, по которому я могу пойти, чтобы я мог в итоге установить oAuth, что делает более стандартизированный процесс взаимодействия с API.
8

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

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

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

  • 2
    Я также должен отметить, что похоже, что конечная точка 'skip request token' будет в oAuth 2, она указана в текущем проекте как тип предоставления доступа "пароль". Смотри раздел 4.1.2: tools.ietf.org/html/draft-ietf-oauth-v2-10#section-4.1.2
  • 0
    Как я уже упоминал в Lonra, я больше интересуюсь xAuth и, в частности, по причинам, которые вы упомянули в конце ... разработчики могут использовать готовые инструменты / библиотеки oAuth для взаимодействия с моим API, что является "хорошей вещью" ,
8

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

Предполагая, что это так, я бы подошел к нему следующим образом (но только "потому что я разработчик Java, поэтому парень С# сделал бы это по-другому):

Служба проверки подлинности и авторизации RESTful

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

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

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

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

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

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

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

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

  • 0
    Спасибо, хорошая информация. Пара вопросов. Во-первых, если подслушивание приемлемо (не уверен, является ли это / нет, мое приложение не имеет в виду никакой реальной личной / ценной информации, но если бы это изменило мое обоснование, изменилось бы), тогда действительно ли требуется HTTPS?
  • 0
    Вы можете управлять всей системой за пределами HTTPS, если хотите. HTTPS предназначен только для защиты секретной информации, поэтому я предполагаю, что на этапе аутентификации вы будете делать это через HTTPS, чтобы обеспечить некоторую гарантию того, что ваше имя пользователя / пароль / секрет хранится в секрете. После того как токен передается в ответе, дальнейшие запросы могут быть сделаны в открытом виде, если информация, содержащаяся в потоке (для которой требуется аутентификация, не требуется), не нуждается в защите от перехватчиков.
Показать ещё 1 комментарий
3

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

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

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

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

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

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

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

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

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

Ещё вопросы

Сообщество Overcoder
Наверх
Меню