Безопасность

·5 мин чтения·Обновлено

OAuth 2.0: почему партнёрам не стоит выдавать пароль от вашей системы

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

Сервис согласования встреч просит пароль от корпоративного календаря. Ему нужно найти свободное время и создать приглашение, но вместе с паролем он может получить совсем другие возможности. А при отказе от интеграции придётся выяснять, где ещё использовались те же учётные данные.

OAuth 2.0 позволяет выдать приложению ограниченный доступ, не передавая основной пароль пользователя. Однако слово «ограниченный» описывает результат проектирования. Сам протокол не знает, нужен ли организатору встреч текст всех событий, право удалять их или доступ к календарям всей компании.

Кто получает право и на чьи данные

В типичном сценарии пользователь подтверждает доступ через доверенную систему выдачи разрешений, а стороннее приложение получает access token — учётные данные для обращения к определённому API. Сам API проверяет токен и допустимость действия. Это отдельные обязанности, даже если все компоненты предоставляет один поставщик.

Не каждый сценарий требует человека перед экраном согласия. Интеграция может работать от имени организации или самого приложения по заранее выданным полномочиям. Например, client credentials предназначен для подходящих доверенных серверных клиентов. Поэтому отсутствие пользовательского делегирования само по себе не делает OAuth ненужным. Обе модели предусмотрены в RFC 6749.

Для встречи нужно договориться о владельце разрешения: отдельный сотрудник подключает свой календарь или администратор разрешает работу с назначенной группой. Уход сотрудника и расторжение договора с поставщиком тогда приводят к разным действиям. Модель стоит записать до первой интеграции, иначе технический токен переживёт своё бизнес-основание.

Вход и доступ к API — не одно обещание

Кнопку «войти через другой сервис» часто называют OAuth-входом. Но OAuth отвечает прежде всего за доступ к ресурсам. Для стандартного подтверждения личности поверх него используется OpenID Connect. Он даёт клиенту сведения об аутентификации пользователя, в том числе через ID token.

ID token и access token имеют разное назначение. Первый нельзя считать универсальным пропуском к произвольному API. И сам access token не обязан быть JWT — определённым форматом подписанных данных. Способ проверки зависит от контракта сервера. Наличие похожей строки в запросе ещё не доказывает ни личность, ни право на действие.

Разрешение «читать календарь» может быть слишком широким

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

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

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

Не воспроизводить старые схемы только потому, что они поддерживаются

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

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

Браузерное или мобильное приложение не может надёжно скрыть общий client secret внутри распространяемого кода. Серверный клиент с защищённым хранением — другая модель. Выбранная библиотека и сервер должны соответствовать типу клиента; самодельная проверка «токен похож на настоящий» здесь неуместна.

«Отключить интеграцию» нужно проверить на уже выданном доступе

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

RFC 7009 описывает отзыв и отмечает возможность задержки распространения. Если API проверяет только подпись и срок автономного токена, оно может не узнать об отзыве немедленно без дополнительного механизма. Среди вариантов — короткий срок и проверка актуального состояния через introspection. Кэширование её результата тоже влияет на задержку.

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

Проверять подключение вместе с расставанием

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

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