Перейти к основному содержимому

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

примечание

Эта страница переведена при помощи нейросети GigaChat.

SASL — это фреймворк для аутентификации в протоколах, ориентированных на соединение. В настоящее время PostgreSQL реализует три механизма аутентификации SASL: SCRAM-SHA-256, SCRAM-SHA-256-PLUS и OAUTHBEARER. В будущем могут быть добавлены и другие. Приведенные ниже шаги иллюстрируют общий способ выполнения аутентификации SASL, а в следующих подразделах приводятся более подробные сведения о конкретных механизмах.

Поток сообщений аутентификации SASL:

  1. Чтобы начать обмен аутентификацией SASL, сервер отправляет сообщение AuthenticationSASL. Оно содержит список механизмов аутентификации SASL, которые сервер может принять, в предпочтительном для сервера порядке.
  2. Клиент выбирает один из поддерживаемых механизмов из списка и отправляет серверу сообщение SASLInitialResponse. Сообщение содержит имя выбранного механизма и необязательный Начальный ответ клиента, если выбранный механизм его использует.
  3. Далее следует одно или несколько сообщений с вызовом сервера и ответом клиента. Каждый вызов сервера отправляется в сообщении AuthenticationSASLContinue, за которым следует ответ клиента в сообщении SASLResponse. Детали сообщений зависят от механизма.
  4. Наконец, после успешного завершения обмена данными аутентификации сервер отправляет необязательное сообщение AuthenticationSASLFinal, за которым сразу же следует сообщение AuthenticationOk. AuthenticationSASLFinal содержит дополнительные данные от сервера к клиенту, содержимое которых имеет особый характер выбранному механизму аутентификации. Если механизм аутентификации не использует дополнительные данные, отправляемые при завершении, сообщение AuthenticationSASLFinal не отправляется.

При ошибке сервер может прервать аутентификацию на любом этапе и отправить сообщение ErrorMessage.

Аутентификация SCRAM-SHA-256

SCRAM-SHA-256 и его вариант с привязкой канала SCRAM-SHA-256-PLUS представляют собой механизмы аутентификации на основе паролей. Они подробно описаны в RFC 7677 и RFC 5802.

Когда в PostgreSQL используется SCRAM-SHA-256, сервер игнорирует имя пользователя, которое клиент отправляет в сообщении client-first-message. Вместо этого будет использоваться имя пользователя, которое уже было отправлено в стартовом сообщении. PostgreSQL поддерживает несколько кодировок символов, в то время как SCRAM предписывает использовать UTF-8 для имени пользователя, поэтому может оказаться невозможным представить имя пользователя PostgreSQL в UTF-8.

Согласно спецификации SCRAM, пароль также должен быть в UTF-8 и обрабатываться алгоритмом SASLprep. Однако PostgreSQL не требует, чтобы для пароля использовался UTF-8. Когда задается пароль пользователя, он обрабатывается алгоритмом SASLprep, как если бы он был в UTF-8, независимо от фактической используемой кодировки. Однако если пароль не является законной последовательностью байтов UTF-8 или содержит последовательности байтов UTF-8, запрещенные алгоритмом SASLprep, необработанный пароль будет использоваться без обработки SASLprep, вместо того чтобы выдать ошибку. Это позволяет нормализовать пароль, если он в UTF-8, но при этом использовать пароль, не содержащий UTF-8, и не требует, чтобы система знала, в какой кодировке используется пароль.

Связывание каналов поддерживается в сборках PostgreSQL с поддержкой SSL. Имя механизма SASL для SCRAM с привязкой к каналу - SCRAM-SHA-256-PLUS. Тип привязки канала, используемый PostgreSQL, - tls-server-end-point.

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

SCRAM с привязкой к каналу предотвращает такие атаки типа "человек посередине", подмешивая подпись сертификата сервера в передаваемый хеш пароля. Хотя поддельный сервер может повторно передать сертификат настоящего сервера, у него нет доступа к закрытому ключу, соответствующему этому сертификату, и поэтому он не может доказать, что является его владельцем, что приводит к разрыву SSL-соединения.

Пример

  1. Сервер отправляет сообщение AuthenticationSASL. Оно содержит список механизмов аутентификации SASL, которые сервер может принимать. Это будут SCRAM-SHA-256-PLUS и SCRAM-SHA-256, если сервер построен с поддержкой SSL, или только последний.
  2. В ответ клиент отправляет сообщение SASLInitialResponse, в котором указывает выбранный механизм, SCRAM-SHA-256 или SCRAM-SHA-256-PLUS. (Клиент может выбрать любой механизм, но для большей безопасности ему следует выбрать вариант с привязкой к каналу, если он может его поддерживать). В поле Initial Client response сообщение содержит сообщение SCRAM client-first-message. Сообщение client-first-message также содержит тип связывания каналов, выбранный клиентом.
  3. Сервер отправляет сообщение AuthenticationSASLContinue, содержимым которого является сообщение SCRAM server-first-message.
  4. Клиент отправляет сообщение SASLResponse, содержащее SCRAM client-final-message в качестве контента.
  5. Сервер отправляет сообщение AuthenticationSASLFinal, содержащее SCRAM server-final-message, за которым сразу же следует сообщение AuthenticationOk.

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

OAUTHBEARER — это механизм федеративной аутентификации на основе токенов. Он подробно описан в RFC 7628.

Типичный обмен отличается в зависимости от того, есть ли у клиента уже закэшированный bearer-токен для текущего пользователя. Если его нет, обмен происходит через два соединения: первое «дискавери»-соединение для получения метаданных OAuth с сервера и второе соединение для отправки токена после того, как клиент его получил. (libpq в настоящее время не реализует метод кэширования как часть своего встроенного потока, поэтому использует обмен в два соединения.)

Этот механизм инициируется клиентом, как и SCRAM. Начальный ответ клиента состоит из стандартного заголовка «GS2», используемого в SCRAM, за которым следует список пар ключ=значение. Единственный ключ, поддерживаемый сервером в настоящее время, — это auth, который содержит bearer-токен. OAUTHBEARER дополнительно определяет три необязательных компонента начального ответа клиента (authzid заголовка GS2, а также ключи host и port), которые в настоящее время игнорируются сервером.

OAUTHBEARER не поддерживает привязку к каналу, и механизм «OAUTHBEARER-PLUS» отсутствует. Этот механизм не использует данные сервера при успешной аутентификации, поэтому сообщение AuthenticationSASLFinal не используется в обмене.

Пример

  1. Во время первого обмена сервер отправляет сообщение AuthenticationSASL с рекламируемым механизмом OAUTHBEARER.

  2. Клиент отвечает отправкой сообщения SASLInitialResponse, которое указывает механизм OAUTHBEARER. Предполагая, что у клиента еще нет действительного bearer-токена для текущего пользователя, поле auth пусто, что указывает на дискавери-соединение.

  3. Сервер отправляет сообщение AuthenticationSASLContinue, содержащее статус ошибки вместе с well-known URI и scopes, которые клиент должен использовать для проведения OAuth-потока.

  4. Клиент отправляет сообщение SASLResponse, содержащее пустой набор (один байт 0x01), чтобы завершить свою часть обмена на этапе дискавери.

  5. Сервер отправляет ErrorMessage для завершения первого обмена с ошибкой.

    На этом этапе клиент проводит один из множества возможных OAuth-потоков для получения bearer-токена, используя любые метаданные, с которыми он был настроен, в дополнение к предоставленным сервером. (Это описание намеренно оставлено расплывчатым; OAUTHBEARER не определяет и не предписывает какой-либо конкретный метод получения токена.)

    Как только у клиента есть токен, клиент переподключается к серверу для финального обмена:

  6. Сервер снова отправляет сообщение AuthenticationSASL с рекламируемым механизмом OAUTHBEARER.

  7. Клиент отвечает отправкой сообщения SASLInitialResponse, но на этот раз поле auth в сообщении содержит bearer-токен, который был получен во время клиентского потока.

  8. Сервер валидирует токен согласно инструкциям провайдера токенов. Если клиент авторизован для подключения, он отправляет сообщение AuthenticationOk для завершения SASL-обмена.