Что означает аутентификация RESTful и как она работает? Я не могу найти хороший обзор в Google. Насколько я понимаю, вы передаете сеансовый ключ (запоминающийся) в URL, но это может быть ужасно неправильно.
Что означает аутентификация RESTful и как она работает? Я не могу найти хороший обзор в Google. Насколько я понимаю, вы передаете сеансовый ключ (запоминающийся) в URL, но это может быть ужасно неправильно.
Ответы:
Как обрабатывать аутентификацию в RESTful клиент-серверной архитектуре - вопрос спорный.
Обычно это может быть достигнуто в мире SOA через HTTP с помощью:
Вы должны будете адаптировать или даже лучше смешать эти методы, чтобы лучше всего соответствовать вашей программной архитектуре.
Каждая схема аутентификации имеет свои PRO и CON, в зависимости от цели вашей политики безопасности и архитектуры программного обеспечения.
Базовая аутентификация HTTP через 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-данные являются данными состояния приложения, поэтому ими должен управлять клиент, а не сервер, в чистом мире без сохранения состояния.
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
Короче говоря, это очень похоже на cookie и страдает теми же проблемами: не без сохранения состояния, полагаясь на детали передачи HTTP, и подвержено множеству недостатков безопасности - включая MiM и Replay - поэтому его следует использовать только через HTTPS. Как правило, JWT используется в качестве токена.
Запрос аутентификации
Аутентификация запроса состоит в подписании каждого запроса RESTful через некоторые дополнительные параметры в URI. Смотрите эту справочную статью .
Это было определено как таковое в этой статье:
Все запросы REST должны проходить проверку подлинности, подписывая параметры запроса, отсортированные в нижнем регистре в алфавитном порядке, используя личные учетные данные в качестве маркера подписи. Подписание должно происходить до того, как URL кодирует строку запроса.
Этот метод, возможно, более совместим с архитектурой без сохранения состояния, а также может быть реализован с легким управлением сеансами (с использованием сеансов в памяти вместо сохранения БД).
Например, вот пример общего URI по ссылке выше:
GET /object?apiKey=Qwerty2010
должен передаваться как таковой:
GET /object?timestamp=1261496500&apiKey=Qwerty2010&signature=abcdef0123456789
Подписываемая строка - /object?apikey=Qwerty2010×tamp=1261496500
это подпись, а хеш этой строки - SHA256 с использованием закрытого компонента ключа API.
Кэширование данных на стороне сервера всегда доступно. Например, в нашей среде мы кэшируем ответы на уровне SQL, а не на уровне URI. Таким образом, добавление этого дополнительного параметра не нарушает механизм кэширования.
В этой статье приведены некоторые подробности об аутентификации RESTful в нашей клиент-серверной инфраструктуре ORM / SOA / MVC, основанной на JSON и REST. Так как мы разрешаем связь не только по HTTP / 1.1, но также по именованным каналам или сообщениям GDI (локально), мы попытались реализовать действительно аутентификационный шаблон RESTful, а не полагаться на специфичность HTTP (например, заголовок или куки).
Позже примечание : добавление подписи в URI может рассматриваться как плохая практика (поскольку, например, она будет отображаться в журналах http-сервера), поэтому ее необходимо смягчить, например, с помощью соответствующего TTL, чтобы избежать повторов. Но если ваши http-логи скомпрометированы, у вас наверняка будут большие проблемы с безопасностью.
На практике предстоящая аутентификация по токенам MAC для OAuth 2.0 может стать огромным улучшением по сравнению с нынешней схемой «Предоставлено токеном». Но это все еще в стадии разработки и связано с передачей HTTP.
Вывод
Стоит сделать вывод, что REST не только основан на HTTP, даже если на практике он также в основном реализован через HTTP. REST может использовать другие коммуникационные уровни. Таким образом, аутентификация RESTful - это не просто синоним аутентификации HTTP, что бы ни отвечал Google. Он даже не должен использовать механизм HTTP вообще, но должен быть абстрагирован от уровня связи. И если вы используете HTTP-связь, благодаря инициативе Let's Encrypt нет никаких причин не использовать надлежащий HTTPS, который требуется в дополнение к любой схеме аутентификации.
Cookie
как лучшую замену, HTTP Basic Auth
вы можете выполнить аутентификацию без сохранения состояния с методом истечения срока аутентификации и возможностью выхода из системы. Пример реализации может использовать cookie, вызываемый Emulated-HTTP-Basic-Auth
со значением, аналогичным реальному HTTP Basic Auth, и дополнительно установленным сроком действия. Выход может быть осуществлен с удалением этого куки. Я предполагаю, что любой клиент, способный поддерживать HTTP Basic Auth, также может поддерживать аутентификацию cookie, выполненную таким образом.
Cookie
Вместо этого можно использовать предоставленную сервером эмуляцию для того же материала в другом заголовке ( ).
Я сомневаюсь, пытались ли когда-нибудь люди, которые с энтузиазмом выкрикивали «HTTP-аутентификацию», создавать приложение на основе браузера (вместо веб-службы «машина-машина») с REST (без обид, - я просто не думаю, что они когда-либо сталкивались с трудностями) ,
Проблемы, которые я обнаружил при использовании HTTP-аутентификации в сервисах RESTful, которые создают HTML-страницы для просмотра в браузере:
Очень проницательная статья, в которой рассматриваются эти вопросы по пунктам, находится здесь , но это приводит к множеству специфических для браузера хакеров javascript, обходных путей для обходных путей и так далее. Как таковой, он также не является совместимым с форвардом, поэтому потребует постоянного обслуживания по мере выпуска новых браузеров. Я не считаю этот чистый и понятный дизайн, плюс я чувствую, что это большая дополнительная работа и головная боль, просто чтобы я с энтузиазмом мог показать свой REST-значок моим друзьям.
Я считаю, что печенье - это решение. Но подождите, печенье - это зло, не так ли? Нет, это не так, то, как куки часто используются - зло. Сам файл cookie - это просто часть информации на стороне клиента, точно так же, как информация HTTP-аутентификации, которую браузер будет отслеживать при просмотре. И эта часть информации на стороне клиента отправляется на сервер при каждом запросе, как и в случае с информацией HTTP-аутентификации. Концептуально, единственное отличие состоит в том, что содержимое этого фрагмента состояния на стороне клиента может быть определено сервером как часть его ответа.
Делая сессии RESTful-ресурсом только со следующими правилами:
Теперь единственное отличие от HTTP-аутентификации состоит в том, что ключ аутентификации генерируется сервером и отправляется клиенту, который продолжает отправлять его обратно, а не клиенту, который вычисляет его по введенным учетным данным.
Конвертер42 добавляет, что при использовании https (что нам и следует) важно, чтобы в файле cookie был установлен флаг безопасности, чтобы информация аутентификации никогда не отправлялась по незащищенному соединению. Отличный момент, сам не видел.
Я чувствую, что это достаточное решение, которое прекрасно работает, но я должен признать, что мне недостаточно эксперта по безопасности, чтобы определить потенциальные дыры в этой схеме - все, что я знаю, это то, что сотни веб-приложений без RESTful используют по существу одно и то же протокол входа в систему ($ _SESSION в PHP, HttpSession в Java EE и т. д.). Содержимое заголовка cookie просто используется для адресации на стороне сервера, точно так же, как язык accept может использоваться для доступа к ресурсам перевода и так далее. Я чувствую, что это то же самое, но, возможно, другие нет? Что вы думаете, ребята?
Достаточно уже сказано на эту тему хорошими людьми здесь. Но вот мои 2 цента.
Есть 2 режима взаимодействия:
Машина является общим знаменателем, выраженным как API REST, а субъектами / клиентами являются люди или машины.
Теперь в действительно RESTful-архитектуре концепция безгражданства подразумевает, что все соответствующие состояния приложения (то есть состояния на стороне клиента) должны предоставляться с каждым запросом. Под релевантным подразумевается, что все, что требуется API REST для обработки запроса и предоставления соответствующего ответа.
Когда мы рассматриваем это в контексте приложений «человек-машина», «основанных на браузере», как указывает Скреббель выше, это означает, что (веб) -приложение, работающее в браузере, должно будет отправлять свое состояние и соответствующую информацию с каждым запросом это делает к концу API REST.
Учтите это: у вас есть платформа данных / информации, представляющая актив API REST. Возможно, у вас есть платформа самообслуживания BI, которая обрабатывает все кубы данных. Но вы хотите, чтобы ваши (люди) клиенты имели доступ к этому через (1) веб-приложение, (2) мобильное приложение и (3) какое-либо стороннее приложение. В конце концов, даже цепочка MTM ведет к HTM - верно. Таким образом, пользователи-люди остаются на вершине информационной цепочки.
В первых двух случаях у вас есть случай взаимодействия человека с машиной, причем информация фактически потребляется человеком-пользователем. В последнем случае у вас есть машинная программа, использующая API REST.
Концепция аутентификации применяется по всем направлениям. Как вы будете проектировать это так, чтобы к вашим API-интерфейсам REST обращались единообразно и безопасно? Как я вижу это, есть 2 способа:
Путь-1:
Путь-2:
Очевидно, что в способе 2 API REST потребуется способ распознавать и доверять токену как действительному. API входа выполнил проверку подлинности, и поэтому этот «ключ камердинера» должен доверять другим API REST в вашем каталоге.
Это, конечно, означает, что ключ / токен авторизации необходимо будет хранить и совместно использовать с REST API. Этот общий доверенный репозиторий токенов может быть локальным / федеративным, что позволяет API-интерфейсам REST других организаций доверять друг другу.
Но я отвлекся.
Дело в том, что «состояние» (о состоянии аутентификации клиента) необходимо поддерживать и совместно использовать, чтобы все API REST могли создать круг доверия. Если мы этого не делаем, что является способом-1, мы должны принять, что акт аутентификации должен быть выполнен для любых / всех поступающих запросов.
Выполнение аутентификации является ресурсоемким процессом. Представьте себе выполнение запросов SQL для каждого входящего запроса к вашему хранилищу пользователей для проверки соответствия uid / pwd. Или для шифрования и выполнения хеш-совпадений (стиль AWS). И архитектурно, каждый API REST должен будет выполнять это, я подозреваю, используя общую внутреннюю службу входа в систему. Потому что, если вы этого не сделаете, то вы засоряете код авторизации везде. Большой беспорядок
Чем больше слоев, тем больше задержка.
Теперь возьми Way-1 и подай заявку на HTM. Ваш (человеческий) пользователь действительно заботится, нужно ли вам отправлять uid / pwd / hash или что-то еще с каждым запросом? Нет, если вы не беспокоите ее, бросая страницу авторизации / входа в систему каждую секунду. Удачи, если у вас есть клиенты. Итак, что вы будете делать, это хранить информацию для входа в систему где-нибудь на стороне клиента, в браузере, в самом начале и отправлять ее при каждом запросе. Для пользователя (пользователя) она уже вошла в систему, и доступна «сессия». Но на самом деле она проходит проверку подлинности при каждом запросе.
То же самое с путем-2. Ваш (человек) пользователь никогда не заметит. Так что никакого вреда не было.
Что, если мы применим Путь 1 к МТМ? В этом случае, поскольку это машина, мы можем чертовски устать от этого парня, попросив его отправлять аутентификационную информацию при каждом запросе. Никому нет дела! Выполнение Way-2 на MTM не вызовет особой реакции; это чертова машина. Это может заботиться меньше!
Так что, действительно, вопрос в том, что соответствует вашим потребностям. Безгражданство имеет свою цену. Заплати цену и двигайся дальше. Если вы хотите быть пуристом, то заплатите цену за это и идите дальше.
В конце концов, философии не имеют значения. Что действительно важно, так это раскрытие информации, презентация и опыт потребления. Если люди любят ваши API, вы сделали свою работу.
Way-3
гибридного подхода. Клиент входит в систему как, Way-2
но, как и в случае Way-1
, учетные данные не проверяются для любого состояния на стороне сервера. В любом случае, токен авторизации создается и отправляется обратно клиенту как в Way-2
. Этот токен позже проверяется на подлинность с использованием асимметричной криптографии без поиска какого-либо конкретного состояния клиента.
Вот подлинно и полностью RESTful решение для аутентификации:
Когда клиент аутентифицируется:
3.1. выдать токен, который содержит следующее:
3.2. Зашифруйте токен с помощью закрытого ключа.
3.3. Отправьте зашифрованный токен обратно пользователю.
Когда пользователь получает доступ к любому API, он также должен передать свой токен авторизации.
Это аутентификация без сохранения состояния / RESTful.
Обратите внимание, что при включении хэша пароля пользователь также отправит незашифрованный пароль вместе с токеном аутентификации. Сервер может проверить, совпадает ли пароль с паролем, использованным для создания токена аутентификации, путем сравнения хешей. Безопасное соединение, использующее что-то вроде HTTPS, будет необходимо. Javascript на стороне клиента может обрабатывать получение пароля пользователя и сохранение его на стороне клиента, либо в памяти, либо в cookie-файле, возможно, зашифрованном с помощью открытого ключа сервера .
Если честно, я видел здесь отличные ответы, но меня немного беспокоит то, что кто-то доведет всю концепцию безгражданства до крайности, когда она станет догматичной. Это напоминает мне о тех старых фанатах Smalltalk, которые хотели только принять чистый ОО, и если что-то не является объектом, то вы делаете это неправильно. Дай мне перерыв.
Предполагается, что подход RESTful сделает вашу жизнь проще и сократит накладные расходы и затраты на сеансы, постарайтесь следовать им, как это целесообразно, но в ту минуту, когда вы следуете дисциплине (любой дисциплине / руководству) до крайности, когда больше не дает выгоды, для которой он был предназначен, тогда вы делаете это неправильно. Некоторые из лучших современных языков имеют функциональное программирование и объектную ориентацию.
Если самый простой способ решить вашу проблему - это сохранить ключ аутентификации в файле cookie и отправить его в заголовке HTTP, тогда сделайте это, только не злоупотребляйте им. Помните, что сессии плохие, когда они становятся тяжелыми и большими, если весь ваш сеанс состоит из короткой строки, содержащей ключ, то в чем же дело?
Я открыт для принятия исправлений в комментариях, но я просто не вижу смысла (пока) в том, чтобы сделать нашу жизнь несчастной, чтобы просто не хранить большой словарь хэшей на нашем сервере.
Прежде всего, веб-сервис RESTful является STATELESS (или, другими словами, SESSIONLESS). Следовательно, сервис RESTful не имеет и не должен иметь понятия сеанса или файлов cookie. Способ выполнения аутентификации или авторизации в службе RESTful заключается в использовании заголовка авторизации HTTP, как определено в спецификациях HTTP RFC 2616. Каждый отдельный запрос должен содержать заголовок авторизации HTTP, а запрос должен отправляться через соединение HTTP (SSL). Это правильный способ проверки подлинности и проверки авторизации запросов в веб-службах HTTP RESTful. Я реализовал веб-сервис RESTful для приложения Cisco PRIME Performance Manager в Cisco Systems. И как часть этого веб-сервиса, я также реализовал аутентификацию / авторизацию.
Это, конечно, не о «сеансовых ключах», поскольку обычно используется для обозначения бессессионной аутентификации, которая выполняется во всех ограничениях REST. Каждый запрос имеет самоописание и содержит достаточно информации для самостоятельной авторизации запроса без какого-либо состояния приложения на стороне сервера.
Самый простой способ достичь этого - начать с встроенных в HTTP механизмов аутентификации в RFC 2617 .
В «очень проницательной» статье, упомянутой @skrebel ( http://www.berenddeboer.net/rest/authentication.html ), обсуждается запутанный, но действительно неработающий метод аутентификации.
Вы можете попытаться посетить страницу (которая должна быть доступна для просмотра только авторизованному пользователю) http://www.berenddeboer.net/rest/site/authenticated.html без каких-либо учетных данных для входа.
(Извините, я не могу прокомментировать ответ.)
Я бы сказал, REST и аутентификация просто не смешиваются. REST означает безгражданство, но «заверенный» - это состояние. Вы не можете иметь их обоих на одном слое. Если вы являетесь защитником RESTful и недовольны состояниями, то вам придется использовать HTTPS (т.е. оставить проблему безопасности на другом уровне).
Я думаю, что спокойная аутентификация включает передачу токена аутентификации в качестве параметра в запросе. Примерами являются использование apikeys от api. Я не верю, что использование cookie-файлов или http-аутентификации оправдано.
Подход, упомянутый ранее ниже, по существу является типом предоставления OAuth2.0 « Учетная запись пароля владельца ресурса» . Это простой способ начать работу. Однако при таком подходе каждое приложение в организации будет иметь собственные механизмы аутентификации и авторизации. Рекомендуемый подход - тип предоставления «Код авторизации». Кроме того, в моем предыдущем ответе ниже я рекомендовал браузер localStorage для хранения токенов авторизации. Тем не менее, я пришел к выводу, что cookie является правильным вариантом для этой цели. В этом ответе StackOverflow я подробно изложил свои причины, подход к реализации типа предоставления кода авторизации, соображения безопасности и т . Д.
Я думаю, что следующий подход может быть использован для аутентификации службы REST:
При таком подходе мы выполняем дорогостоящую операцию по загрузке кеша с конкретными пользовательскими правами доступа каждые 30 минут. Таким образом, если доступ отменяется или предоставляется новый доступ, для его отражения требуется 30 минут или выход из системы с последующим входом в систему.
Вот способ сделать это: использование OAuth 2.0 для входа в систему .
Вы можете использовать другие методы аутентификации, отличные от Google, если они поддерживают OAuth.
Использование инфраструктуры открытого ключа, в которой регистрация ключа включает в себя надлежащее связывание, гарантирует, что открытый ключ будет привязан к человеку, которому он назначен, таким образом, чтобы обеспечить отказ от авторства.
См. Http://en.wikipedia.org/wiki/Public_key_infrastructure . Если вы соблюдаете надлежащие стандарты PKI, лицо или агент, который неправильно использует украденный ключ, может быть идентифицирован и заблокирован. Если агенту требуется использовать сертификат, привязка становится довольно жесткой. Умный и быстроходный вор может убежать, но они оставляют больше крошек.
Чтобы ответить на этот вопрос из моего понимания ...
Система аутентификации, которая использует 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 мы создали бы действие, которое выводит пользователя из системы и отправляет его обратно на домашнюю страницу.
GET на странице входа даст форму. POST на странице входа в систему будет рассматриваться как попытка входа в систему, при этом данные POST будут использоваться для входа в систему.
Для меня это практика использования методов HTTP, сопоставленных с их значением в базе данных, а затем создание системы аутентификации с учетом того, что вам не нужно передавать какие-либо идентификаторы сеансов или отслеживать сеансы.
Я все еще учусь - если вы обнаружите, что я сказал что-то неправильно, поправьте меня, и если вы узнаете больше, опубликуйте это здесь. Спасибо.
Советы действительны для защиты любого веб-приложения
Если вы хотите защитить свое приложение, то вам определенно следует начать с использования HTTPS вместо HTTP , это обеспечит создание безопасного канала между вами и пользователями, что предотвратит перехват данных, отправляемых пользователям назад и вперед, и поможет сохранить данные обменялись конфиденциально.
Вы можете использовать JWT (JSON Web Tokens) для защиты API RESTful , это имеет много преимуществ по сравнению с сеансами на стороне сервера, преимущества в основном:
1- Более масштабируемый, так как ваши серверы API не должны будут поддерживать сеансы для каждого пользователя (что может быть большим бременем, когда у вас много сеансов)
2 - JWT являются самодостаточными и имеют претензии, которые определяют роль пользователя, например, и к чему он может получить доступ и выпущен на дату и дату истечения срока действия (после чего JWT не будет действительным)
3. Легче обрабатывать балансировщики нагрузки, и если у вас несколько API-серверов, поскольку вам не нужно обмениваться данными сеанса и не настраивать сервер для маршрутизации сеанса на один и тот же сервер, когда запрос с JWT попадает на любой сервер, он может быть аутентифицирован & авторизовано
4- Меньшая нагрузка на вашу БД, а также вам не придется постоянно хранить и извлекать идентификатор сессии и данные для каждого запроса
5- JWT не могут быть подделаны, если вы используете сильный ключ для подписи JWT, поэтому вы можете доверять утверждениям в JWT, отправляемом с запросом, без необходимости проверять сеанс пользователя и проверять, авторизован он или нет , вы можете просто проверить JWT, и тогда вы все будете знать, кто и что может сделать этот пользователь.
Многие библиотеки предоставляют простые способы создания и проверки JWT на большинстве языков программирования, например: в node.js одним из самых популярных является jsonwebtoken
Поскольку API REST обычно нацелены на то, чтобы сервер не сохранял состояние, поэтому JWT более совместимы с этой концепцией, поскольку каждый запрос отправляется с помощью автономного токена авторизации (JWT), при этом серверу не нужно отслеживать сеанс пользователя по сравнению с сеансами, которые делают Сервер с состоянием, так что он запоминает пользователя и его роль, однако сессии также широко используются и имеют свои плюсы, которые вы можете искать, если хотите.
Важно отметить, что вы должны безопасно доставить JWT клиенту, используя HTTPS, и сохранить его в безопасном месте (например, в локальном хранилище).
Вы можете узнать больше о JWT по этой ссылке