Защита REST API без необходимости изобретать велосипед - PullRequest
73 голосов
/ 30 августа 2011

При разработке REST API обычно сначала выполняется аутентификация пользователя?

Типичный пример использования, который я ищу:

  • Пользователь хочет получить данные.Конечно круто, мы хотели бы поделиться!Получите открытый ключ API и прочитайте!
  • Пользователь хочет сохранить / обновить данные ... вау, подождите!кто вы, можете ли вы сделать это?

Я хотел бы собрать его один раз и разрешить использовать его, скажем, в веб-приложении, приложении для Android или приложении для iPhone.REST API представляется логичным выбором с такими требованиями:

. Для иллюстрации моего вопроса я приведу простой пример.

У меня есть элемент в базе данных, который имеет рейтинг атрибут (целое число от 1 до 5).

Если я правильно понимаю REST, я бы реализовал запрос GET, используя язык по своему выбору, который возвращает csv, xml или json, например:

http://example.com/product/getrating/{id}/

Скажем, мы выбираем JSON и возвращаем:

{
  "id": "1",
  "name": "widget1",
  "attributes": { "rating": {"type":"int", "value":4} }
}

Это хорошо для общедоступных API.Я получил эту часть.

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

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

Если пользователь "JOE"хочет добавить рейтинг к элементу

Это можно сделать с помощью:

http://example.com/product/addrating/{id}/{givenRating}/

На данный момент я хочу сохранитьданные о том, что "JOE" дал продукту {id} рейтинг {даноРейтинг}.

Вопрос: Как узнать, что запрос поступил от "JOE", а не от "BOB".

Более тогоЧто, если это было бы для более разумных данных, таких как номер телефона пользователя?

Что я получил до сих пор:

1) Используйте встроенную функцию HTTP для аутентификации на каждомзапрос, либо простой HTTP или HTTPS.

Это означает, что каждый запрос теперь принимает форму:

https://joe:joepassword@example.com/product/addrating/{id}/{givenRating}/

2) Используйте подход, подобный Amazon S3 с закрытым и открытым ключом: http://www.thebuzzmedia.com/designing-a-secure-rest-api-without-oauth-authentication/

3) В любом случае используйте cookie-файл и прервите часть REST без состояния.

Второй подход мне кажется лучше, но яоставил вопрос: а нужно ли мне заново изобретать все это?Хеширование, хранение, генерация ключей и т. Д. Самостоятельно?

Это похоже на использование сессии в типичном веб-приложении и переписывание всего стека самостоятельно, что для меня обычно означает «Вы делаете это неправильно», особенно когда речь идет о безопасности.

РЕДАКТИРОВАТЬ: Я думаю, я должен был упомянуть OAuth.

Ответы [ 3 ]

21 голосов
/ 30 августа 2011

Редактировать 5 лет спустя

Использовать OAuth2!

Предыдущая версия

Нет, использовать куки-файлы абсолютно не нужно. Он не в два раза безопаснее, чем HTTP Digest, OAuth или Amazon AWS (которые нетрудно скопировать).

То, как вы должны смотреть на cookie-файл, заключается в том, что это токен аутентификации, такой же, как Basic / Digest / OAuth /, в зависимости от того, что будет, но менее целесообразно.

Однако я не думаю, что использование cookie противоречит принципам RESTful per se , если содержимое cookie сеанса не влияет на содержимое ресурса, который вы возвращаете с сервера. .

Печенье злые, прекратите их использовать.

21 голосов
/ 30 августа 2011

Не беспокойтесь о том, чтобы быть "RESTful", беспокойтесь о безопасности. Вот как я это делаю:

Шаг 1. Пользователь обращается к службе аутентификации с учетными данными.

Шаг 2. Если проверяются учетные данные, верните отпечаток пальца, идентификатор сеанса и т. Д. И вставьте их в общую память для последующего быстрого поиска или используйте базу данных, если вы не против добавить несколько миллисекунд в веб время выполнения услуги.

Шаг 3. Добавьте вызов точки входа в начало каждого сценария веб-службы, который проверяет отпечаток пальца и идентификатор сеанса для каждого запроса веб-службы.

Шаг 4. Если отпечаток пальца и идентификатор сеанса недействительны или время ожидания перенаправлено на проверку подлинности.

ПРОЧИТАЙТЕ ЭТО:

Аутентификация RESTful

8 голосов
/ 03 декабря 2013

Редактировать 3 года спустя

Я полностью согласен с Evert, используйте OAuth2 с HTTPS и не изобретайте колесо!:-)

Более простыми API REST - не предназначены для сторонних клиентов - Web-токены JSON также могут быть хорошими.

Предыдущая версия

В любом случае используйте cookie-файл и прервите часть REST без состояния.

Не используйте сеансы, с сеансами ваша служба REST не будет хорошо масштабируемой ...Здесь есть два состояния: состояние приложения (или состояния клиента или сеанса) и состояние ресурса.Состояние приложения содержит данные сеанса и поддерживается клиентом REST.Состояние ресурса содержит свойства и отношения ресурса и поддерживается службой REST.Вы можете очень легко решить, является ли конкретная переменная частью состояния приложения или состояния ресурса.Если объем данных увеличивается с увеличением количества активных сеансов, он относится к состоянию приложения.Так, например, идентификатор пользователя в текущем сеансе принадлежит состоянию приложения, но список пользователей или разрешений пользователей принадлежит состоянию ресурса.

Таким образом, клиент REST должен хранить факторы идентификации и отправлять их с каждымзапрос.Не путайте REST-клиента с HTTP-клиентом.Они не то же самое.REST-клиент также может находиться на стороне сервера, если он использует curl, или он может создать, например, cookie-файл на стороне сервера, который он может совместно использовать со службой REST через CORS.Единственное, что имеет значение, что служба REST должна проходить аутентификацию при каждом запросе, поэтому вы должны отправлять учетные данные (имя пользователя, пароль) при каждом запросе.

  • Если вы пишете клиентский REST-клиент,тогда это можно сделать с помощью аутентификации SSL + HTTP.В этом случае вы можете создать кэш credentials -> (identity, permissions) на сервере, чтобы ускорить аутентификацию.Имейте в виду, что если вы очистите этот кеш и пользователи отправят один и тот же запрос, они получат одинаковый ответ, просто это займет немного больше времени.Вы можете сравнить это с сессиями: если вы очистите хранилище сессий, то пользователи получат status: 401 unauthorized ответ ...
  • Если вы напишите клиентский REST-клиент и отправите факторы идентификации в службу REST череззавить, тогда у вас есть 2 варианта.Вы также можете использовать http auth, или вы можете использовать менеджер сеансов в вашем REST-клиенте, но не в REST-сервисе.
  • Если кто-то ненадежный пишет ваш клиент REST, то вам нужно написать приложение для аутентификации пользователей и предоставить им возможность решать, хотят ли они предоставлять разрешения различным клиентам или нет.Oauth - это уже существующее решение для этого.Oauth1 более безопасен, oauth2 менее безопасен, но проще, и я думаю, что есть несколько других решений этой проблемы ... Вам не нужно изобретать это заново.Существуют полные решения для аутентификации и авторизации, использующие oauth, например: wso идентификационный сервер .

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

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