Как обрабатывать аутентификацию в архитектуре RESTful клиент-сервер - вопрос спорный.
Обычно этого можно добиться в мире SOA через HTTP с помощью:
- Базовая аутентификация HTTP через HTTPS;
- Cookies и управление сессиями;
- токен в заголовках HTTP (например, OAuth 2.0 + JWT);
- Запрос аутентификации с дополнительными параметрами подписи.
Вам придется адаптировать или даже лучше смешать эти методы, чтобы в лучшем случае соответствовать архитектуре вашего программного обеспечения.
У каждой схемы аутентификации есть свои PRO и CON, в зависимости от цели вашей политики безопасности и архитектуры программного обеспечения.
Базовая аутентификация HTTP через HTTPS
Это первое решение, основанное на стандартном протоколе HTTPS, используется большинством веб-сервисов.
GET /spec.html HTTP/1.1
Host: www.example.org
Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==
Это легко реализовать, доступно по умолчанию во всех браузерах, но имеет некоторые известные недостатки, такие как ужасное окно аутентификации, отображаемое в браузере, которое будет сохраняться (здесь нет функции, подобной LogOut), некоторые дополнительные функции на стороне сервера Использование ЦП и тот факт, что имя пользователя и пароль передаются (через HTTPS) на Сервер (должно быть более безопасно, чтобы пароль оставался только на стороне клиента, во время ввода с клавиатуры и сохранялся как безопасный хеш при Сервер).
Мы можем использовать Дайджест-аутентификацию , но для этого также требуется HTTPS, поскольку он уязвим для MiM или Воспроизведение атак и специфичен для HTTP.
Сессия с помощью файлов cookie
Честно говоря, сеанс, управляемый на Сервере, не является действительно безгосударственным.
Одной из возможностей может быть сохранение всех данных в содержимом cookie. И, в соответствии с этим, cookie обрабатывается на стороне сервера (фактически клиент даже не пытается интерпретировать эти данные cookie: он просто передает их обратно на сервер при каждом последующем запросе). Но эти cookie-данные являются данными состояния приложения, поэтому ими должен управлять клиент, а не сервер, в чистом мире без сохранения состояния.
GET /spec.html HTTP/1.1
Host: www.example.org
Cookie: theme=light; sessionToken=abc123
Сама техника cookie связана с HTTP, поэтому она не является действительно RESTful, которая должна быть независимой от протокола, ИМХО. Он уязвим для 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, который требуется в дополнение к любой схеме аутентификации.