支持的版本:当前 (17) / 16 / 15 / 14 / 13
开发版本:devel
不支持的版本:12 / 11 / 10

53.3. SASL 身份验证 #

SASL 是面向连接协议中身份验证的框架。目前,PostgreSQL 实现了两种 SASL 身份验证机制:SCRAM-SHA-256 和 SCRAM-SHA-256-PLUS。未来可能会添加更多机制。以下步骤说明了通常如何执行 SASL 身份验证,而下一小节则详细介绍了 SCRAM-SHA-256 和 SCRAM-SHA-256-PLUS。

SASL 身份验证消息流

  1. 要开始 SASL 身份验证交换,服务器会发送一个 AuthenticationSASL 消息。其中包含服务器可以接受的 SASL 身份验证机制列表,并按服务器的首选顺序排列。

  2. 客户端从列表中选择一个支持的机制,并向服务器发送 SASLInitialResponse 消息。该消息包括所选机制的名称,以及可选的初始客户端响应(如果所选机制使用)。

  3. 接下来会有一个或多个服务器质询和客户端响应消息。每个服务器质询都在 AuthenticationSASLContinue 消息中发送,随后客户端在 SASLResponse 消息中做出响应。消息的具体细节是特定于机制的。

  4. 最后,当身份验证交换成功完成时,服务器会发送 AuthenticationSASLFinal 消息,然后立即发送 AuthenticationOk 消息。AuthenticationSASLFinal 包含额外的服务器到客户端数据,其内容特定于所选的身份验证机制。如果身份验证机制不使用在完成时发送的额外数据,则不会发送 AuthenticationSASLFinal 消息。

如果出现错误,服务器可以在任何阶段中止身份验证,并发送 ErrorMessage。

53.3.1. SCRAM-SHA-256 身份验证 #

目前实现的 SASL 机制是 SCRAM-SHA-256 及其带有通道绑定的变体 SCRAM-SHA-256-PLUS。它们在 RFC 7677RFC 5802 中有详细描述。

当在 PostgreSQL 中使用 SCRAM-SHA-256 时,服务器会忽略客户端在 client-first-message 中发送的用户名。而是使用启动消息中已经发送的用户名。PostgreSQL 支持多种字符编码,而 SCRAM 规定用户名必须使用 UTF-8,因此可能无法用 UTF-8 表示 PostgreSQL 用户名。

SCRAM 规范规定密码也必须使用 UTF-8,并使用 SASLprep 算法进行处理。PostgreSQL 不需要对密码使用 UTF-8。当设置用户的密码时,会使用 SASLprep 进行处理,就好像它是 UTF-8 格式一样,而不管实际使用的编码如何。但是,如果它不是合法的 UTF-8 字节序列,或者它包含 SASLprep 算法禁止的 UTF-8 字节序列,则将使用原始密码而不进行 SASLprep 处理,而不是抛出错误。这允许在密码为 UTF-8 格式时对其进行规范化,但仍然允许使用非 UTF-8 密码,并且不需要系统知道密码的编码格式。

在具有 SSL 支持的 PostgreSQL 构建版本中支持通道绑定。带有通道绑定的 SCRAM 的 SASL 机制名称为 SCRAM-SHA-256-PLUS。PostgreSQL 使用的通道绑定类型为 tls-server-end-point

SCRAM不带通道绑定的情况下,服务器会选择一个随机数,该随机数将传输给客户端,以便与传输的密码哈希中的用户提供的密码混合。虽然这可以防止在以后的会话中成功重新传输密码哈希,但它无法阻止真实服务器和客户端之间的虚假服务器通过服务器的随机值并成功进行身份验证。

SCRAM使用通道绑定可以通过将服务器证书的签名混合到传输的密码哈希中来防止此类中间人攻击。虽然虚假服务器可以重新传输真实服务器的证书,但它无法访问与该证书匹配的私钥,因此无法证明它是所有者,从而导致 SSL 连接失败。

示例

  1. 服务器发送 AuthenticationSASL 消息。它包含服务器可以接受的 SASL 身份验证机制列表。如果服务器是使用 SSL 支持构建的,则此列表将为 SCRAM-SHA-256-PLUSSCRAM-SHA-256,否则仅为后者。

  2. 客户端通过发送 SASLInitialResponse 消息来响应,该消息指示选择的机制:SCRAM-SHA-256SCRAM-SHA-256-PLUS。(客户端可以自由选择任一机制,但为了提高安全性,如果可以支持,则应选择通道绑定变体。)在初始客户端响应字段中,该消息包含 SCRAM client-first-messageclient-first-message 还包含客户端选择的通道绑定类型。

  3. 服务器发送 AuthenticationSASLContinue 消息,其中包含 SCRAM server-first-message 作为内容。

  4. 客户端发送 SASLResponse 消息,其中包含 SCRAM client-final-message 作为内容。

  5. 服务器发送 AuthenticationSASLFinal 消息,其中包含 SCRAM server-final-message,然后立即发送 AuthenticationOk 消息。

提交更正

如果您在文档中发现任何不正确的内容,与特定功能的体验不符或需要进一步澄清的内容,请使用此表单报告文档问题。