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

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

    Как обрабатывать аутентификацию в архитектуре 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== 

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

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

    Сессия через cookies

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

    Одной из возможностей может быть сохранение всех данных в содержимом файла 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.

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

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

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

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

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

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

     GET /object?apiKey=Qwerty2010 

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

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

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

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

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

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

    Вывод

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

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

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

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

    Очень проницательная статья, которая решает эти вопросы по пунктам, здесь , но это приводит к большому браузеру 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 просто используется для адресации ресурса на стороне сервера, так же как язык приема может использоваться для доступа к ресурсам перевода и т. Д. Я чувствую, что это то же самое, но, может быть, другие нет? Что вы думаете, ребята?

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

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

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

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

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

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

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

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

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

    Путь-1:

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

    Путь-2:

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

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

    Это, конечно, означает, что ключ / токен аутентификации должен быть сохранен и распространен среди API REST. Этот общий, доверенный repository токенов может быть локальным / федеративным, что позволяет 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, вы сделали свою работу.

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

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

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

      • Время истечения
      • имя пользователя (необязательно)
      • пользователи IP (необязательно)
      • hash пароля (необязательно)

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

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

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

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

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

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

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

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

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

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

    Прежде всего, веб-служба RESTful является БЕЗОПАСНОЙ (или, другими словами, БЕСПЛАТНО ). Таким образом, служба 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 (т.е. оставить проблему безопасности на другом уровне).

    I think restful authentication involves the passing of an authentication token as a parameter in the request. Examples are the use of apikeys by api’s. I don’t believe the use of cookies or http auth qualifies.

    I think the following approach can be used for REST service authentication:

    1. Create a login RESTful API to accept username and password for authentication. Use HTTP POST method to prevent caching and SSL for security during transit On successful authentication, the API returns two JWTs – one access token (shorter validity, say 30 minutes) and one refresh token (longer validity, say 24 hours)
    2. The client (a web based UI) stores the JWTs in local storage and in every subsequent API call passes the access token in “Authorization: Bearer #access token” header
    3. The API checks the validity of the token by verifying the signature and expiry date. If the token is valid, check if the user (It interprets the “sub” claim in JWT as username) has access to the API with a cache lookup. If the user is authorized to access the API, execute the business logic
    4. If the token is expired, the API returns HTTP response code 400
    5. The client, on receiving 400/401, invokes another REST API with the refresh token in “Authorization: Bearer #refresh token” header to get a new access token.
    6. On receiving the call with refresh token, check if the refresh token is valid by checking the signature and the expiry date. If the refresh token is valid, refresh the access right cache of the user from DB and return new access token and refresh token. If the refresh token is invalid, return HTTP response code 400
    7. If a new access token and refresh token are returned, go to step 2. If HTTP response code 400 is returned, the client assumes that the refresh token has expired and asks for username and password from the user
    8. For logout, purge the local storage

    With this approach we are doing the expensive operation of loading the cache with user specific access right details every 30 minutes. So if an access is revoked or new access is granted, it takes 30 minutes to reflect or a logout followed by a login.

    That’s the way to do that: Using OAuth 2.0 for Login .

    You may use other authentication methods other then Google’s as long as it supports OAuth.

    To answer this question from my understanding…

    An authentication system that uses REST so that you do not need to actually track or manage the users in your system. This is done by using the HTTP methods POST, GET, PUT, DELETE. We take these 4 methods and think of them in terms of database interaction as CREATE, READ, UPDATE, DELETE (but on the web we use POST and GET because that is what anchor tags support currently). So treating POST and GET as our CREATE/READ/UPDATE/DELETE (CRUD) then we can design routes in our web application that will be able to deduce what action of CRUD we are achieving.

    For example, in a Ruby on Rails application we can build our web app such that if a user who is logged in visits http://store.com/account/logout then the GET of that page can viewed as the user attempting to logout. In our rails controller we would build an action in that logs the user out and sends them back to the home page.

    A GET on the login page would yield a form. a POST on the login page would be viewed as a login attempt and take the POST data and use it to login.

    To me, it is a practice of using HTTP methods mapped to their database meaning and then building an authentication system with that in mind you do not need to pass around any session id’s or track sessions.

    I’m still learning — if you find anything I have said to be wrong please correct me, and if you learn more post it back here. Благодарю.

    Using a Public key infrastruction in which the registration of a key involves proper binding ensures that the public key is bound to the individual to which it is assigned in a way that ensures non-repudiation

    See http://en.wikipedia.org/wiki/Public_key_infrastructure . If you follow the proper PKI standards, the person or agent who improperly uses the stolen key can be identified and locked out. If the agent is required to use a certificate, the binding gets pretty tight. A clever and quick-moving thief can escape, but they leave more crumbs.

    Давайте будем гением компьютера.