Restful веб-сервис аутентификации - PullRequest
43 голосов
/ 29 августа 2010

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

Я использую https, поэтому связь зашифрована. У меня есть две идеи:

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

Я гораздо ближе выбрал первый подход (он соответствует стандарту Restful, относительно прост в реализации, XML, json или html можно использовать без каких-либо изменений), но я хотел бы узнать, что вы думаете? Что вы рекомендуете: первый, второй или какой-то третий подход?

Кстати, я использую Python на стороне сервера.

Ответы [ 4 ]

23 голосов
/ 19 июня 2011

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

Вот как я это реализовал:

POST /sessions { Username: "User", Password: "Password" }

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

DELETE /session/{id}

Немедленно истекает сеанс, поэтому он больше не может быть использован. Это используется для явных выходов.

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

Что я предпочитаю в этом, так это то, что это чрезвычайно просто.

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

Если вы используете HTTPS везде, вам, вероятно, не нужно слишком беспокоиться. Однако, если вы хотите использовать HTTP, вам нужно будет использовать что-то вроде хеш-кода вместе с секретным ключом и сказать отметку времени, чтобы сгенерировать безопасный ключ для каждого запроса. Таким образом, вы можете поделиться секретным ключом через HTTPS, а затем переключиться на HTTP для дальнейших вызовов. Даже если кому-то удастся найти ключ в запросе, он может истечь почти мгновенно и быть бесполезным.

Отказ от ответственности: я не эксперт по безопасности; -).

8 голосов
/ 19 июня 2011

Нет причин не использовать здесь только HTTP-аутентификацию.

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

Этот метод рассматривался при использовании хеша bcrypt для исходного пароля из-за фактических затрат на проверку пользователя (если вы не знаете, bcrypt может быть настроен так, чтобы выполнять хэш-функцию в реальном времени). Был сделан выбор, чтобы обеспечить возможность «входа» службы один раз с использованием пароля, который будет проходить дорогостоящий процесс проверки через bcrypt, а затем получать токен с блокировкой времени в обмен на будущие запросы, которые будут обходить процесс bcrypt. .

В случае процесса bcrypt используйте HTTP-аутентификацию, служба будет работать как с обычным паролем, так и с токеном. Таким образом, пользователь всегда может использовать пароль для своего сервиса, но он просто становится дорогим. Таким образом, они МОГУТ сделать это, они просто НЕ ДОЛЖНЫ. Сервису не важно, какую технику аутентификации использует клиент.

Для повышения пропускной способности предлагается услуга nonce.

Кроме этого, это стандартная HTTP-аутентификация, но с новой схемой.

6 голосов
/ 29 августа 2010

Веб-сервисы Amazon делают это хорошо, ознакомьтесь с методологией для некоторых идей.По сути, они заставляют клиентов шифровать специальный заголовок http, используя свой пароль.

Вот ссылка:

http://docs.aws.amazon.com/AmazonS3/latest/API/sig-v4-authenticating-requests.html

4 голосов
/ 19 июня 2011

Предполагая, что служба никогда не используется в браузере, а связь в любом случае зашифрована, я не вижу вреда в варианте второго метода: добавьте X-заголовки для отправки имени пользователя / пароля при каждом запросе, например:

GET /foo HTTP/1.1
Host: www.bar.com
X-MyUsername: foo
X-MyPassword: bar

Другая идея заключается в том, чтобы использовать HTTP Basic Auth и просто отправить Authorization: Basic base64(user:password) -Header.То есть, если соединение всегда зашифровано.

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