注意
LDAP可插拔身份验证是商业产品MySQL Enterprise Edition中包含的扩展。要了解有关商业产品的更多信息,请参见https://www.mysql.com/products/。

MySQL Enterprise Edition支持一种身份验证方法,该方法使MySQL Server可以通过访问目录服务(例如X.500)来使用LDAP(轻型目录访问协议)来对MySQL用户进行身份验证。MySQL使用LDAP来获取用户,凭证和组信息。

LDAP可插拔身份验证提供以下功能:

外部身份验证:LDAP身份验证使MySQL Server能够接受来自LDAP目录中MySQL授予表之外定义的用户的连接。

代理用户支持:LDAP身份验证可以基于外部用户所属的LDAP组,将与客户端程序传递的外部用户名不同的用户名返回给MySQL。这意味着LDAP插件可以返回MySQL用户,该用户定义了外部LDAP认证用户应具有的特权。例如,名为LDAP用户joe可以连接并有一个名为MySQL用户的权限 developer,如果用于LDAP组 joe是developer。

安全性:使用TLS,可以确保与LDAP服务器的连接安全。

下表显示了用于简单的基于SASL的LDAP身份验证的插件和库文件名。文件名后缀在您的系统上可能有所不同。文件必须位于plugin_dir系统变量命名的目录中 。

表6.18用于简单LDAP身份验证的插件和库名称

插件或文件 插件或文件名
服务器端插件名称 authentication_ldap_simple
客户端插件名称 mysql_clear_password
库文件名 authentication_ldap_simple.so

表6.19基于SASL的LDAP身份验证的插件和库名称

插件或文件 插件或文件名
服务器端插件名称 authentication_ldap_sasl
客户端插件名称 authentication_ldap_sasl_client
库文件名 authentication_ldap_sasl.so, authentication_ldap_sasl_client.so

库文件仅包含 身份验证插件。客户端 插件内置在 客户端库中。 authentication_ldap_XXXmysql_clear_passwordlibmysqlclient

每个服务器端LDAP插件均与特定的客户端插件一起使用:

服务器端 authentication_ldap_simple插件执行简单的LDAP身份验证。对于使用此插件的帐户进行的连接,客户端程序使用客户端mysql_clear_password插件,该客户端插件将密码以明文形式发送到服务器。不使用密码哈希或加密,因此建议在MySQL客户端和服务器之间建立安全连接以防止密码泄露。

服务器端authentication_ldap_sasl 插件执行基于SASL的LDAP身份验证。对于使用此插件的帐户进行的连接,客户端程序使用客户端 authentication_ldap_sasl_client插件。客户端和服务器端SASL LDAP插件使用SASL消息在LDAP协议内安全地传输凭据,以避免在MySQL客户端和服务器之间发送明文密码。

以下各节提供特定于LDAP可插拔身份验证的安装和使用信息:

LDAP可插入身份验证的先决条件

MySQL用户的LDAP身份验证如何工作

安装LDAP可插入身份验证

卸载LDAP可插入身份验证

使用LDAP可插入身份验证

简单LDAP认证

基于SASL的LDAP身份验证

LDAP认证用户DN后缀

LDAP身份验证与代理

LDAP身份验证组首选项和映射规范

有关MySQL中的可插入身份验证的一般信息,请参见第6.2.17节“可插入身份验证”。有关mysql_clear_password插件的信息,请参见 第6.4.1.4节“客户端明文可插入身份验证”。有关代理用户的信息,请参见第6.2.18节“代理用户”。

注意
如果您的系统支持PAM并允许LDAP作为PAM身份验证方法,则将LDAP用于MySQL用户身份验证的另一种方法是使用服务器端 authentication_pam插件。请参见 第6.4.1.5节“ PAM可插拔身份验证”。

LDAP可插入身份验证的先决条件
要将LDAP可插拔身份验证用于MySQL,必须满足以下先决条件:

LDAP服务器必须可用于LDAP身份验证插件进行通信。

要由MySQL认证的LDAP用户必须存在于LDAP服务器管理的目录中。

LDAP客户端库必须在使用服务器端authentication_ldap_sasl或 authentication_ldap_simple插件的系统上可用 。当前,受支持的库是Windows本机LDAP库或非Windows系统上的OpenLDAP库。

要使用基于SASL的LDAP验证,请执行以下操作:

LDAP服务器必须配置为与SASL服务器通信。

使用客户端authentication_ldap_sasl_client 插件的系统上必须有SASL客户端库 。当前,唯一受支持的库是Cyrus SASL库。

MySQL用户的LDAP身份验证如何工作
本节概述了MySQL和LDAP如何协同工作以认证MySQL用户。有关显示如何设置MySQL帐户以使用特定LDAP身份验证插件的示例,请参见 使用LDAP可插拔身份验证。

客户端连接到MySQL服务器,提供MySQL客户端用户名和LDAP密码:

对于简单的LDAP身份验证,客户端和服务器端插件将密码作为明文传递。

对于基于SASL的LDAP身份验证,客户端和服务器端插件使用SASL消息在LDAP协议中安全传输凭据,以避免在MySQL客户端和服务器之间发送明文密码。

如果客户端用户名和主机名不匹配任何MySQL帐户,则连接被拒绝。

如果存在匹配的MySQL帐户,则会针对LDAP进行身份验证。LDAP服务器查找与用户匹配的条目,并根据LDAP密码对条​​目进行身份验证:

如果MySQL帐户命名为LDAP用户专有名称(DN),则LDAP身份验证将使用该值和客户端提供的LDAP密码。(要将LDAP用户DN与MySQL帐户相关联,请BY在CREATE USER创建帐户的语句中包含一个用于指定身份验证字符串的 子句。)

如果MySQL帐户未命名LDAP用户DN,则LDAP身份验证将使用客户端提供的用户名和LDAP密码。在这种情况下,身份验证插件首先使用根DN和密码作为凭据绑定到LDAP服务器,以根据客户端用户名查找用户DN,然后根据LDAP密码对该用户DN进行身份验证。如果根DN和密码设置为不正确的值或为空(未设置),并且LDAP服务器不允许匿名连接,则使用根证书的绑定将失败。

如果LDAP服务器未找到匹配项或多个匹配项,则身份验证失败,并且客户端连接被拒绝。

如果LDAP服务器找到单个匹配项,则LDAP身份验证成功(假设密码正确),LDAP服务器返回LDAP条目,并且身份验证插件根据该条目确定经过身份验证的用户的名称:

如果LDAP条目具有组属性(默认为该 cn属性),则插件将其值作为经过身份验证的用户名返回。

如果LDAP条目没有组属性,那么认证插件将客户机用户名作为已认证的用户名返回。

MySQL服务器将客户端用户名与经过身份验证的用户名进行比较,以确定客户端会话是否发生代理:

如果名称相同,则不会发生代理:与客户端用户名匹配的MySQL帐户用于特权检查。

如果名称不同,则发生代理:MySQL查找与经过身份验证的用户名匹配的帐户。该帐户将成为代理用户,用于特权检查。与客户端用户名匹配的MySQL帐户被视为外部代理用户。

安装LDAP可插入身份验证
本节介绍如何安装LDAP认证插件。有关安装插件的一般信息,请参见 第5.6.1节“安装和卸载插件”。

要由服务器使用,插件库文件必须位于MySQL插件目录(由plugin_dir系统变量命名的目录)中。如有必要,通过设置plugin_dir服务器启动时的值来配置插件目录位置 。

服务器端插件库文件的基本名称为 authentication_ldap_simple和 authentication_ldap_sasl。每个平台的文件名后缀都不同(例如, .so对于Unix和类似Unix的系统, .dll对于Windows)。

要在服务器启动时加载插件,请使用 --plugin-load-add选项来命名包含它们的库文件。使用此插件加载方法,每次服务器启动时必须给出选项。另外,为要配置的任何插件提供的系统变量指定值。

每个服务器端LDAP插件都公开了一组系统变量,这些变量可对其进行配置。设置大多数选项是可选的,但是必须设置变量以指定LDAP服务器主机(以便插件知道连接位置)和LDAP绑定操作的基础专有名称(以限制搜索范围并获得更快的搜索)。有关所有LDAP系统变量的详细信息,请参见 第6.4.1.11节“可插入身份验证系统变量”。

要加载插件并为LDAP绑定操作设置LDAP服务器主机和基本专有名称,请在my.cnf文件中放入诸如此类的行(.so必要时调整平台的 后缀):

[mysqld]
plugin-load-add=authentication_ldap_simple.so
authentication_ldap_simple_server_host=127.0.0.1
authentication_ldap_simple_bind_base_dn="dc=example,dc=com"
plugin-load-add=authentication_ldap_sasl.so
authentication_ldap_sasl_server_host=127.0.0.1
authentication_ldap_sasl_bind_base_dn="dc=example,dc=com"
修改之后my.cnf,重新启动服务器以使新设置生效。

或者,要在运行时加载插件,请使用以下语句(.so根据需要调整平台的后缀):

INSTALL PLUGIN authentication_ldap_simple
SONAME 'authentication_ldap_simple.so';
INSTALL PLUGIN authentication_ldap_sasl
SONAME 'authentication_ldap_sasl.so';
INSTALL PLUGIN立即加载该插件,并将其注册到mysql.plugins系统表中,以使服务器为每次后续的正常启动加载该插件,而 无需--plugin-load-add。

在运行时安装插件后,它们的系统变量将变为可用,并且您可以将其设置添加到my.cnf文件中,以配置插件以供后续重启。例如:

[mysqld]
authentication_ldap_simple_server_host=127.0.0.1
authentication_ldap_simple_bind_base_dn="dc=example,dc=com"
authentication_ldap_sasl_server_host=127.0.0.1
authentication_ldap_sasl_bind_base_dn="dc=example,dc=com"
修改之后my.cnf,重新启动服务器以使新设置生效。

或者,要在运行时设置和保留值,请使用以下语句:

SET PERSIST authentication_ldap_simple_server_host='127.0.0.1';
SET PERSIST authentication_ldap_simple_bind_base_dn='dc=example,dc=com';
SET PERSIST authentication_ldap_sasl_server_host='127.0.0.1';
SET PERSIST authentication_ldap_sasl_bind_base_dn='dc=example,dc=com';
SET PERSIST设置正在运行的MySQL实例的值。它还保存该值,使该值可用于随后的服务器重新启动。要更改正在运行的MySQL实例的值而不保存其值以供以后重新启动,请使用GLOBAL关键字而不是 PERSIST。请参见 第13.7.6.1节“变量分配的SET语法”。

要验证插件安装,请检查 INFORMATION_SCHEMA.PLUGINS表或使用以下SHOW PLUGINS 语句(请参见 第5.6.2节“获取服务器插件信息”)。例如:

mysql> SELECT PLUGIN_NAME, PLUGIN_STATUS
FROM INFORMATION_SCHEMA.PLUGINS
WHERE PLUGIN_NAME LIKE '%ldap%';
+----------------------------+---------------+
| PLUGIN_NAME | PLUGIN_STATUS |
+----------------------------+---------------+
| authentication_ldap_sasl | ACTIVE |
| authentication_ldap_simple | ACTIVE |
+----------------------------+---------------+
如果插件未能初始化,请检查服务器错误日志以获取诊断消息。

要将MySQL帐户与LDAP插件相关联,请参见 使用LDAP可插拔身份验证。

SELinux的附加说明
在启用了SELinux的运行EL6或EL的系统上,需要更改SELinux策略才能使MySQL LDAP插件与LDAP服务通信:

创建mysqlldap.te具有以下内容的文件:

module mysqlldap 1.0;

require {
type ldap_port_t;
type mysqld_t;
class tcp_socket name_connect;
}

#============= mysqld_t ==============

allow mysqld_t ldap_port_t:tcp_socket name_connect;
将安全策略模块编译为二进制表示形式:

checkmodule -M -m mysqlldap.te -o mysqlldap.mod
创建一个SELinux策略模块包:

semodule_package -m mysqlldap.mod -o mysqlldap.pp
安装模块包:

semodule -i mysqlldap.pp
更改SELinux策略后,重新启动MySQL服务器:

service mysqld restart
卸载LDAP可插入身份验证
卸载LDAP身份验证插件的方法取决于安装方式:

如果使用--plugin-load-add选项在服务器启动时安装了插件,请在 不使用这些选项的情况下重新启动服务器。

如果您在使用时在运行时安装了插件 INSTALL PLUGIN,则在服务器重新启动后它们将保持安装状态。要卸载它们,请使用 UNINSTALL PLUGIN:

UNINSTALL PLUGIN authentication_ldap_simple;
UNINSTALL PLUGIN authentication_ldap_sasl;
此外,从my.cnf文件中删除所有设置LDAP插件相关系统变量的启动选项。如果您SET PERSIST以前用于 保留LDAP系统变量,请使用 RESET PERSIST来删除设置。

使用LDAP可插入身份验证
本节描述了如何使MySQL帐户能够使用LDAP可插入身份验证连接到MySQL服务器。如“ 安装LDAP可插拔身份验证”中所述,假定服务器正在运行并启用了适当的服务器端插件 ,并且客户机主机上提供了适当的客户机端插件。

本节不介绍LDAP配置或管理。假定您熟悉这些主题。

两个服务器端LDAP插件分别与特定的客户端插件一起使用:

服务器端 authentication_ldap_simple插件执行简单的LDAP身份验证。对于使用此插件的帐户进行的连接,客户端程序使用客户端mysql_clear_password 插件,该客户端插件将密码以明文形式发送到服务器。不使用密码哈希或加密,因此建议在MySQL客户端和服务器之间建立安全连接以防止密码泄露。

服务器端 authentication_ldap_sasl插件执行基于SASL的LDAP身份验证。对于使用此插件的帐户进行的连接,客户端程序使用客户端 authentication_ldap_sasl_client插件。客户端和服务器端SASL LDAP插件使用SASL消息在LDAP协议内安全地传输凭据,以避免在MySQL客户端和服务器之间发送明文密码。

MySQL用户的LDAP身份验证的总体要求:

每个要认证的用户都必须有一个LDAP目录条目。

必须有一个MySQL用户帐户,该帐户指定一个服务器端LDAP身份验证插件,并可以选择命名关联的LDAP用户专有名称(DN)。(要将LDAP用户DN与MySQL帐户相关联,请BY在CREATE USER创建帐户的语句中包括一个子句 。)如果帐户未命名LDAP字符串,则LDAP身份验证将使用客户端指定的用户名来查找LDAP条目。

客户端程序使用适合MySQL帐户使用的服务器端身份验证插件的连接方法进行连接。对于LDAP身份验证,连接需要MySQL用户名和LDAP密码。另外,对于使用服务器端authentication_ldap_simple插件的帐户 ,请调用带有--enable-cleartext-plugin启用客户端mysql_clear_password插件选项的 客户端程序 。

这里的说明假定以下情形:

MySQL用户betsy和 分别boris对betsy_ldap和 的LDAP条目进行身份验证boris_ldap。(不必使MySQL和LDAP用户名不同。在本讨论中使用不同的名称有助于阐明操作上下文是MySQL还是LDAP。)

LDAP条目使用该uid属性指定用户名。这可能因LDAP服务器而异。某些LDAP服务器将cn 属性用于用户名,而不是 uid。要更改属性,请 适当修改 authentication_ldap_simple_user_search_attr 或 authentication_ldap_sasl_user_search_attr系统变量。

这些LDAP条目在LDAP服务器管理的目录中可用,以提供可唯一标识每个用户的专有名称值:

uid=betsy_ldap,ou=People,dc=example,dc=com
uid=boris_ldap,ou=People,dc=example,dc=com
CREATE USER创建MySQL帐户的语句在该BY子句中为LDAP用户命名 ,以指示MySQL帐户针对哪个LDAP条目进行身份验证。

设置使用LDAP身份验证的帐户的说明取决于所使用的服务器端LDAP插件。以下各节描述了几种使用方案。

简单LDAP认证
要为简单的LDAP身份验证配置MySQL帐户,该CREATE USER语句指定authentication_ldap_simple 插件,并可以选择命名LDAP用户专有名称(DN):

CREATE USER user
IDENTIFIED WITH authentication_ldap_simple
[BY 'LDAP user DN'];
假设MySQL用户betsy在LDAP目录中具有以下条目:

uid=betsy_ldap,ou=People,dc=example,dc=com
然后,为其创建MySQL帐户的语句 betsy如下所示:

CREATE USER 'betsy'@'localhost'
IDENTIFIED WITH authentication_ldap_simple
AS 'uid=betsy_ldap,ou=People,dc=example,dc=com';
BY子句中 指定的认证字符串 不包括LDAP密码。必须由客户端用户在连接时提供。

客户端通过提供MySQL用户名和LDAP密码并启用客户端mysql_clear_password插件来连接到MySQL服务器 :

shell> mysql --user=betsy --password --enable-cleartext-plugin
Enter password: betsy_password (betsy_ldap LDAP password)
注意
客户端mysql_clear_password 身份验证插件使密码保持不变,因此客户端程序将其以明文形式发送到MySQL服务器。这样可以将密码原样传递给LDAP服务器。明文密码是使用不带SASL的服务器端LDAP库所必需的,但在某些配置中可能是安全问题。这些措施可最大程度地降低风险:

为了减少偶然使用该 mysql_clear_password插件的可能性,MySQL客户端必须显式启用它(例如,使用 --enable-cleartext-plugin选项)。请参见 第6.4.1.4节“客户端明文可插入身份验证”。

为了避免在mysql_clear_password启用插件的情况下暴露密码 ,MySQL客户端应使用加密连接连接到MySQL服务器。请参见 第6.3.1节“配置MySQL以使用加密连接”。

身份验证过程如下所示:

客户端插件将betsy和 betsy_password作为客户端用户名和LDAP密码发送到MySQL服务器。

连接尝试与'betsy'@'localhost'帐户匹配 。服务器端LDAP插件发现此帐户的身份验证字符串为 'uid=betsy_ldap,ou=People,dc=example,dc=com' LDAP用户DN。插件将此字符串和LDAP密码发送到LDAP服务器。

LDAP服务器找到的LDAP条目, betsy_ldap并且密码匹配,因此LDAP身份验证成功。

LDAP条目没有组属性,因此服务器端插件将客户端用户名(betsy)作为经过身份验证的用户返回。这是客户端提供的相同用户名,因此不会发生代理,客户端会话将使用该 'betsy'@'localhost'帐户进行特权检查。

如果匹配的LDAP条目包含组属性,则该属性值将是经过身份验证的用户名,并且如果该值不同于betsy,则将发生代理。有关使用group属性的示例,请参阅 LDAP身份验证与代理。

如果该CREATE USER语句不包含BY用于指定betsy_ldapLDAP专有名称的子句 ,则身份验证尝试将使用客户端提供的用户名(在这种情况下为betsy)。如果没有用于的LDAP条目betsy,则身份验证将失败。

基于SASL的LDAP身份验证
要配置用于SASL LDAP认证的MySQL帐户,该 CREATE USER语句指定authentication_ldap_sasl插件,并可以选择命名LDAP用户专有名称(DN):

CREATE USER user
IDENTIFIED WITH authentication_ldap_sasl
[BY 'LDAP user DN'];
假设MySQL用户boris在LDAP目录中具有以下条目:

uid=boris_ldap,ou=People,dc=example,dc=com
然后,为其创建MySQL帐户的语句 boris如下所示:

CREATE USER 'boris'@'localhost'
IDENTIFIED WITH authentication_ldap_sasl
AS 'uid=boris_ldap,ou=People,dc=example,dc=com';
BY子句中 指定的认证字符串 不包括LDAP密码。必须由客户端用户在连接时提供。

客户端通过提供MySQL用户名和LDAP密码连接到MySQL服务器:

shell> mysql --user=boris --password
Enter password: boris_password (boris_ldap LDAP password)
对于服务器端 authentication_ldap_sasl插件,客户端使用客户端 authentication_ldap_sasl_client插件。如果客户端程序找不到客户端插件,请指定一个--plugin-dir选项来命名插件库文件的安装目录。

的身份验证过程boris与先前针对betsy简单LDAP身份验证的过程类似 ,不同之处在于,客户端和服务器端SASL LDAP插件使用SASL消息在LDAP协议内安全地传输凭据,以避免在客户端之间发送明文密码。 MySQL客户端和服务器。

LDAP认证用户DN后缀
LDAP认证插件允许提供用户DN信息的认证字符串以+前缀字符开头 :

在没有+字符的情况下,身份验证字符串值按原样处理而无需修改。

如果身份验证字符串以开头 +,则插件将从客户端发送的用户名构造完整的用户DN值,以及身份验证字符串中指定的DN(已+删除)。在构造的DN中,客户端用户名成为指定LDAP用户名的属性的值。这是 uid默认; 要更改属性,请 适当修改 authentication_ldap_simple_user_search_attr 或 authentication_ldap_sasl_user_search_attr系统变量。身份验证字符串的存储方式如mysql.user 系统表,其中包含完整的用户DN,该用户DN在身份验证之前即时构建。

此帐户身份验证字符串 +开头没有,因此将其作为完整用户DN:

CREATE USER 'baldwin'
IDENTIFIED WITH authentication_ldap_simple
AS 'uid=admin,ou=People,dc=example,dc=com';
客户端使用帐户(baldwin)中指定的用户名进行连接。在这种情况下,不使用该名称,因为身份验证字符串没有前缀,因此可以完全指定用户DN。

此帐户身份验证字符串确实 +在开头,因此仅作为用户DN的一部分:

CREATE USER 'accounting'
IDENTIFIED WITH authentication_ldap_simple
AS '+ou=People,dc=example,dc=com';
客户端使用在帐户(accounting)中指定的用户名进行连接,在这种情况下,该用户名uid与认证字符串一起用作属性,以构造用户DN: uid=accounting,ou=People,dc=example,dc=com

前面示例中的帐户具有非空用户名,因此客户端始终使用与帐户定义中指定的名称相同的名称连接到MySQL服务器。如果一个帐户具有空用户名,例如LDAP Authentication with Proxying中''@'%'描述的默认匿名 代理帐户 ,则客户端可能会使用不同的用户名连接到MySQL服务器。但是原理是相同的:如果认证字符串以开头,则插件将使用客户端发送的用户名以及认证字符串来构造用户DN。 +

LDAP身份验证与代理
LDAP身份验证插件支持代理,使用户可以以一个用户身份连接到MySQL服务器,但可以承担其他用户的特权。本节介绍基本的LDAP插件代理支持。LDAP插件还支持组首选项和代理用户映射的规范。请参阅 LDAP身份验证组首选项和映射规范。

此处描述的身份验证方案基于将LDAP组属性值映射到将使用LDAP进行身份验证的MySQL用户连接到定义了不同权限集的其他MySQL帐户的基础上,使用代理。用户不会直接通过定义特权的帐户进行连接。相反,它们通过通过LDAP认证的默认代理帐户连接,这样所有外部登录名都将映射到拥有特权的MySQL帐户。使用代理帐户进行连接的任何用户都将映射到这些MySQL帐户之一,这些帐户的特权确定了允许外部用户执行的数据库操作。

这里的说明假定以下情形:

LDAP条目使用uid和 cn属性分别指定用户名和组值。要使用不同的用户和组属性名称,请设置适当的系统变量以配置插件:

对于authentication_ldap_simple:设置 authentication_ldap_simple_user_search_attr 和 authentication_ldap_simple_group_search_attr。

对于authentication_ldap_sasl:设置 authentication_ldap_sasl_user_search_attr 和 authentication_ldap_sasl_group_search_attr。

这些LDAP条目在LDAP服务器管理的目录中可用,以提供可唯一标识每个用户的专有名称值:

uid=basha,ou=People,dc=example,dc=com,cn=accounting
uid=basil,ou=People,dc=example,dc=com,cn=front_office
组属性值将成为经过身份验证的用户名,因此它们分别命名accounting 和front_office帐户。

这些示例假定使用SASL LDAP身份验证。对简单的LDAP身份验证进行适当的调整。

创建默认的代理MySQL帐户:

CREATE USER ''@'%'
IDENTIFIED WITH authentication_ldap_simple;
代理帐户定义没有子句来命名LDAP用户DN。从而: AS 'auth_string'

客户端连接时,客户端用户名用作要搜索的LDAP用户名。

预期匹配的LDAP条目将包含一个组属性,该属性命名代理的MySQL帐户,该帐户定义了客户端应具有的特权。

注意
如果您的MySQL安装中有匿名用户,则它们可能与默认代理用户冲突。有关此问题及其处理方式的更多信息,请参见 默认代理用户和匿名用户冲突。

创建代理帐户并向其授予MySQL访问所需的特权:

CREATE USER 'accounting'@'localhost'
IDENTIFIED WITH mysql_no_login;
CREATE USER 'front_office'@'localhost'
IDENTIFIED WITH mysql_no_login;

GRANT ALL PRIVILEGES
ON accountingdb.
TO 'accounting'@'localhost';
GRANT ALL PRIVILEGES
ON frontdb.

TO 'front_office'@'localhost';
代理帐户使用mysql_no_login 身份验证插件来防止客户端使用帐户直接登录到MySQL服务器。而是希望使用LDAP进行身份验证的用户将使用默认''@'%'代理帐户。(这假设mysql_no_login已安装了插件。有关说明,请参见 第6.4.1.8节“无登录可插入身份验证”。)有关防止代理帐户直接使用的替代方法,请参见 防止直接登录代理帐户。

向代理帐户PROXY授予每个代理帐户的 特权:

GRANT PROXY
  ON 'accounting'@'localhost'
  TO ''@'%';
GRANT PROXY
  ON 'front_office'@'localhost'
  TO ''@'%';

使用mysql命令行客户端以方式连接到MySQL服务器basha。

shell> mysql --user=basha --password
Enter password: basha_password (basha LDAP password)

身份验证如下:

服务器使用默认''@'%'代理帐户为客户端用户 验证连接 basha。

匹配的LDAP条目是:

uid=basha,ou=People,dc=example,dc=com,cn=accounting
匹配的LDAP条目具有group属性 cn=accounting,因此 accounting成为经过身份验证的用户。

经过身份验证的用户不同于客户端用户名 basha,其结果 basha被视为的代理 accounting,并 basha假定了该accounting帐户的特权 。以下查询返回输出,如下所示:

mysql> SELECT USER(), CURRENT_USER(), @@proxy_user;
+-----------------+----------------------+--------------+
| USER()          | CURRENT_USER()       | @@proxy_user |
+-----------------+----------------------+--------------+
| basha@localhost | accounting@localhost | ''@'%'       |
+-----------------+----------------------+--------------+

这说明basha使用授予accountingMySQL帐户的特权,并且通过默认的代理用户帐户进行代理。

现在basil改为连接:

shell> mysql --user=basil --password
Enter password: basil_password (basil LDAP password)

的身份验证过程basil与之前针对basha以下内容所述的过程类似 :

服务器使用默认''@'%'代理帐户为客户端用户 验证连接 basil。

匹配的LDAP条目是:

uid=basil,ou=People,dc=example,dc=com,cn=front_office
匹配的LDAP条目具有group属性 cn=front_office,因此 front_office成为经过身份验证的用户。

经过身份验证的用户不同于客户端用户名 basil,其结果 basil被视为的代理 front_office,并 basil假定了该front_office帐户的特权 。以下查询返回输出,如下所示:

mysql> SELECT USER(), CURRENT_USER(), @@proxy_user;
+-----------------+------------------------+--------------+
| USER()          | CURRENT_USER()         | @@proxy_user |
+-----------------+------------------------+--------------+
| basil@localhost | front_office@localhost | ''@'%'       |
+-----------------+------------------------+--------------+

这说明basil使用授予front_office MySQL帐户的特权,并且通过默认的代理用户帐户进行代理。

LDAP身份验证组首选项和映射规范
如使用代理的LDAP身份验证中所述 ,基本LDAP身份验证代理的工作原理是插件将LDAP服务器返回的第一个组名用作MySQL代理用户帐户名。如果LDAP服务器返回多个组名,则此简单功能无法指定关于使用哪个组名的任何首选项,也不能指定除组名以外的任何名称作为代理用户名。

从MySQL 8.0.14开始,对于使用LDAP身份验证的MySQL帐户,身份验证字符串可以指定以下信息以实现更大的代理灵活性:

按优先顺序排列的组列表,以便插件使用列表中与LDAP服务器返回的组匹配的第一个组名称。

从组名到代理用户名的映射,这样,组名匹配时可以提供指定的名称以用作代理用户。这提供了使用组名作为代理用户的替代方法。

考虑以下MySQL代理帐户定义:

CREATE USER ''@'%'
IDENTIFIED WITH authentication_ldap_sasl
AS '+ou=People,dc=example,dc=com#grp1=usera,grp2,grp3=userc';
身份验证字符串具有ou=People,dc=example,dc=com以该+字符为前缀 的用户DN后缀 。因此,如 LDAP认证用户DN后缀中所述,完整的用户DN由指定的用户DN后缀加上客户端用户名作为uid属性来构造 。

身份验证字符串的其余部分以开头 #,表示组首选项和映射信息的开始。在为了验证字符串列表组名的这部分 grp1,grp2, grp3。LDAP插件将该列表与LDAP服务器返回的组名称集进行比较,并按列表顺序查找与返回名称的匹配项。插件使用第一个匹配项,如果没有匹配项,则认证失败。

假设LDAP服务器返回组 grp3,grp2和 grp7。使用LDAP插件 grp2是因为它是身份验证字符串中匹配的第一个组,即使它不是LDAP服务器返回的第一个组也是如此。如果LDAP服务器返回grp4,grp2和 grp1,则插件 也会使用, grp1即使它们grp2也匹配。grp1具有比grp2由于在身份验证字符串中较早列出的优先级更高的优先级。

假设插件找到一个匹配的组名,它将执行从该组名到MySQL代理用户名的映射。对于示例代理帐户,映射如下所示:

如果匹配的组名是grp1或 grp3,则它们在身份验证字符串中分别与用户名usera和关联 userc。该插件使用相应的关联用户名作为代理用户名。

如果匹配的组名是grp2,则认证字符串中没有关联的用户名。该插件grp2用作代理用户名。

如果LDAP服务器返回DN格式的组,则LDAP插件将解析组DN,以从中提取组名。

要指定LDAP组首选项和映射信息,请遵循以下原则:

以#前缀字符开始认证字符串的组首选项和映射部分。

组首选项和映射规范是一个或多个项目的列表,以逗号分隔。每个项目的格式为 或。项目应按组名首选项顺序列出。对于由插件选择的,与LDAP服务器返回的组名集合匹配的组名,这两种语法的效果不同,如下所示: group_name=user_namegroup_name

对于指定为 (带有用户名)的项目,组名映射到用户名,该用户名用作MySQL代理用户名。 group_name=user_name

对于指定为 group_name(没有用户名)的项目,组名用作MySQL代理用户名。

要引用包含特殊字符(例如空格)的组或用户名,请用双引号(")字符将其引起来。例如,如果某个项目的组名和用户名是my group name和my user name,则必须使用引号将其写在组映射中:

"my group name"="my user name"
如果项目的组和用户名为 my_group_name和 my_user_name(不包含特殊字符),则可能但不必使用引号将其写成。以下任何一项均有效:

my_group_name=my_user_name
my_group_name="my_user_name"
"my_group_name"=my_user_name
"my_group_name"="my_user_name"

要转义字符,请在其前面加上反斜杠(\)。这在包含文字双引号或反斜杠时特别有用,否则原义不包含在内。

用户DN不必出现在身份验证字符串中,但是如果存在,则它必须在组首选项和映射部分之前。用户DN可以作为完整的用户DN给出,也可以作为带有+前缀字符的用户DN后缀给出 。