LDAP可插拔身份验证
注意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身份验证的插件和库名称
插件或文件 | 插件或文件名 |
---|---|
服务器端插件名称 | uthentication_ldap_simple |
客户端插件名称 | mysql_clear_password |
库文件名 | uthentication_ldap_simple.so |
表6.19基于SASL的LDAP身份验证的插件和库名称
插件或文件 | 插件或文件名 |
---|---|
服务器端插件名称 | uthentication_ldap_sasl |
客户端插件名称 | uthentication_ldap_sasl_client |
库文件名 | uthentication_ldap_sasl.so , uthentication_ldap_sasl_client.so |
库文件仅包含身份验证插件。客户端插件内置在客户端库中。 uthentication_ldap_XXX
mysql_clear_password
libmysqlclient
每个服务器端LDAP插件均与特定的客户端插件一起使用:
- 服务器端
uthentication_ldap_simple
插件执行简单的LDAP身份验证。对于使用此插件的帐户进行的连接,客户端程序使用客户端mysql_clear_password
插件,该客户端插件将密码以明文形式发送到服务器。不使用密码哈希或加密,因此建议在MySQL客户端和服务器之间建立安全连接以防止密码泄露。 - 服务器端
uthentication_ldap_sasl
插件执行基于SASL的LDAP身份验证。对于使用此插件的帐户进行的连接,客户端程序使用客户端uthentication_ldap_sasl_client
插件。客户端和服务器端SASL LDAP插件使用SASL消息在LDAP协议内安全地传输凭据,以避免在MySQL客户端和服务器之间发送明文密码。
以下各节提供特定于LDAP可插拔身份验证的安装和使用信息:
- LDAP可插入身份验证的先决条件
- MySQL用户的LDAP身份验证如何工作
- 安装LDAP可插入身份验证
- 卸载LDAP可插入身份验证
- 使用LDAP可插入身份验证
- 简单LDAP认证
- 基于SASL的LDAP身份验证
- LDAP认证用户DN后缀
- LDAP身份验证与代理
- LDAP身份验证组首选项和映射规范
有关MySQL中的可插入身份验证的一般信息,有关mysql_clear_password
插件的信息,请参见“客户端明文可插入身份验证”。有关代理用户的信息,请参见“代理用户”。
注意如果您的系统支持PAM并允许LDAP作为PAM身份验证方法,则将LDAP用于MySQL用户身份验证的另一种方法是使用服务器端
uthentication_pam
插件。请参见“ PAM可插拔身份验证”。
LDAP可插入身份验证的先决条件
要将LDAP可插拔身份验证用于MySQL,必须满足以下先决条件:
- LDAP服务器必须可用于LDAP身份验证插件进行通信。
- 要由MySQL认证的LDAP用户必须存在于LDAP服务器管理的目录中。
- LDAP客户端库必须在使用服务器端
uthentication_ldap_sasl
或uthentication_ldap_simple
插件的系统上可用。当前,受支持的库是Windows本机LDAP库或非Windows系统上的OpenLDAP库。 要使用基于SASL的LDAP身份验证,请执行以下操作:
- LDAP服务器必须配置为与SASL服务器通信。
- 使用客户端
uthentication_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认证插件。有关安装插件的一般信息,请参见“MySQL服务器插件”。
要由服务器使用,插件库文件必须位于MySQL插件目录(由plugin_dir
系统变量命名的目录)中。如有必要,通过设置plugin_dir
服务器启动时的值来配置插件目录位置。
服务器端插件库文件的基本名称为 uthentication_ldap_simple
和 uthentication_ldap_sasl
。每个平台的文件名后缀都不同(例如,.so
对于Unix和类似Unix的系统,.dll
对于Windows)。
要在服务器启动时加载插件,请使用--plugin-load-add
选项来命名包含它们的库文件。使用此插件加载方法,每次服务器启动时必须给出选项。另外,为要配置的任何插件提供的系统变量指定值。
每个服务器端LDAP插件都公开了一组系统变量,这些变量可对其进行配置。设置其中大多数是可选的,但是您必须设置用于指定LDAP服务器主机的变量(以便插件知道连接的位置)和LDAP绑定操作的基础专有名称(以限制搜索范围并获得更快的搜索)。有关所有LDAP系统变量的详细信息,请参见“可插拔身份验证系统变量”。
要加载插件并为LDAP绑定操作设置LDAP服务器主机和基本专有名称,请在my.cnf
文件中放入诸如此类的行(.so
必要时调整平台的后缀):
[mysqld] plugin-load-add= uthentication_ldap_simple.so uthentication_ldap_simple_server_host=127.0.0.1 uthentication_ldap_simple_bind_base_dn="dc=example,dc=com" plugin-load-add= uthentication_ldap_sasl.so uthentication_ldap_sasl_server_host=127.0.0.1 uthentication_ldap_sasl_bind_base_dn="dc=example,dc=com"
修改之后my.cnf
,重新启动服务器以使新设置生效。
或者,要在运行时加载插件,请使用以下语句(.so
根据需要调整平台的后缀):
INSTALL PLUGIN authentication_ldap_simpleSONAME 'authentication_ldap_simple.so';INSTALL PLUGIN authentication_ldap_saslSONAME 'authentication_ldap_sasl.so';
INSTALL PLUGIN
立即加载该插件,并将其注册到mysql.plugins
系统表中,以使服务器为每次后续的正常启动加载该插件,而无需--plugin-load-add
。
在运行时安装插件后,它们的系统变量将变为可用,并且您可以将其设置添加到my.cnf
文件中,以配置插件以供后续重启。例如:
[mysqld] uthentication_ldap_simple_server_host=127.0.0.1 uthentication_ldap_simple_bind_base_dn="dc=example,dc=com" uthentication_ldap_sasl_server_host=127.0.0.1 uthentication_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
。请参见“变量分配的SET语法”。
要验证插件安装,请检查INFORMATION_SCHEMA.PLUGINS
表或使用以下SHOW PLUGINS
语句(请参见“获取服务器插件信息”)。例如:
mysql>SELECT PLUGIN_NAME, PLUGIN_STATUSFROM 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插件分别与特定的客户端插件一起使用:
- 服务器端
uthentication_ldap_simple
插件执行简单的LDAP身份验证。对于使用此插件的帐户进行的连接,客户端程序使用客户端mysql_clear_password
插件,该客户端插件将密码以明文形式发送到服务器。不使用密码哈希或加密,因此建议在MySQL客户端和服务器之间建立安全连接以防止密码泄露。 - 服务器端
uthentication_ldap_sasl
插件执行基于SASL的LDAP身份验证。对于使用此插件的帐户进行的连接,客户端程序使用客户端uthentication_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密码。另外,对于使用服务器端
uthentication_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
。要更改属性,请适当修改uthentication_ldap_simple_user_search_attr
或uthentication_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
语句指定 uthentication_ldap_simple
插件,并可以选择命名LDAP用户专有名称(DN):
CREATE USER userIDENTIFIED 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_simpleAS '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
选项)。请参见“客户端明文可插入身份验证”。- 为了避免在
mysql_clear_password
启用插件的情况下暴露密码,MySQL客户端应使用加密连接连接到MySQL服务器。请参见“配置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_ldap
LDAP专有名称的子句,则身份验证尝试将使用客户端提供的用户名(在这种情况下为betsy
)。如果没有用于的LDAP条目betsy
,则身份验证将失败。
基于SASL的LDAP身份验证
要配置用于SASL LDAP认证的MySQL帐户,该CREATE USER
语句指定 uthentication_ldap_sasl
插件,并可以选择命名LDAP用户专有名称(DN):
CREATE USER userIDENTIFIED 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_saslAS '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)
对于服务器端 uthentication_ldap_sasl
插件,客户端使用客户端 uthentication_ldap_sasl_client
插件。如果客户端程序找不到客户端插件,请指定一个--plugin-dir
选项来命名插件库文件的安装目录。
身份验证过程boris
与先前针对betsy
简单LDAP身份验证的过程类似,不同之处在于,客户端和服务器端SASL LDAP插件使用SASL消息在LDAP协议内安全地传输凭据,以避免在客户端之间发送明文密码。 MySQL客户端和服务器。
LDAP认证用户DN后缀
LDAP认证插件允许提供用户DN信息的认证字符串以 +
前缀字符开头:
- 在没有
+
字符的情况下,身份验证字符串值按原样处理而无需修改。 - 如果身份验证字符串以开头
+
,则插件将从客户端发送的用户名构造完整的用户DN值,以及身份验证字符串中指定的DN(已+
删除)。在构造的DN中,客户端用户名成为指定LDAP用户名的属性的值。这是uid
默认;要更改属性,请适当修改uthentication_ldap_simple_user_search_attr
或uthentication_ldap_sasl_user_search_attr
系统变量。身份验证字符串的存储方式如mysql.user
系统表,其中包含完整的用户DN,该用户DN在身份验证之前即时构建。
此帐户身份验证字符串 +
开头没有,因此将其作为完整用户DN:
CREATE USER 'baldwin'IDENTIFIED WITH authentication_ldap_simpleAS 'uid=admin,ou=People,dc=example,dc=com';
客户端使用帐户(baldwin
)中指定的用户名进行连接。在这种情况下,不使用该名称,因为身份验证字符串没有前缀,因此可以完全指定用户DN。
此帐户身份验证字符串确实 +
在开头,因此仅作为用户DN的一部分:
CREATE USER 'accounting'IDENTIFIED WITH authentication_ldap_simpleAS ' +ou=People,dc=example,dc=com';
客户端使用在帐户( ccounting
)中指定的用户名进行连接,在这种情况下,该用户名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
属性分别指定用户名和组值。要使用不同的用户和组属性名称,请设置适当的系统变量以配置插件:- 对于
uthentication_ldap_simple
:设置uthentication_ldap_simple_user_search_attr
和uthentication_ldap_simple_group_search_attr
。 - 对于
uthentication_ldap_sasl
:设置uthentication_ldap_sasl_user_search_attr
和uthentication_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
组属性值将成为经过身份验证的用户名,因此它们分别命名
ccounting
和front_office
帐户。- 这些示例假定使用SASL LDAP身份验证。对简单的LDAP身份验证进行适当的调整。
创建默认的代理MySQL帐户:
CREATE USER ''@'%'IDENTIFIED WITH authentication_ldap_simple;
代理帐户定义没有子句来命名LDAP用户DN。从而:AS ' uth_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
已安装了插件。有关说明,请参见“无登录可插入身份验证”。)有关防止代理帐户直接使用的替代方法,请参见防止直接登录代理帐户。
向代理帐户PROXY
授予每个代理帐户的特权:
GRANT PROXY ON 'accounting'@'localhost'TO ''@'%';GRANT PROXY ON 'front_office'@'localhost'TO ''@'%';
使用mysql命令行客户端以方式连接到MySQL服务器bash
。
shell>mysql --user=bash --password Enter password: basha_password (basha LDAP password)
身份验证如下:
- 服务器使用默认
''@'%'
代理帐户为客户端用户验证连接bash
。 匹配的LDAP条目是:
uid=basha,ou=People,dc=example,dc=com,cn=accounting
- 匹配的LDAP条目具有group属性
cn=accounting
,因此ccounting
成为经过身份验证的用户。 经过身份验证的用户不同于客户端用户名
bash
,其结果bash
被视为的代理ccounting
,并bash
假定了该ccounting
帐户的特权。以下查询返回输出,如下所示:mysql>
SELECT USER(), CURRENT_USER(), @@proxy_user; +----------------- +---------------------- +-------------- + | USER() | CURRENT_USER() | @@proxy_user | +----------------- +---------------------- +-------------- + | basha@localhost | accounting@localhost | ''@'%' | +----------------- +---------------------- +-------------- +
这说明bash
使用授予 ccounting
MySQL帐户的特权,并且通过默认的代理用户帐户进行代理。
现在basil
改为连接:
shell>mysql --user=basil --password Enter password: basil_password (basil LDAP password)
身份验证过程basil
与之前针对bash
以下内容所述的过程类似:
- 服务器使用默认
''@'%'
代理帐户为客户端用户验证连接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_saslAS ' +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
,则它们在身份验证字符串中分别与用户名user
和关联userc
。该插件使用相应的关联用户名作为代理用户名。 - 如果匹配的组名是
grp2
,则认证字符串中没有关联的用户名。该插件grp2
用作代理用户名。
如果LDAP服务器返回DN格式的组,则LDAP插件将解析组DN,以从中提取组名。
要指定LDAP组首选项和映射信息,请遵循以下原则:
- 以
#
前缀字符开始认证字符串的组首选项和映射部分。 组首选项和映射规范是一个或多个项目的列表,以逗号分隔。每个项目的格式为或。项目应按组名首选项顺序列出。对于由插件选择的,与LDAP服务器返回的组名集合匹配的组名,这两种语法的效果不同,如下所示:
group_name=user_name
group_name
- 对于指定为(带有用户名)的项目,组名映射到用户名,该用户名用作MySQL代理用户名。
group_name=user_name
- 对于指定为
group_name
(没有用户名)的项目,组名用作MySQL代理用户名。
- 对于指定为(带有用户名)的项目,组名映射到用户名,该用户名用作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后缀给出。