52.3. Аутентификация SASL
SASL — это инфраструктура аутентификации для протоколов, ориентированных на соединения. На данный момент PostgreSQL реализует только один механизм SASL, SCRAM-SHA-256, но в будущем могут появиться и другие. Далее описывается, как в принципе осуществляется аутентификация SASL, а в следующем подразделе более подробно рассматривается SCRAM-SHA-256.
Поток сообщений аутентификации SASL
Чтобы начать обмен по схеме аутентификации SASL, сервер передаёт сообщение AuthenticationSASL. Оно содержит список механизмов аутентификации SASL, с которыми может работать сервер, в порядке предпочтений сервера.
Клиент выбирает один из поддерживаемых механизмов из списка и передаёт серверу сообщение SASLInitialResponse. Это сообщение содержит имя выбранного механизма и может содержать «Начальный ответ клиента», если это использует выбранный механизм.
За этим следует одно или нескольких сообщений вызова со стороны сервера и ответов со стороны клиента. Все вызовы сервер передаёт в сообщениях AuthenticationSASLContinue, а клиент отвечает на них сообщениями SASLResponse. Частные детали сообщений зависят от конкретного механизма.
Наконец, когда обмен аутентификационной информацией заканчивается успешно, сервер передаёт сообщение AuthenticationSASLFinal и сразу за ним сообщение AuthenticationOk. В сообщении AuthenticationSASLFinal передаются дополнительные данные от сервера клиенту, содержимое которых определяется выбранным механизмом аутентификации. Если механизм аутентификации не требует передавать дополнительные данные в завершение обмена, сообщение AuthenticationSASLFinal опускается.
В случае ошибки сервер может прервать процесс аутентификации на любом этапе и передать сообщение ErrorMessage.
52.3.1. Аутентификация SCRAM-SHA-256
Аутентификация SCRAM-SHA-256 (далее называемая просто SCRAM) — единственный реализованный на данный момент механизм SASL. Она подробно описывается в RFC 7677 и RFC 5802.
Когда в PostgreSQL задействуется SCRAM-SHA-256, сервер игнорирует имя пользователя, которое клиент передаёт в client-first-message
. Вместо этого используется имя, переданное ранее в стартовом сообщении. Согласно спецификации SCRAM, имя пользователя должно быть в UTF-8, но PostgreSQL поддерживает разные кодировки символов, и значит, имя пользователя PostgreSQL не всегда будет представимо в UTF-8.
В спецификации SCRAM говорится, что пароль также должен передаваться в UTF-8 и обрабатываться алгоритмом SASLprep. Однако PostgreSQL не требует, чтобы пароль представлялся в UTF-8. Когда устанавливается пароль пользователя, он обрабатывается алгоритмом SASLprep как пароль в UTF-8, вне зависимости от фактической кодировки. Однако если он представлен недопустимой для UTF-8 последовательностью байтов либо содержит комбинации байтов UTF-8, которые не принимает алгоритм SASLprep, это не будет считаться ошибкой — при аутентификации будет использоваться исходный пароль, без обработки SASLprep. Это позволяет нормализовать пароли, представленные в UTF-8, и при этом использовать пароли не в UTF-8, а также не требует, чтобы система знала, в какой кодировке задан пароль.
Связывание с каналом ещё не реализовано.
Пример
Сервер передаёт сообщение AuthenticationSASL. Оно содержит список механизмов аутентификации SASL, с которыми может работать сервер.
Клиент в ответ передаёт сообщение SASLInitialResponse, информирующее о выбранном механизме,
SCRAM-SHA-256
. В поле «Начального ответа клиента» это сообщение содержит данные SCRAMclient-first-message
.Сервер передаёт сообщение AuthenticationSASLContinue, содержащее данные SCRAM
server-first-message
.Клиент передаёт сообщение SASLResponse, содержащее данные SCRAM
client-final-message
.Сервер передаёт сообщение AuthenticationSASLFinal, содержащее данные SCRAM
server-final-message
, и сразу за ним сообщение AuthenticationOk.