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 中发送的用户名。而是使用已经在启动消息中发送的用户名。PostgreSQL 支持多种字符编码,而 SCRAM 规定用户名必须使用 UTF-8,因此可能无法用 UTF-8 表示 PostgreSQL 用户名。
SCRAM 规范规定密码也必须采用 UTF-8 编码,并通过 SASLprep 算法处理。不过,PostgreSQL 并不要求密码使用 UTF-8。设置用户密码时,无论实际采用何种编码,都会将其视作 UTF-8 并用 SASLprep 处理。但是,如果密码不是合法的 UTF-8 字节序列,或者包含 SASLprep 算法禁止的 UTF-8 字节序列,就会直接使用未经 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 消息。