6.4.1.9 LDAP 可插拔身份验证
Note
LDAP 可插拔身份验证是商业产品 MySQL Enterprise Edition 中包含的扩展。要了解有关商品的更多信息,请参阅https://www.mysql.com/products/。
从 MySQL 5.7.19 开始,MySQL Enterprise Edition 支持一种身份验证方法,该方法使 MySQL Server 可以通过访问目录服务(例如 X.500)使用 LDAP(轻型目录访问协议)来对 MySQL 用户进行身份验证。 MySQL 使用 LDAP 来获取用户,凭证和组信息。
LDAP 可插拔身份验证提供以下功能:
-
外部身份验证:LDAP 身份验证使 MySQL Server 可以接受来自 LDAP 目录中 MySQL 授权 table 外部定义的用户的连接。
-
代理用户支持:LDAP 身份验证可以基于外部用户所属的 LDAP 组,将与 Client 端程序传递的外部用户名不同的用户名返回给 MySQL。这意味着 LDAP 插件可以返回 MySQL 用户,该用户定义了外部 LDAP 认证用户应具有的特权。例如,如果
joe
的 LDAP 组为developer
,则名为joe
的 LDAP 用户可以连接并具有名为developer
的 MySQL 用户的特权。 -
安全性:使用 TLS,可以确保与 LDAP 服务器的连接安全。
下 table 显示了用于简单的基于 SASL 的 LDAP 身份验证的插件和库文件名。文件名后缀可能在您的系统上有所不同。这些文件必须位于plugin_dir系统变量命名的目录中。
table6.15 用于简单 LDAP 身份验证的插件和库名称
插件或文件 | 插件或文件名 |
---|---|
服务器端插件名称 | authentication_ldap_simple |
Client 端插件名称 | mysql_clear_password |
库文件名 | authentication_ldap_simple.so |
table6.16 基于 SASL 的 LDAP 身份验证的插件和库名称
插件或文件 | 插件或文件名 |
---|---|
服务器端插件名称 | authentication_ldap_sasl |
Client 端插件名称 | authentication_ldap_sasl_client |
库文件名 | authentication_ldap_sasl.so , authentication_ldap_sasl_client.so |
库文件仅包含authentication_ldap_XXX
身份验证插件。Client 端mysql_clear_password
插件内置在libmysqlclient
Client 端库中。
每个服务器端 LDAP 插件均与特定的 Client 端插件一起使用:
-
服务器端
authentication_ldap_simple
插件执行简单的 LDAP 身份验证。对于使用此插件的帐户进行的连接,Client 端程序使用 Client 端mysql_clear_password
插件,该插件将密码以明文形式发送到服务器。不使用密码哈希或加密,因此建议在 MySQLClient 端和服务器之间构建安全连接以防止密码泄露。 -
服务器端
authentication_ldap_sasl
插件执行基于 SASL 的 LDAP 身份验证。对于使用此插件的帐户进行的连接,Client 端程序使用 Client 端authentication_ldap_sasl_client
插件。Client 端和服务器端 SASL LDAP 插件使用 SASL 消息在 LDAP 协议中安全地传输凭据,以避免在 MySQLClient 端和服务器之间发送明文密码。
以下各节提供特定于 LDAP 可插入身份验证的安装和使用信息:
有关 MySQL 中可插拔身份验证的一般信息,请参见第 6.2.13 节“可插入身份验证”。有关mysql_clear_password
插件的信息,请参见第 6.4.1.6 节“Client 端明文可插入身份验证”。有关代理用户的信息,请参见第 6.2.14 节“代理用户”。
Note
如果您的系统支持 PAM 并允许 LDAP 作为 PAM 身份验证方法,则将 LDAP 用于 MySQL 用户身份验证的另一种方法是使用服务器端authentication_pam
插件。参见第 6.4.1.7 节“ PAM 可插入身份验证”。
LDAP 可插入身份验证的先决条件
要将 LDAP 可插拔身份验证用于 MySQL,必须满足以下先决条件:
-
LDAP 服务器必须可用于 LDAP 身份验证插件进行通信。
-
要由 MySQL 认证的 LDAP 用户必须存在于 LDAP 服务器 Management 的目录中。
-
LDAPClient 端库必须在使用服务器端
authentication_ldap_sasl
或authentication_ldap_simple
插件的系统上可用。当前,受支持的库是 Windows 本机 LDAP 库或非 Windows 系统上的 OpenLDAP 库。 -
要使用基于 SASL 的 LDAP 身份验证,请执行以下操作:
-
LDAP 服务器必须配置为与 SASL 服务器通信。
- 在使用 Client 端
authentication_ldap_sasl_client
插件的系统上,SASLClient 端库必须可用。当前,唯一受支持的库是 Cyrus SASL 库。
- 在使用 Client 端
MySQL 用户的 LDAP 身份验证如何工作
本节概述了 MySQL 和 LDAP 如何协同工作以认证 MySQL 用户。有关显示如何设置 MySQL 帐户以使用特定 LDAP 身份验证插件的示例,请参见使用 LDAP 可插入身份验证。
Client 端连接到 MySQL 服务器,并提供 MySQLClient 端用户名和 LDAP 密码:
-
对于简单的 LDAP 身份验证,Client 端和服务器端插件将密码作为明文传递。建议在 MySQLClient 端和服务器之间构建安全连接,以防止密码泄露。
-
对于基于 SASL 的 LDAP 身份验证,Client 端和服务器端插件可避免在 MySQLClient 端和服务器之间发送明文密码。例如,插件可能使用 SASL 消息在 LDAP 协议中安全传输凭据。
如果 Client 端用户名和主机名不匹配任何 MySQL 帐户,则连接被拒绝。
如果存在匹配的 MySQL 帐户,则会针对 LDAP 进行身份验证。 LDAP 服务器查找与用户匹配的条目,并根据 LDAP 密码对条目进行身份验证:
-
如果 MySQL 帐户命名为 LDAP 用户专有名称(DN),则 LDAP 身份验证将使用该值和 Client 端提供的 LDAP 密码。 (要将 LDAP 用户 DN 与 MySQL 帐户相关联,请在创建帐户的CREATE USER语句中包含一个
BY
子句,该子句指定身份验证字符串。) -
如果 MySQL 帐户没有命名 LDAP 用户 DN,则 LDAP 身份验证将使用 Client 端提供的用户名和 LDAP 密码。在这种情况下,身份验证插件首先使用根 DN 和密码作为凭据绑定到 LDAP 服务器,以根据 Client 端用户名查找用户 DN,然后根据 LDAP 密码对该用户 DN 进行身份验证。如果根 DN 和密码设置为不正确的值或为空(未设置),并且 LDAP 服务器不允许匿名连接,则使用根证书的绑定将失败。
如果 LDAP 服务器找不到匹配项或多个匹配项,则身份验证将失败并且 Client 端连接将被拒绝。
如果 LDAP 服务器找到单个匹配项,则 LDAP 身份验证成功(假设密码正确),LDAP 服务器返回 LDAP 条目,并且身份验证插件根据该条目确定经过身份验证的用户的名称:
-
如果 LDAP 条目具有组属性(默认情况下为
cn
属性),则插件将其值作为经过身份验证的用户名返回。 -
如果 LDAP 条目没有组属性,那么认证插件将 Client 机用户名作为已认证的用户名返回。
MySQL 服务器将 Client 端用户名与经过身份验证的用户名进行比较,以确定 Client 端会话是否发生代理:
-
如果名称相同,则不会发生代理:与 Client 端用户名匹配的 MySQL 帐户用于特权检查。
-
如果名称不同,则发生代理:MySQL 查找与经过身份验证的用户名匹配的帐户。该帐户成为代理用户,用于特权检查。与 Client 端用户名匹配的 MySQL 帐户被视为外部代理用户。
安装 LDAP 可插入身份验证
本节介绍如何安装 LDAP 认证插件。有关安装插件的一般信息,请参见第 5.5.1 节“安装和卸载插件”。
要由服务器使用,插件库文件必须位于 MySQL 插件目录(由plugin_dir系统变量命名的目录)中。如有必要,通过在服务器启动时设置plugin_dir的值来配置插件目录位置。
服务器端插件库文件的基本名称为authentication_ldap_simple
和authentication_ldap_sasl
。文件名后缀因平台而异(例如,对于 Unix 和类 Unix 系统,为.so
;对于 Windows,为.dll
)。
要在服务器启动时加载插件,请使用--plugin-load-add选项命名包含它们的库文件。使用这种插件加载方法,每次服务器启动时必须给出选项。另外,为要配置的任何插件提供的系统变量指定值。
每个服务器端 LDAP 插件都公开了一组系统变量,这些变量可以对其操作进行配置。设置大多数选项是可选的,但是必须设置变量以指定 LDAP 服务器主机(以便插件知道连接的位置)和 LDAP 绑定操作的基础专有名称(以限制搜索范围并获得更快的搜索)。有关所有 LDAP 系统变量的详细信息,请参见第 6.4.1.13 节,“可插入身份验证系统变量”。
要加载插件并为 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
系统 table 中,以使服务器为每次后续的正常启动加载该插件,而无需--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
后,重新启动服务器以使新设置生效。
要验证插件安装,请检查INFORMATION_SCHEMA.PLUGINStable 或使用SHOW PLUGINS语句(请参见第 5.5.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 可插入身份验证。
Additional Notes for 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;
- 将安全策略模块编译为二进制 table 示形式:
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 插件相关系统变量的启动选项。
LDAP 可插拔身份验证和 ldap.conf
对于使用 OpenLDAP 的安装,ldap.conf
文件为 LDAPClient 端提供全局默认值。可以在此文件中设置选项以影响 LDAPClient 端,包括 LDAP 身份验证插件。 OpenLDAP 按以下优先 Sequences 使用配置选项:
-
LDAPClient 端指定的配置。
-
ldap.conf
文件中指定的配置。要禁用此文件,请设置LDAPNOINIT
环境变量。
- OpenLDAP 库内置的默认值。
如果库的默认值或ldap.conf
值未产生适当的选项值,则 LDAP 认证插件可能能够设置相关变量以直接影响 LDAP 配置。例如,LDAP 插件可以覆盖用于 TLS 配置的ldap.conf
参数:系统变量可用于启用 TLS 和控制 CA 配置,例如用于简单 LDAP 认证的authentication_ldap_simple_tls和authentication_ldap_simple_ca_path以及用于 SASL LDAP 认证的authentication_ldap_sasl_tls和authentication_ldap_sasl_ca_path。
有关ldap.conf
的更多信息,请参见ldap.conf(5)
手册页。
使用 LDAP 可插入身份验证
本节介绍如何使用 LDAP 可插入身份验证使 MySQL 帐户连接到 MySQL 服务器。如安装 LDAP 可插入身份验证所述,假定服务器正在启用适当的服务器端插件的情况下运行,并且 Client 端主机上提供了适当的 Client 端插件。
本节不介绍 LDAP 配置或 Management。假定您熟悉这些主题。
两个服务器端 LDAP 插件分别与特定的 Client 端插件一起使用:
-
服务器端
authentication_ldap_simple
插件执行简单的 LDAP 身份验证。对于使用此插件的帐户进行的连接,Client 端程序使用 Client 端mysql_clear_password
插件,该插件将密码以明文形式发送到服务器。不使用密码哈希或加密,因此建议在 MySQLClient 端和服务器之间构建安全连接以防止密码泄露。 -
服务器端
authentication_ldap_sasl
插件执行基于 SASL 的 LDAP 身份验证。对于使用此插件的帐户进行的连接,Client 端程序使用 Client 端authentication_ldap_sasl_client
插件。Client 端和服务器端 SASL LDAP 插件使用 SASL 消息在 LDAP 协议中安全地传输凭据,以避免在 MySQLClient 端和服务器之间发送明文密码。
MySQL 用户的 LDAP 身份验证的总体要求:
-
每个要认证的用户都必须有一个 LDAP 目录条目。
-
必须有一个 MySQL 用户帐户,该帐户指定一个服务器端 LDAP 身份验证插件,并可以选择命名关联的 LDAP 用户专有名称(DN)。 (要将 LDAP 用户 DN 与 MySQL 帐户相关联,请在创建该帐户的CREATE USER语句中包含
BY
子句。)如果帐户未命名 LDAP 字符串,则 LDAP 身份验证将使用 Client 端指定的用户名来查找 LDAP 条目。 -
Client 端程序使用适合 MySQL 帐户使用的服务器端身份验证插件的连接方法进行连接。对于 LDAP 身份验证,连接需要 MySQL 用户名和 LDAP 密码。此外,对于使用服务器端
authentication_ldap_simple
插件的帐户,请使用--enable-cleartext-plugin
选项调用 Client 端程序以启用 Client 端mysql_clear_password
插件。
这里的说明假定以下情况:
-
MySQL 用户
betsy
和boris
分别对betsy_ldap
和boris_ldap
的 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 服务器 Management 的目录中可用,以提供可唯一标识每个用户的专有名称值:
uid=betsy_ldap,ou=People,dc=example,dc=com
uid=boris_ldap,ou=People,dc=example,dc=com
- 创建 MySQL 帐户的CREATE USER语句在
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
然后为betsy
创建 MySQL 帐户的语句如下所示:
CREATE USER 'betsy'@'localhost'
IDENTIFIED WITH authentication_ldap_simple
AS 'uid=betsy_ldap,ou=People,dc=example,dc=com';
BY
子句中指定的认证字符串不包含 LDAP 密码。必须由 Client 端用户在连接时提供。
Client 端通过提供 MySQL 用户名和 LDAP 密码并启用 Client 端mysql_clear_password
插件来连接到 MySQL 服务器:
shell> mysql --user=betsy --password --enable-cleartext-plugin
Enter password: betsy_password (betsy_ldap LDAP password)
Note
Client 端mysql_clear_password
身份验证插件不会更改密码,因此 Client 端程序会将其以明文形式发送到 MySQL 服务器。这样可以将密码原样传递给 LDAP 服务器。明文密码是使用不带 SASL 的服务器端 LDAP 库所必需的,但在某些配置中可能是安全问题。这些措施可最大程度地降低风险:
-
为了减少偶然使用
mysql_clear_password
插件的可能性,MySQLClient 端必须显式启用它(例如,使用--enable-cleartext-plugin
选项)。参见第 6.4.1.6 节“Client 端明文可插入身份验证”。 -
为了避免在启用
mysql_clear_password
插件的情况下暴露密码,MySQLClient 端应使用加密连接连接到 MySQL 服务器。参见第 6.3.1 节“配置 MySQL 以使用加密连接”。
身份验证过程如下所示:
-
Client 端插件将
betsy
和*betsy_password
*作为 Client 端用户名和 LDAP 密码发送到 MySQL 服务器。 -
连接尝试与
'betsy'@'localhost'
帐户匹配。服务器端 LDAP 插件发现该帐户的身份验证字符串为'uid=betsy_ldap,ou=People,dc=example,dc=com'
来命名 LDAP 用户 DN。插件将此字符串和 LDAP 密码发送到 LDAP 服务器。 -
LDAP 服务器找到
betsy_ldap
的 LDAP 条目,并且密码匹配,因此 LDAP 身份验证成功。 -
LDAP 条目没有组属性,因此服务器端插件将 Client 机用户名(
betsy
)返回为经过身份验证的用户。这是 Client 端提供的相同用户名,因此不会发生代理,并且 Client 端会话使用'betsy'@'localhost'
帐户进行特权检查。
如果匹配的 LDAP 条目包含组属性,则该属性值将是经过身份验证的用户名,并且,如果该值与betsy
不同,则将发生代理。有关使用 group 属性的示例,请参见LDAP 身份验证与代理。
如果CREATE USER语句不包含BY
子句以指定betsy_ldap
LDAP 专有名称,则身份验证尝试将使用 Client 端提供的用户名(在本例中为betsy
)。在没有betsy
的 LDAP 条目的情况下,身份验证将失败。
基于 SASL 的 LDAP 身份验证
要为 MySQL 帐户配置 SASL LDAP 身份验证,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
然后为boris
创建 MySQL 帐户的语句如下所示:
CREATE USER 'boris'@'localhost'
IDENTIFIED WITH authentication_ldap_sasl
AS 'uid=boris_ldap,ou=People,dc=example,dc=com';
BY
子句中指定的认证字符串不包含 LDAP 密码。必须由 Client 端用户在连接时提供。
Client 端通过提供 MySQL 用户名和 LDAP 密码连接到 MySQL 服务器:
shell> mysql --user=boris --password
Enter password: boris_password (boris_ldap LDAP password)
对于服务器端authentication_ldap_sasl
插件,Client 端使用 Client 端authentication_ldap_sasl_client
插件。如果 Client 端程序找不到 Client 端插件,请指定--plugin-dir
选项,该选项将命名插件库文件的安装目录。
boris
的身份验证过程与先前针对betsy
的简单 LDAP 身份验证过程类似,不同之处在于 Client 端和服务器端 SASL LDAP 插件使用 SASL 消息在 LDAP 协议内安全传输凭据,以避免发送明文密码在 MySQLClient 端和服务器之间。
LDAP 身份验证与代理
LDAP 身份验证插件支持代理,使用户可以以一个用户身份连接到 MySQL 服务器,但可以承担其他用户的特权。本节介绍基本的 LDAP 插件代理支持。 LDAP 插件还支持组首选项和代理用户 Map 的规范。参见LDAP 身份验证组首选项和 Map 规范。
此处描述的代理实现基于使用 LDAP 组属性值将使用 LDAP 进行身份验证的连接 MySQL 用户 Map 到定义了不同权限集的其他 MySQL 帐户。用户不会直接通过定义特权的帐户进行连接。相反,它们通过通过 LDAP 认证的默认代理帐户进行连接,这样所有外部登录名都将 Map 到拥有特权的代理 MySQL 帐户。使用代理帐户进行连接的任何用户都将 Map 到这些代理的 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 服务器 Management 的目录中可用,以提供可唯一标识每个用户的专有名称值:
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_sasl;
代理帐户定义没有用于命名 LDAP 用户 DN 的AS 'auth_string'
子句。从而:
-
Client 端连接后,Client 端用户名将成为要搜索的 LDAP 用户名。
-
预期匹配的 LDAP 条目将包含一个组属性,该属性命名代理的 MySQL 帐户,该帐户定义了 Client 端应具有的特权。
Note
如果您的 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
身份验证插件来防止 Client 端使用帐户直接登录到 MySQL 服务器。相反,期望使用 LDAP 进行身份验证的用户将使用默认的''@'%'
代理帐户。 (这假定已安装mysql_no_login
插件.有关说明,请参阅第 6.4.1.10 节“无登录可插入身份验证”。)有关防止代理帐户直接使用的替代方法,请参阅防止直接登录到代理帐户。
为代理帐户授予每个代理帐户的PROXY特权:
GRANT PROXY
ON 'accounting'@'localhost'
TO ''@'%';
GRANT PROXY
ON 'front_office'@'localhost'
TO ''@'%';
使用mysql命令行 Client 端以basha
连接到 MySQL 服务器。
shell> mysql --user=basha --password
Enter password: basha_password (basha LDAP password)
身份验证如下:
-
服务器使用默认的
''@'%'
代理帐户为 Client 端用户basha
认证连接。 -
匹配的 LDAP 条目是:
uid=basha,ou=People,dc=example,dc=com,cn=accounting
-
匹配的 LDAP 条目具有组属性
cn=accounting
,因此accounting
成为经过身份验证的代理用户。 -
经过身份验证的用户不同于 Client 端用户名
basha
,结果是basha
被视为accounting
的代理,并且basha
承担了代理accounting
帐户的特权。以下查询返回输出,如下所示:
mysql> SELECT USER(), CURRENT_USER(), @@proxy_user;
+-----------------+----------------------+--------------+
| USER() | CURRENT_USER() | @@proxy_user |
+-----------------+----------------------+--------------+
| basha@localhost | accounting@localhost | ''@'%' |
+-----------------+----------------------+--------------+
这 table 明basha
使用授予代理accounting
MySQL 帐户的特权,并且代理通过默认的代理用户帐户进行。
现在改为以basil
的身份连接:
shell> mysql --user=basil --password
Enter password: basil_password (basil LDAP password)
basil
的身份验证过程与先前针对basha
所述的过程类似:
-
服务器使用默认的
''@'%'
代理帐户为 Client 端用户basil
认证连接。 -
匹配的 LDAP 条目是:
uid=basil,ou=People,dc=example,dc=com,cn=front_office
-
匹配的 LDAP 条目具有组属性
cn=front_office
,因此front_office
成为经过身份验证的代理用户。 -
经过身份验证的用户不同于 Client 端用户名
basil
,结果是basil
被视为front_office
的代理,并且basil
承担了代理front_office
帐户的特权。以下查询返回输出,如下所示:
mysql> SELECT USER(), CURRENT_USER(), @@proxy_user;
+-----------------+------------------------+--------------+
| USER() | CURRENT_USER() | @@proxy_user |
+-----------------+------------------------+--------------+
| basil@localhost | front_office@localhost | ''@'%' |
+-----------------+------------------------+--------------+
这 table 明basil
使用授予代理front_office
MySQL 帐户的特权,并且代理通过默认的代理用户帐户进行。
LDAP 身份验证组首选项和 Map 规范
如LDAP 身份验证与代理中所述,基本 LDAP 身份验证代理的工作原理是:插件使用 LDAP 服务器返回的第一个组名作为 MySQL 代理的用户帐户名。如果 LDAP 服务器返回多个组名,则此简单功能无法指定关于使用哪个组名的任何首选项,也不能指定除组名以外的任何名称作为代理用户名。
从 MySQL 5.7.25 开始,对于使用 LDAP 身份验证的 MySQL 帐户,身份验证字符串可以指定以下信息以实现更大的代理灵 Active:
-
按优先 Sequences 排列的组列 table,以便插件使用列 table 中与 LDAP 服务器返回的组匹配的第一个组名称。
-
从组名到代理用户名的 Map,这样一个组名在匹配时可以提供指定的名称以用作代理用户。这提供了使用组名作为代理用户的替代方法。
考虑以下 MySQL 代理帐户定义:
CREATE USER ''@'%'
IDENTIFIED WITH authentication_ldap_sasl
AS '+ou=People,dc=example,dc=com#grp1=usera,grp2,grp3=userc';
验证字符串具有以+
字符为前缀的用户 DN 后缀ou=People,dc=example,dc=com
。因此,如LDAP 认证用户 DN 后缀中所述,完整的用户 DN 由指定的用户 DN 后缀加上 Client 端用户名作为uid
属性构成。
认证字符串的其余部分以#
开头,这 table 示组首选项和 Map 信息的开始。验证字符串的此部分按grp1
,grp2
,grp3
的 Sequences 列出组名。 LDAP 插件将该列 table 与 LDAP 服务器返回的组名称集进行比较,并按列 tableSequences 查找与返回名称的匹配项。插件使用第一个匹配项,或者如果没有匹配项,则认证失败。
假设 LDAP 服务器返回组grp3
,grp2
和grp7
。 LDAP 插件使用grp2
,因为它是身份验证字符串中匹配的第一组,即使它不是 LDAP 服务器返回的第一组。如果 LDAP 服务器返回grp4
,grp2
和grp1
,则即使grp2
也匹配,插件也会使用grp1
。 grp1
的优先级高于grp2
,因为它在身份验证字符串中列在较早的位置。
假设插件找到一个匹配的组名,它将执行从该组名到 MySQL 代理用户名的 Map。对于示例代理帐户,Map 如下所示:
-
如果匹配的组名是
grp1
或grp3
,则它们在身份验证字符串中分别与用户名usera
和userc
关联。插件使用相应的关联用户名作为代理用户名。 -
如果匹配的组名是
grp2
,则认证字符串中没有关联的用户名。插件使用grp2
作为代理用户名。
如果 LDAP 服务器返回 DN 格式的组,则 LDAP 插件将解析组 DN,以从中提取组名。
要指定 LDAP 组首选项和 Map 信息,请遵循以下原则:
-
以
#
前缀字符开头身份验证字符串的组首选项和 Map 部分。 -
组首选项和 Map 规范是一个或多个项目的列 table,以逗号分隔。每个项目的格式均为
group_name=user_name
或*group_name
*。项目应按组名首选项 Sequences 列出。对于插件选择的组名作为 LDAP 服务器返回的组名集合的匹配项,这两种语法的效果不同,如下所示: -
对于指定为
group_name=user_name
(带有用户名)的项目,组名 Map 到用户名,该用户名用作 MySQL 代理的用户名。- 对于指定为*
group_name
*(无用户名)的项目,组名用作 MySQL 代理的用户名。
- 对于指定为*
-
要引用包含特殊字符(例如空格)的组或用户名,请用双引号(
"
)字符将其引起来。例如,如果某项的组名和用户名分别为my group name
和my user name
,则必须使用引号将其写在组 Map 中:
"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"
-
要转义字符,请在其前面加上反斜杠(
\
)。这在包含 Literals 双引号或反斜杠时特别有用,否则原义不包含在内。 -
用户 DN 不必出现在身份验证字符串中,但是如果存在,则它必须在组首选项和 Map 部分之前。用户 DN 可以作为完整的用户 DN 给出,也可以作为带有_前缀字符的用户 DN 后缀给出。 (请参阅LDAP 认证用户 DN 后缀。)
LDAP 认证用户 DN 后缀
从 MySQL 5.7.21 开始,LDAP 认证插件允许提供用户 DN 信息的认证字符串以+
前缀字符开头:
-
在没有
+
字符的情况下,身份验证字符串值按原样处理而无需修改。 -
如果认证字符串以
+
开头,则插件将从 Client 端发送的用户名构造完整的用户 DN 值,以及认证字符串中指定的 DN(删除+
)。在构造的 DN 中,Client 端用户名成为指定 LDAP 用户名的属性的值。默认为uid
;要更改属性,请修改适当的系统变量(authentication_ldap_simple_user_search_attr或authentication_ldap_sasl_user_search_attr)。身份验证字符串按mysql.user
系统 table 中的给定存储,其中完整的用户 DN 是在身份验证之前即时构建的。
此帐户身份验证字符串开头没有+
,因此将其作为完整的用户 DN:
CREATE USER 'baldwin'
IDENTIFIED WITH authentication_ldap_simple
AS 'uid=admin,ou=People,dc=example,dc=com';
Client 端使用帐户(baldwin
)中指定的用户名进行连接。在这种情况下,不使用该名称,因为身份验证字符串没有前缀,因此可以完全指定用户 DN。
此帐户身份验证字符串的开头确实有+
,因此它被视为用户 DN 的一部分:
CREATE USER 'accounting'
IDENTIFIED WITH authentication_ldap_simple
AS '+ou=People,dc=example,dc=com';
Client 端使用帐户(accounting
)中指定的用户名进行连接,在这种情况下,该用户名与验证字符串一起用作uid
属性,以构造用户 DN:uid=accounting,ou=People,dc=example,dc=com
前面示例中的帐户具有非空用户名,因此 Client 端始终使用与帐户定义中指定的名称相同的名称连接到 MySQL 服务器。如果一个帐户具有空用户名,例如LDAP 身份验证与代理中描述的默认匿名''@'%'
代理帐户,则 Client 端可能会使用不同的用户名连接到 MySQL 服务器。但是原理是相同的:如果认证字符串以+
开头,则插件将使用 Client 端发送的用户名和认证字符串来构造用户 DN。
LDAP 身份验证方法
LDAP 认证插件使用可配置的认证方法。适当的系统变量和可用的方法选择是特定于插件的:
-
对于
authentication_ldap_simple
插件:通过设置authentication_ldap_simple_auth_method_name系统变量来配置方法。允许的选择是SIMPLE
和AD-FOREST
。 -
对于
authentication_ldap_sasl
插件:通过设置authentication_ldap_sasl_auth_method_name系统变量来配置方法。唯一允许的选择是SCRAM-SHA-1
。
有关每个允许的方法的信息,请参见系统变量描述。