Аутентификация, авторизация и управление сеансом в традиционных веб-приложениях и API

Исправьте меня, если я ошибаюсь: в традиционном веб-приложении браузер автоматически добавляет информацию о сеансе в запрос на сервер, поэтому сервер может узнать, от кого запрос. Что конкретно добавлено на самом деле?

Однако в приложении на основе API эта информация не отправляется автоматически, поэтому при разработке API я должен проверить себя, если запрос поступает от аутентифицированного пользователя, например? Как это обычно делается?

Ответ 1

Протокол HTTP не имеет аналогов по дизайну, каждый запрос выполняется отдельно и выполняется в отдельном контексте.

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

Cookies

В типичном случае браузера-сервера; браузер управляет списком пар ключ/значение, известный как файлы cookie, для каждого домена:

  • Файлы cookie могут управляться сервером (созданным/измененным/удаленным) с помощью заголовка ответа Set-Cookie HTTP.
  • Доступ к файлам cookie можно получить на сервере (чтение) путем разбора заголовка запроса HTTP Cookie.

Веб-ориентированные языки программирования/фреймворки предоставляют функции для обработки файлов cookie на более высоком уровне, например, PHP предоставляет setcookie/$_COOKIE, чтобы писать/читать файлы cookie.

Сессия

Назад к сеансам. В типичном случае браузера-сервера (снова) серверное управление сеансом использует преимущества управления файлами cookie на стороне клиента. Управление сеансом PHP устанавливает cookie идентификатора сеанса и использует его для идентификации последующих запросов.

API веб-приложений?

Теперь вернемся к вашему вопросу; так как вы будете ответственны за проектирование API и документируете его, реализация будет вашим решением. Вы в основном должны

  • предоставить клиенту идентификатор, будь то с помощью заголовка ответа HTTP Set-Cookie, внутри тела ответа (ответ XML/JSON).
  • есть механизм для поддержания связи идентификатора/клиента. например таблицу базы данных, которая связывает идентификатор 00112233445566778899aabbccddeeff с клиентом/пользователем # 1337.
  • попросите клиента повторно отправить идентификатор, отправленный ему в (1.) во всех последующих запросах, будь то в заголовке запроса HTTP Cookie, a ?sid=00112233445566778899aabbccddeeff param (*).
  • найдите полученный идентификатор, используя механизм в (2.), проверьте правильность аутентификации и авторизуйтесь для выполнения запрошенной операции, а затем выполните операцию от имени пользователя auth'd.

Конечно, вы можете опираться на существующую инфраструктуру, вы можете использовать управление сеансами PHP (которое позаботится о 1..2 и части аутентификации 4.) в вашем приложении и потребовать, чтобы на стороне клиента выполнялись файлы cookie (что будет заботиться о 3.), а затем вы оставите всю свою логику приложения.


(*) У каждого подхода есть минусы и профи, например, использование параметра запроса GET проще реализовать, но может иметь последствия для безопасности, поскольку запросы GET регистрируются. Вы должны использовать https для критических (все?) Приложений.

Ответ 2

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

session_start();  // Will create a cookie named PHPSESSID with the session token

После создания сеанса вы можете сохранить на нем данные. Например, если вы хотите сохранить пользователя в журнале:

// If username and password match, you can just save the user id on the session
$_SESSION['userID'] = 123;

Теперь вы можете проверить, аутентифицирован ли пользователь или нет:

if ($_SESSION['userID'])
    echo 'user is authenticated';
else
    echo 'user isn't authenticated';       

Если вы хотите, вы можете создать сеанс только для аутентифицированного пользователя:

if (verifyAccountInformation($user,$pass)){ // Check user credentials
    // Will create a cookie named PHPSESSID with the session token
    session_start();
    $_SESSION['userID'] = 123;
}

Ответ 3

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

Кроме того, в классических веб-приложениях после аутентификации и авторизации пользователя (в основном путем поиска пары имени пользователя и пароля в базе данных), информация авторизации и идентификации записывается в хранилище сеансов. Хранилище сеансов не обязательно должно быть на стороне сервера, так как большинство приведенных выше ответов предлагает, оно также может быть сохранено в cookie на стороне клиента, зашифрованном в большинстве случаев. Например, инфраструктура PHP CodeIgniter делает это по умолчанию. Существует ряд механизмов защиты сеанса на стороне клиента, и я не вижу, чтобы этот способ хранения данных сеанса был менее безопасным, чем хранение sessionId, который затем просматривается в хранилище сеансов на стороне сервера. Кроме того, хранение клиентской стороны сеанса довольно удобно в распределенной среде, поскольку устраняет необходимость в разработке решения (или с использованием уже существующего) для управления центральным сеансом на стороне сервера.

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

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

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

Со всеми этими словами я бы сказал, что ответы на следующий вопрос вводят процедуру принятия решения о выборе механизма авторизации/аутентификации для WebApi:

1) Какая целевая аудитория, общедоступная ли она или только для зарегистрированных (платных) участников?
2) Выполняется ли это или * NIX или платформа MS
3) Какое количество пользователей ожидается
4) Насколько чувствителен API данных с данными (более сильные и слабые механизмы аутентификации)
5) Существует ли какая-либо служба единого входа, которую вы могли бы использовать

.. и многое другое.

Надеюсь, что это очистит бит, так как в уравнении есть много переменных.

Ответ 4

Если APP на основе API является клиентом, тогда API должен иметь возможность извлекать/читать файлы cookie из потока ответов сервера и хранить его. Для автоматического добавления файлов cookie при подготовке объекта запроса для того же сервера/URL-адреса. Если он недоступен, идентификатор сеанса не может быть восстановлен.

Ответ 5

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

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

Существует множество других механизмов аутентификации для HTTP-интерфейсов API, базового/дайджеста HTTP, чтобы назвать пару, и, конечно же, вездесущего o-auth, который специально разработан для этих вещей, если я не ошибаюсь. Никакие файлы cookie не поддерживаются, учетные данные являются частью каждого обмена (достаточно уверен в этом).

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

Ответ 6

Я бы предложил вам отправить какой-то токен с каждым запросом.

В зависимости от сервера и сервиса они могут быть JSESSIONID в вашем запросе GET/POST или что-то зрелом, как SAML в SOAP через HTTP в запросе веб-службы.