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

Что означает аутентификация RESTful и как она работает? Я не могу найти хороший обзор в Google. Мое единственное понимание заключается в том, что вы передаете ключ сеанса (remeberal) в URL-адресе, но это может быть ужасно неправильно.

Ответ 1

Как обрабатывать аутентификацию в архитектуре RESTful Client-Server является дебатом.

Как правило, его можно достичь в мире SOA через HTTP через:

  • HTTP basic auth over HTTPS;
  • Cookies и управление сеансом;
  • Токен в заголовках HTTP (например, OAuth 2.0);
  • Аутентификация запроса с дополнительными параметрами подписи.

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

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

HTTP basic auth over HTTPS

Это первое решение, основанное на стандартном протоколе HTTPS, используется большинством веб-служб.

GET /spec.html HTTP/1.1
Host: www.example.org
Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==

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

Мы можем использовать Дайджест аутентификации, но для этого требуется также HTTPS, так как он уязвим для MiM или Replay и специфичен для HTTP.

Сессия через файлы cookie

Честно говоря, сеанс, управляемый на сервере, не является по сути безстоящим.

Одной из возможностей может быть сохранение всех данных в содержимом файла cookie. И, по своему усмотрению, cookie обрабатывается на стороне сервера (клиент фактически даже не пытается интерпретировать данные cookie: он просто передает его обратно серверу на каждый последующий запрос). Но эти данные cookie представляют собой данные состояния приложения, поэтому клиент должен управлять им, а не сервером, в чистом мире без гражданства.

GET /spec.html HTTP/1.1
Host: www.example.org
Cookie: theme=light; sessionToken=abc123

Техника cookie сама по себе связана с HTTP, поэтому она не является действительно RESTful, которая должна быть независимой от протокола, IMHO. Он уязвим для MiM или Replay атак.

Предоставляется через токен (OAuth2)

Альтернативой является поставить токен в заголовках HTTP, чтобы запрос был аутентифицирован. Это то, что делает OAuth 2.0, например. См. RFC 6749:

 GET /resource/1 HTTP/1.1
 Host: example.com
 Authorization: Bearer mF_9.B5f-4.1JqM

Короче говоря, это очень похоже на куки файл и страдает от одних и тех же проблем: не имеет апатрида, полагаясь на подробности передачи HTTP и подвергая много слабых мест безопасности - включая MiM и Replay - поэтому должен использоваться только через HTTPS.

Аутентификация запроса

Аутентификация запроса заключается в подписании каждого запроса RESTful через некоторые дополнительные параметры в URI. См. эту справочную статью.

Он был определен как таковой в этой статье:

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

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

Например, здесь приведен общий пример URI из приведенной выше ссылки:

GET /object?apiKey=Qwerty2010

должен передаваться как таковой:

GET /object?timestamp=1261496500&apiKey=Qwerty2010&signature=abcdef0123456789

Подписанная строка /object?apikey=Qwerty2010&timestamp=1261496500, а подпись - это хэш SHA256 этой строки с использованием частного компонента ключа API.

Серверное кэширование данных может быть всегда доступно. Например, в наших рамках мы кэшируем ответы на уровне SQL, а не на уровне URI. Поэтому добавление этого дополнительного параметра не нарушает механизм кэширования.

См. эту статью для получения подробной информации об аутентификации RESTful в нашей инфраструктуре ORM/SOA/MVC клиент-сервер на основе JSON и REST. Поскольку мы разрешаем общение не только по HTTP/1.1, но также и по именованным каналам или сообщениям GDI (локально), мы пытались внедрить подлинный шаблон проверки RESTful и не полагаться на специфику HTTP (например, заголовок или куки).

На практике ожидаемая аутентификация MAC Tokens для OAuth 2.0может быть огромным улучшением в отношении нынешней схемы "Предоставлено токеном". Но это все еще продолжается работа и привязана к передаче HTTP.

Заключение

Стоит заключить, что REST не только основан на HTTP, даже если на практике он в основном реализован через HTTP. REST может использовать другие уровни связи. Таким образом, аутентификация RESTful - это не просто синоним аутентификации HTTP, независимо от того, что отвечает Google. Он вообще не должен использовать механизм HTTP, но должен быть абстрагирован от уровня связи.

Ответ 2

Я сомневаюсь, что люди с энтузиазмом кричали "HTTP-аутентификация", когда-либо пробовали сделать приложение на основе браузера (вместо веб-сервиса от машины к машине) с помощью REST (без обид - я просто не думаю, что они когда-либо сталкивались с осложнениями),

Проблемы, которые я обнаружил при использовании HTTP-аутентификации в службах RESTful, которые создают HTML-страницы для просмотра в браузере, следующие:

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

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

Я считаю, что cookie - это решение. Но подождите, печенье злые, не так ли? Нет, они не такие, как часто используются куки, это зло. Сам файл cookie - это всего лишь часть клиентской информации, точно так же, как информация об аутентификации HTTP, которую браузер будет отслеживать во время просмотра. И эта часть клиентской информации отправляется на сервер по каждому запросу, опять же, как и HTTP-аутентификация. Понятно, что единственное отличие состоит в том, что содержимое этой части клиентского состояния может быть определено сервером как часть его ответа.

Создавая сеансы ресурса RESTful, используя только следующие правила:

  • Сеанс отображает ключ к идентификатору пользователя (и, возможно, метку времени последнего действия для тайм-аутов)
  • Если сеанс существует, это означает, что ключ действителен.
  • Вход означает POSTing to/sessions, новый ключ устанавливается как файл cookie
  • Выход из системы означает DELETEING/sessions/{key} (с перегруженным POST, помните, что мы браузер, а HTML 5 - еще длинный путь)
  • Аутентификация выполняется путем отправки ключа в виде файла cookie при каждом запросе и проверки наличия и действительности сеанса

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

convert42 добавляет, что при использовании https (что нам нужно) важно, чтобы cookie установил свой безопасный флаг, чтобы информация аутентификации никогда не отправлялась по незащищенному соединению. Отличный момент, сам не видел.

Я считаю, что это достаточное решение, которое прекрасно работает, но я должен признать, что мне недостаточно эксперта по безопасности для выявления потенциальных явлений в этой схеме - все, что я знаю, это то, что сотни веб-приложений, не относящихся к RESTful, используют по существу то же самое протокол входа в систему ($ _SESSION inphp, HttpSession в Java EE и т.д.). Содержимое заголовка файла cookie просто используется для адресации ресурса на стороне сервера, так же как язык приема может использоваться для доступа к ресурсам перевода и т.д. Я чувствую, что это то же самое, но, может быть, другие нет? Что вы думаете, ребята?

Ответ 3

Достаточно уже сказано на эту тему хорошими людьми здесь. Но вот мои 2 цента.

Существует 2 режима взаимодействия:

  • от человека к машине (HTM)
  • машина-машина (MTM)

Машина является общим знаменателем, выраженным как API REST, а субъекты/клиенты - либо люди, либо машины.

Теперь, в реальной архитектуре RESTful, концепция безгражданства подразумевает, что все соответствующие состояния приложения (то есть состояния клиентской стороны) должны предоставляться с каждым запросом. Под релевантным подразумевается то, что требуется REST API для обработки запроса и предоставления соответствующего ответа.

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

Рассмотрим это: у вас есть платформа данных/информации, представленная как набор REST API. Возможно, у вас есть платформа BI для самообслуживания, которая обрабатывает все кубы данных. Но вы хотите, чтобы ваши (человеческие) клиенты получили доступ к этому через (1) веб-приложение, (2) мобильное приложение и (3) какое-то стороннее приложение. В конце концов, даже цепочка MTM ведет к HTM - право. Таким образом, человеческие пользователи остаются на вершине информационной цепочки.

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

Понятие аутентификации применяется по всем направлениям. Как вы это разработаете, чтобы ваши API-интерфейсы REST были доступны в едином, защищенном виде? Как я вижу это, есть два способа:

Way-1:

  • Для начала нет логина. Каждый запрос выполняет вход
  • Клиент отправляет свои идентификационные параметры + конкретный запрос параметры с каждым запросом
  • API REST принимает их, оборачивается, пингует пользовательское хранилище (что бы это ни было) и подтверждает auth
  • Если auth установлен, обслуживает запрос; в противном случае отрицает с соответствующим кодом состояния HTTP
  • Повторите вышеуказанное для каждого запроса по всем API-интерфейсам REST в вашем Каталог

Way-2:

  • Клиент начинает с запроса auth
  • API REST входа будет обрабатывать все такие запросы
  • Он принимает параметры auth (ключ API, uid/pwd или что угодно выберите) и проверит auth на хранилище пользователей (LDAP, AD или MySQL DB и т.д.).
  • Если проверено, создается токен аутентификации и возвращает его обратно клиент/абонент
  • Затем вызывающий отправляет этот токен аутентификации + запрашивает определенные параметры с помощью каждый последующий запрос к другим бизнес-REST API, до выхода из системы или до истечения срока аренды.

Очевидно, что в Way-2 API REST будет нужен способ распознавания и доверия к токену как действительный. API-интерфейс Login API выполнил аутентификацию аутентификации, и поэтому для того, чтобы "валет-ключ" должен был доверять другие API-интерфейсы REST в вашем каталоге.

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

Но я отвлекся.

Дело в том, что "состояние" (о статусе аутентификации клиента) необходимо поддерживать и совместно использовать, чтобы все API REST могли создать круг доверия. Если мы этого не сделаем, это путь-1, мы должны признать, что акт аутентификации должен выполняться для любых/всех входящих запросов.

Выполнение аутентификации - это ресурсоемкий процесс. Представьте, что вы выполняете SQL-запросы для каждого входящего запроса в своем хранилище пользователей, чтобы проверить соответствие uid/pwd. Или для шифрования и выполнения хеш-совпадений (стиль AWS). И в архитектуре каждый API REST должен будет выполнить это, я подозреваю, используя общую службу входа в систему. Потому что, если вы этого не сделаете, вы повредите код auth везде. Большой беспорядок.

Так что больше слоев, больше латентности.

Теперь, возьмите Way-1 и применитесь к HTM. Ваш пользователь (человек) действительно заботится, если вам нужно отправить uid/pwd/hash или что угодно с каждым запросом? Нет, если вы не беспокоите ее, бросая страницу auth/login каждую секунду. Удачи, если у вас есть клиенты. Итак, что вы будете делать, это хранить информацию для входа где-то на стороне клиента, в браузере, в самом начале и отправлять ее с каждым сделанным запросом. Для пользователя (пользователя) она уже вошла в систему и доступна "сессия". Но на самом деле она аутентифицируется по каждому запросу.

То же самое с Way-2. Ваш (пользователь) пользователь никогда не заметит. Поэтому никакого вреда не было.

Что делать, если мы применим Way-1 к MTM? В этом случае, поскольку его машина, мы можем избавиться от этого парня, попросив его предоставить информацию аутентификации с каждым запросом. Никто не заботится! Выполнение Way-2 на MTM не вызовет никакой особой реакции; его проклятая машина. Это могло бы заботиться меньше!

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

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

Ответ 4

Вот действительно и полностью RESTful решение для проверки подлинности:

  • Создайте пару открытого/закрытого ключей на сервере аутентификации.
  • Распределите открытый ключ на всех серверах.
  • Когда клиент аутентифицируется:

    3,1. выдать токен, который содержит следующее:

    • Срок действия
    • имя пользователя (необязательно)
    • пользователи IP (необязательно)
    • хэш пароля (необязательно)

    3,2. Зашифруйте токен с помощью закрытого ключа.

    3.3. Отправляйте зашифрованный токен пользователю.

  • Когда пользователь обращается к любому API, он также должен передать свой токен аутентификации.

  • Серверы могут проверить, что токен действителен, дешифруя его с помощью открытого ключа auth-сервера.

Это аутентификация без сохранения состояния /RESTful.

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

Ответ 5

Честно говоря, я видел здесь отличные ответы, но кое-что, что меня немного беспокоит, - это то, что кто-то полностью примет концепцию безгражданства, где она станет догматичной. Это напоминает мне тех старых поклонников Smalltalk, которые хотели только принять чистое ОО, и если что-то не является объектом, то вы делаете это неправильно. Дайте мне перерыв.

Предполагается, что подход RESTful облегчит вашу жизнь и уменьшит накладные расходы и затраты на сеансы, постарайтесь следовать за ней, поскольку это мудрая вещь, но в тот момент, когда вы следуете дисциплине (любая дисциплина/руководство) к где он больше не обеспечивает того преимущества, ради которого он предназначался, тогда вы делаете это неправильно. Некоторые из лучших языков сегодня имеют как функциональное программирование, так и объектную ориентацию.

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

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

Ответ 6

Прежде всего, веб-служба RESTful БЕЗОПАСНО (или, другими словами, SESSIONLESS). Таким образом, служба RESTful не имеет и не должна иметь понятия сеанса или файлов cookie. Способ аутентификации или авторизации в службе RESTful - это использование заголовка HTTP-авторизации, как определено в спецификациях HTTP RFC 2616. Каждый отдельный запрос должен содержать заголовок HTTP-авторизации, и запрос должен быть отправлен по HTTP-соединению (SSL). Это правильный способ сделать аутентификацию и проверить авторизацию запросов в веб-службах HTTP RESTful. Я реализовал веб-службу RESTful для приложения Cisco PRIME Performance Manager в Cisco Systems. И как часть этой веб-службы, я также внедрил аутентификацию/авторизацию.

Рубенс Гомес.

Ответ 7

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

Самый простой способ приблизиться к этому - начать с встроенных механизмов аутентификации HTTP в RFC 2617.

Ответ 8

"Очень проницательная" статья, упомянутая @skrebel (http://www.berenddeboer.net/rest/authentication.html) обсуждает запутанный, но действительно нарушенный метод аутентификации.

Вы можете попробовать посетить страницу (которая должна отображаться только для аутентифицированного пользователя) http://www.berenddeboer.net/rest/site/authenticated.html без учетных данных для входа.

(Извините, я не могу прокомментировать ответ.)

Я бы сказал, что REST и аутентификация просто не смешиваются. REST означает "без гражданства", но "аутентифицированный" - это состояние. Вы не можете иметь их обоих на одном уровне. Если вы являетесь сторонником RESTful и нахмурились на государствах, тогда вам нужно пойти с HTTPS (то есть оставить проблему безопасности на другом уровне).

Ответ 9

Я думаю, что спокойная аутентификация включает в себя передачу токена аутентификации в качестве параметра в запросе. Примерами являются использование apikeys api's. Я не считаю, что использование файлов cookie или http auth квалифицируется.

Ответ 10

Я думаю, что для аутентификации службы REST можно использовать следующий подход:

  1. Создайте API входа RESTful, чтобы принять имя пользователя и пароль для аутентификации. Используйте метод HTTP POST для предотвращения кеширования и SSL для обеспечения безопасности во время транзита. При успешной аутентификации API возвращает два JWT - один токен доступа (более короткая достоверность, скажем, 30 минут) и один токен обновления (более длительный срок действия, например, 24 часа)
  2. Клиент (веб-интерфейс) хранит JWT в локальном хранилище и в каждом последующем вызове API пропускает токен доступа в заголовке "Авторизация: несущий #access"
  3. API проверяет действительность токена, проверяя дату подписи и истечения срока действия. Если токен действителен, проверьте, является ли пользователь (он интерпретирует требование "под" в JWT как имя пользователя) имеет доступ к API с помощью поиска в кеше. Если пользователь имеет право доступа к API, выполните бизнес-логику
  4. Если токен истек, API возвращает код ответа HTTP 400
  5. Клиент, получая 400/401, вызывает еще один REST API с токеном обновления в заголовке "Authorization: Bearer #refresh token", чтобы получить новый токен доступа.
  6. При получении вызова с токеном обновления проверьте, действителен ли токен обновления, проверяя подпись и дату истечения срока действия. Если токен обновления действителен, обновите кэш прав доступа пользователя из БД и верните новый токен доступа и обновите токен. Если токен обновления недействителен, верните код ответа HTTP 400
  7. Если возвращается токен доступа и токен обновления, перейдите к шагу 2. Если возвращается код ответа HTTP 400, клиент предполагает, что токен обновления истек и запрашивает у пользователя имя пользователя и пароль
  8. Для выхода из системы очистите локальное хранилище

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

Ответ 12

Чтобы ответить на этот вопрос из моего понимания...

Система аутентификации, которая использует REST, чтобы вам не нужно было отслеживать или управлять пользователями в вашей системе. Это делается с использованием методов HTTP POST, GET, PUT, DELETE. Мы используем эти 4 метода и рассматриваем их в терминах взаимодействия с базами данных как CREATE, READ, UPDATE, DELETE (но в Интернете мы используем POST и GET, потому что в настоящее время поддерживаются теги привязки). Поэтому, рассматривая POST и GET как наш CREATE/READ/UPDATE/DELETE (CRUD), мы можем разработать маршруты в нашем веб-приложении, которые смогут определить, какое действие CRUD мы добиваемся.

Например, в приложении Ruby on Rails мы можем создать наше веб-приложение таким образом, чтобы, если пользователь, который вошел в систему, посещает http://store.com/account/logout тогда GET этой страницы можно просмотреть как пользователь, пытающийся выйти из системы. В нашем контроллере rails мы создадим действие в том, что регистрирует пользователя и отправляет его обратно на домашнюю страницу.

A GET на странице входа даст форму. POST на странице входа будет рассматриваться как попытка входа в систему и взять данные POST и использовать его для входа в систему.

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

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

Ответ 13

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

См. http://en.wikipedia.org/wiki/Public_key_infrastructure. Если вы соблюдаете надлежащие стандарты PKI, человек или агент, который неправильно использует украденный ключ, могут быть идентифицированы и заблокированы. Если агент должен использовать сертификат, привязка становится довольно жесткой. Умный и быстродвижущийся вор может убежать, но они оставляют больше крошек.