Аутентификация и потоки OAuth2

Что это такое

Аутентификация отвечает на вопрос, кто вызывает систему, и в современном API вызывающий предъявляет обычно не пароль, а токен, выданный провайдером идентификации. OAuth2 описывает, как такой токен получают: кто просит доступ, кто аутентифицирует пользователя, чем клиент доказывает собственную личность и что позволяет выданное разрешение. От вида клиента и от того, присутствует ли при этом пользователь, зависит выбор потока.

Почему это важно

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

Ключевые идеи

Стороны различны, и их секреты тоже

Владельцем ресурса выступает пользователь, клиентом — приложение, которое просит доступ, сервер авторизации выдаёт токены, а сервер ресурсов их принимает, и для любого потока ключевой вопрос один: кто из этих сторон способен хранить секрет. Серверное приложение способно; страница в браузере и мобильное приложение — нет, и именно это закодировано в выборе потока.

пользователь -> клиент -> сервер авторизации -> токен -> сервер ресурсов

Authorization code с перенаправлением — вариант по умолчанию для клиентов с пользователем

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

Поток client credentials — для сервисов без пользователя

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

Секрет нельзя хранить в браузере или в мобильном бинарнике

Всё, что попало на устройство пользователя, можно прочитать, поэтому такой клиент приходится считать публичным. Любой поток, который требует от него хранить секрет, сломан по построению. Отсюда и дополнительный шаг доказательства, и вытеснение потока в стиле implicit grant, возвращавшего токен прямо в браузер.

Токены должны быть краткоживущими, а обновление — отдельным разрешением

Access token предъявляется при каждом запросе и чаще всего становится добычей копирования, поэтому срок его жизни должен быть коротким. Refresh token хранят тщательнее и используют только против сервера авторизации; им и получают новый access token, не тревожа пользователя лишний раз. Долгоживущие access token убирают запас прочности, благодаря которому утечку ещё можно пережить.

Области доступа выражают разрешение, а не роль пользователя

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

Практика

Выберите поток для трёх клиентов

Укажите, какой поток использует каждый из трёх клиентов — серверное веб-приложение, одностраничное приложение и ночная пакетная задача, — и где этот клиент хранит свой секрет.

Готово, когда: в каждом выборе названа сторона, хранящая секрет, и ни одному клиенту, не способному его хранить, секрет не вменяется.

Проследите жизненный цикл токена

Опишите последовательность от первого запроса пользователя до того момента, когда истёкший access token обновляют, и назовите, у какой стороны на каждом шаге находится каждая учётная единица.

Готово, когда: вы можете сказать, сколько access token остаётся действительным и что происходит с запросом в полёте, когда он истекает.

Частые ошибки

  • Хранение секрета клиента в браузере или мобильном приложении — его прочтёт кто угодно; исправить: считайте клиент публичным и выбирайте поток, не требующий секрета.
  • Использование долгоживущего access token — утечку нельзя ограничить сроком действия; исправить: держите access token коротким и обновляйте его.
  • Использование потока client credentials от имени пользователя — личность сервиса подменяет личность пользователя; исправить: берите поток, в котором участвует пользователь.
  • Трактовка области доступа как роли — узкое разрешение принимают за ограниченные полномочия; исправить: держите решения об авторизации отдельно от разрешения.
  • Работа с паролем пользователя внутри клиента — пароль оказывается под ударом собственных багов клиента; исправить: отправляйте пользователя на сервер авторизации.

Что читать дальше