SASL是面向连接的协议中的认证的一个框架。目前,PostgreSQL 仅实现了一个SASL认证机制SCRAM-SHA-256,但未来可能会添加更多。 下面的步骤说明了SASL认证通常如何执行,而下一小节给出了关于SCRAM-SHA-256的更多细节。
SASL 认证消息流
要开始SASL认证交换,服务器将发送一个AuthenticationSASL消息。 它包括一个服务器可以接受的SASL认证机制列表,按照服务器的首选顺序。
客户端从列表中选择一个受支持的机制,并向服务器发送SASLInitialResponse消息。 该消息包含所选机制的名称,以及可选的初始客户端响应(如果所选机制使用该机制)。
接下来将会有一个或多个服务器质询和客户端响应消息。 在AuthenticationSASLContinue消息中发送每个服务器质询, 然后在SASLResponse消息中发送来自客户端的响应。消息的细节是机制特定的。
最后,当认证交换成功完成时,服务器发送AuthenticationSASLFinal消息, 紧接着是AuthenticationOk消息。AuthenticationSASLFinal包含附加的服务器到客户端数据, 其内容特定于所选的认证机制。如果认证机制不使用在完成时发送的附加数据, 则不会发送AuthenticationSASLFinal消息。
出错时,服务器可以在任何阶段中止身份验证,并发送一个错误信息。
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密码, 并且不要求系统知道密码所使用的编码。
Channel binding尚未实现。
示例
服务器发送AuthenticationSASL消息。它包含服务器可以接受的SASL认证机制列表。
客户端通过发送SASLInitialResponse消息进行响应,该消息指示选择的机制SCRAM-SHA-256
。
在初始客户端响应字段中,该消息包含SCRAM client-first-message
。
服务器发送AuthenticationSASLContinue消息,内容为SCRAM
server-first message
。
客户端发送SASLResponse消息,内容为SCRAM
client-final-message
。
服务器发送AuthenticationSASLFinal消息,内容为SCRAM
server-final-message
,紧接着是一个AuthenticationOk消息。