20.10. LDAP 认证 #
这种认证方法的工作方式与 password 类似,只不过它使用 LDAP 作为密码验证方法。LDAP 只用于验证用户名/密码对。因此,在使用 LDAP 进行认证之前,用户必须已经存在于数据库中。
LDAP 认证可以在两种模式下工作。第一种模式称为简单绑定模式,服务器会绑定到按 prefix username suffix 形式构造出的可分辨名称。通常,prefix 参数用于指定 cn=,或在 Active Directory 环境中指定 DOMAIN\。suffix 则用于指定非 Active Directory 环境中 DN 的剩余部分。
第二种模式称为搜索+绑定模式,服务器首先使用由 ldapbinddn 和 ldapbindpasswd 指定的固定用户名和密码绑定到 LDAP 目录,并搜索试图登录数据库的用户。如果没有配置用户名和密码,则会尝试对目录进行匿名绑定。搜索会在 ldapbasedn 指定的子树上进行,并尝试对 ldapsearchattribute 指定的属性做精确匹配。一旦在搜索中找到了该用户,服务器就会作为该用户重新绑定到目录,并使用客户端指定的密码来验证登录是否正确。这种模式与 Apache mod_authnz_ldap 和 pam_ldap 等软件中的 LDAP 认证方案相同。这种方法使目录中用户对象的位置更具灵活性,但会对 LDAP 服务器额外发起两次请求。
以下配置选项在两种模式下都使用:
ldapserver#要连接的 LDAP 服务器的名称或 IP 地址。可以指定多个服务器,用空格分隔。
ldapport#要连接的 LDAP 服务器的端口号。如果未指定端口,则将使用 LDAP 库的默认端口设置。
ldapscheme#设置为
ldaps以使用 LDAPS。这是一种非标准的通过 SSL 使用 LDAP 的方式,受一些 LDAP 服务器实现支持。另请参阅ldaptls选项作为替代。ldaptls#设置为 1 以使 PostgreSQL 和 LDAP 服务器之间的连接使用 TLS 加密。这使用
StartTLS操作,参见 RFC 4513。另请参阅ldapscheme选项作为替代。
注意使用 ldapscheme 或 ldaptls 仅会加密 PostgreSQL 服务器和 LDAP 服务器之间的通信。PostgreSQL 服务器和 PostgreSQL 客户端之间的连接仍是未加密的,除非也在其上使用 SSL。
下列选项只被用于简单绑定模式:
以下选项仅在搜索+绑定模式中使用:
以下选项提供了另一种写法,可以用更紧凑、标准的形式表示上述部分 LDAP 选项:
ldapurl#一个 RFC 4516 LDAP URL。格式为
ldap[s]://
host[:port]/basedn[?[attribute][?[scope][?[filter]]]]scope必须是base、one、sub中的一个,通常是最后一个。(默认为base,在此应用中通常无用。)attribute可以指定单个属性,此时将用作ldapsearchattribute的值。如果attribute为空,则filter可用作ldapsearchfilter的值。URL 方案
ldaps会选择 LDAPS 方法,通过 SSL 建立 LDAP 连接,等同于使用ldapscheme=ldaps。要通过StartTLS操作使用加密的 LDAP 连接,请使用普通的 URL 方案ldap,并在ldapurl之外指定ldaptls选项。对于非匿名绑定,必须将
ldapbinddn和ldapbindpasswd指定为单独的选项。LDAP URL 目前仅受 OpenLDAP 支持,不支持 Windows。
将简单绑定选项与搜索+绑定选项混用是错误的。若要在简单绑定模式下使用 ldapurl,该 URL 中不能包含 basedn 或查询元素。
在使用搜索+绑定模式时,可以使用由 ldapsearchattribute 指定的单个属性执行搜索,也可以使用由 ldapsearchfilter 指定的自定义搜索过滤器执行搜索。指定 ldapsearchattribute=foo 等价于指定 ldapsearchfilter="(foo=$username)"。如果两个选项都未指定,则默认使用 ldapsearchattribute=uid。
如果 PostgreSQL 编译时使用了 OpenLDAP 作为 LDAP 客户端库,则可以省略 ldapserver 设置。在这种情况下,会通过 RFC 2782 DNS SRV 记录查找主机名和端口列表。查找的名称是 _ldap._tcp.DOMAIN,其中 DOMAIN 从 ldapbasedn 中提取。
下面是一个简单绑定 LDAP 配置示例:
host ... ldap ldapserver=ldap.example.net ldapprefix="cn=" ldapsuffix=", dc=example, dc=net"
当请求以数据库用户 someuser 连接数据库服务器时,PostgreSQL 将尝试使用 DN cn=someuser, dc=example, dc=net 和客户端提供的密码绑定到 LDAP 服务器。如果该连接成功,数据库访问就会被授予。
下面是另一种简单绑定配置,它使用 LDAPS 方案和自定义端口号,并以 URL 形式写出:
host ... ldap ldapurl="ldaps://ldap.example.net:49151" ldapprefix="cn=" ldapsuffix=", dc=example, dc=net"
这种写法比单独指定 ldapserver、ldapscheme 和 ldapport 稍微更紧凑。
下面是一个搜索+绑定配置示例:
host ... ldap ldapserver=ldap.example.net ldapbasedn="dc=example, dc=net" ldapsearchattribute=uid
当请求以数据库用户 someuser 连接数据库服务器时,PostgreSQL 将尝试对 LDAP 服务器进行匿名绑定(因为未指定 ldapbinddn),并在指定的基础 DN 下执行一次 (uid=someuser) 搜索。如果找到了对应条目,随后就会尝试使用该条目的信息以及客户端提供的密码进行绑定。如果第二次绑定成功,数据库访问就会被授予。
下面是以 URL 形式写出的同一个搜索+绑定配置:
host ... ldap ldapurl="ldap://ldap.example.net/dc=example,dc=net?uid?sub"
某些支持 LDAP 认证的其他软件也使用相同的 URL 格式,因此共享这类配置会更容易。
这里是一个搜索+绑定配置的示例,它使用 ldapsearchfilter 而不是 ldapsearchattribute 来允许用用户 ID 或电子邮件地址进行认证:
host ... ldap ldapserver=ldap.example.net ldapbasedn="dc=example, dc=net" ldapsearchfilter="(|(uid=$username)(mail=$username))"
这是一个搜索+绑定配置的示例,它使用 DNS SRV 发现来查找域名 example.net 的 LDAP 服务的主机名和端口。
host ... ldap ldapbasedn="dc=example,dc=net"
提示
如示例中所示,由于 LDAP 通常使用逗号和空格来分隔一个 DN 的不同部分,在配置 LDAP 选项时通常有必要使用双引号包围的参数值。
报告文档问题
阅读 上游文档. 通过 PostgreSQL 文档反馈表单.