当客户端连接到 MySQL 服务器时,服务器会使用客户端提供的用户名和客户端主机从 mysql.user
系统表中选择相应的帐户行。然后,服务器会对客户端进行身份验证,并根据帐户行确定适用于客户端的身份验证插件
如果服务器找不到该插件,则会发生错误,并且连接尝试会被拒绝。
否则,服务器会调用该插件对用户进行身份验证,并且插件会向服务器返回一个状态,指示用户是否提供了正确的密码并且允许连接。
可插拔身份验证支持以下重要功能
身份验证方法的选择。 可插拔身份验证使 DBA 可以轻松地选择和更改用于各个 MySQL 帐户的身份验证方法。
外部身份验证。 可插拔身份验证使客户端可以使用适用于将凭据存储在
mysql.user
系统表以外的其他位置的身份验证方法的凭据连接到 MySQL 服务器。例如,可以创建插件以使用外部身份验证方法,例如 PAM、Windows 登录 ID、LDAP 或 Kerberos。代理用户: 如果允许用户连接,则身份验证插件可以向服务器返回与连接用户名称不同的用户名,以指示连接用户是另一个用户(被代理用户)的代理。在连接持续期间,出于访问控制的目的,代理用户将被视为具有被代理用户的权限。实际上,一个用户可以模拟另一个用户。有关更多信息,请参见 第 8.2.19 节“代理用户”。
如果使用 --skip-grant-tables
选项启动服务器,即使已加载身份验证插件,也不会使用它们,因为服务器不执行客户端身份验证并允许任何客户端连接。因为这很不安全,所以如果使用 --skip-grant-tables
选项启动服务器,它还会通过启用 skip_networking
来禁用远程连接。
MySQL 8.4 提供以下身份验证插件
执行原生身份验证的插件;也就是说,基于在 MySQL 中引入可插拔身份验证之前使用的密码哈希方法的身份验证。
mysql_native_password
插件实现了基于此原生密码哈希方法的身份验证。请参见 第 8.4.1.1 节“原生可插拔身份验证”。注意mysql_native_password
身份验证插件已弃用,并将在未来版本的 MySQL 中删除。使用 SHA-256 密码哈希执行身份验证的插件。这比原生身份验证提供的加密更强大。请参见 第 8.4.1.2 节“缓存 SHA-2 可插拔身份验证” 和 第 8.4.1.3 节“SHA-256 可插拔身份验证”。
一个客户端插件,它将密码发送到服务器,而无需进行哈希或加密。此插件与需要完全按照客户端用户提供的方式访问密码的服务器端插件一起使用。请参见 第 8.4.1.4 节“客户端明文可插拔身份验证”。
一个使用 PAM(可插拔身份验证模块)执行外部身份验证的插件,使 MySQL 服务器能够使用 PAM 对 MySQL 用户进行身份验证。此插件也支持代理用户。请参阅第 8.4.1.5 节 “PAM 可插拔身份验证”。
一个在 Windows 上执行外部身份验证的插件,使 MySQL 服务器能够使用本地 Windows 服务对客户端连接进行身份验证。登录到 Windows 的用户可以根据其环境中的信息从 MySQL 客户端程序连接到服务器,而无需指定其他密码。此插件也支持代理用户。请参阅第 8.4.1.6 节 “Windows 可插拔身份验证”。
使用 LDAP(轻量级目录访问协议)执行身份验证的插件,通过访问 X.500 等目录服务对 MySQL 用户进行身份验证。这些插件也支持代理用户。请参阅第 8.4.1.7 节 “LDAP 可插拔身份验证”。
一个使用 Kerberos 执行身份验证的插件,用于对与 Kerberos 主体对应的 MySQL 用户进行身份验证。请参阅第 8.4.1.8 节 “Kerberos 可插拔身份验证”。
一个阻止所有客户端连接到使用它的任何帐户的插件。此插件的用例包括:永远不允许直接登录但只能通过代理帐户访问的代理帐户,以及必须能够以提升的权限执行存储过程和视图而不会将这些权限暴露给普通用户的帐户。请参阅第 8.4.1.9 节 “禁止登录可插拔身份验证”。
一个对通过 Unix 套接字文件从本地主机连接的客户端进行身份验证的插件。请参阅第 8.4.1.10 节 “套接字对等凭据可插拔身份验证”。
一个使用带有 FIDO/FIDO2 设备的 WebAuthn 格式对 MySQL 服务器用户进行身份验证的插件。请参阅第 8.4.1.11 节 “WebAuthn 可插拔身份验证”。
一个测试插件,用于检查帐户凭据并将成功或失败记录到服务器错误日志中。此插件用于测试和开发目的,以及作为如何编写身份验证插件的示例。请参阅第 8.4.1.12 节 “测试可插拔身份验证”。
有关使用可插拔身份验证的当前限制的信息,包括哪些连接器支持哪些插件,请参阅可插拔身份验证的限制。
第三方连接器开发人员应阅读该部分,以确定连接器可以在多大程度上利用可插拔身份验证功能,以及采取哪些步骤才能更好地兼容。
如果您有兴趣编写自己的身份验证插件,请参阅编写身份验证插件。
本节提供有关安装和使用身份验证插件的一般说明。有关特定插件的说明,请参阅第 8.4.1 节 “身份验证插件”下描述该插件的部分。
通常,可插拔身份验证在服务器端和客户端使用一对对应的插件,因此您可以使用如下所示的给定身份验证方法
如有必要,请安装包含相应插件的插件库。在服务器主机上,安装包含服务器端插件的库,以便服务器可以使用它对客户端连接进行身份验证。同样,在每个客户端主机上,安装包含客户端程序使用的客户端插件的库。内置的身份验证插件不需要安装。
对于您创建的每个 MySQL 帐户,请指定要用于身份验证的相应服务器端插件。如果帐户要使用默认身份验证插件,则帐户创建语句不需要显式指定插件。服务器将分配默认身份验证插件,该插件的确定方式如默认身份验证插件中所述。
当客户端连接时,服务器端插件会告诉客户端程序使用哪个客户端插件进行身份验证。
如果帐户使用的身份验证方法是服务器和客户端程序的默认方法,则服务器不需要与客户端通信使用哪个客户端插件,并且可以避免客户端/服务器协商中的往返行程。
对于标准 MySQL 客户端,例如mysql和mysqladmin,可以在命令行上指定--default-auth=
选项作为程序可以使用哪个客户端插件的提示,尽管如果与用户帐户关联的服务器端插件需要不同的客户端插件,则服务器会覆盖此选项。plugin_name
如果客户端程序找不到客户端插件库文件,请指定--plugin-dir=
选项以指示插件库目录位置。dir_name
可插拔身份验证允许灵活选择 MySQL 帐户的身份验证方法,但在某些情况下,由于客户端和服务器之间的身份验证插件不兼容,客户端连接可能无法建立。
成功建立客户端与给定服务器上的给定帐户的连接的一般兼容性原则是,客户端和服务器都必须支持帐户所需的方法。因为身份验证方法是由身份验证插件实现的,所以客户端和服务器都必须支持帐户所需的插件。
身份验证插件不兼容性可以通过多种方式出现。例如:
使用 5.7.22 或更低版本的 MySQL 5.7 客户端从连接到使用
caching_sha2_password
进行身份验证的 MySQL 8.4 服务器帐户。这将失败,因为 5.7 客户端无法识别该插件。(此问题已在 5.7.23 版本的 MySQL 5.7 中得到解决,在该版本中,caching_sha2_password
客户端支持已添加到 MySQL 客户端库和客户端程序中。)使用 MySQL 5.7 客户端连接到使用
mysql_old_password
进行身份验证的 5.7 之前的服务器帐户。这会由于多种原因而失败。首先,这样的连接需要--secure-auth=0
,这不再是受支持的选项。即使受支持,5.7 客户端也无法识别该插件,因为它已在 MySQL 5.7 中删除。使用来自社区发行版的 MySQL 5.7 客户端连接到使用其中一个仅限企业版使用的 LDAP 身份验证插件进行身份验证的 MySQL 5.7 企业版服务器帐户。这将失败,因为社区客户端无权访问企业版插件。
通常,在来自同一 MySQL 发行版的客户端和服务器之间建立连接时,不会出现这些兼容性问题。在来自不同 MySQL 系列的客户端和服务器之间建立连接时,可能会出现问题。当 MySQL 引入新的身份验证插件或删除旧插件时,这些问题在开发过程中是固有的。为了最大程度地减少不兼容的可能性,请及时定期升级服务器、客户端和连接器。
存在 MySQL 客户端/服务器协议的各种实现。libmysqlclient
C API 客户端库就是这样一种实现。一些 MySQL 连接器(通常不是用 C 编写的)提供了自己的实现。但是,并非所有协议实现都以相同的方式处理插件身份验证。本节描述了协议实现者应考虑的身份验证问题。
在客户端/服务器协议中,服务器会告诉连接的客户端它认为哪个身份验证插件是默认插件。如果客户端使用的协议实现尝试加载默认插件,并且该插件在客户端不存在,则加载操作将失败。如果默认插件不是客户端尝试连接的帐户实际需要的插件,那么这是一个不必要的失败。
如果客户端/服务器协议实现没有自己的默认身份验证插件概念,并且始终尝试加载服务器指定的默认插件,则如果该插件不可用,则会失败并显示错误。
为了避免此问题,客户端使用的协议实现应具有自己的默认插件,并应将其用作首选(或者,如果无法加载服务器指定的默认插件,则回退到此默认插件)。例如:
在 MySQL 5.7 中,
libmysqlclient
使用mysql_native_password
或通过mysql_options()
的MYSQL_DEFAULT_AUTH
选项指定的插件作为默认选择。当 5.7 客户端尝试连接到 8.4 服务器时,服务器会指定
caching_sha2_password
作为其默认身份验证插件,但客户端仍然会根据mysql_native_password
或MYSQL_DEFAULT_AUTH
指定的任何内容发送凭据详细信息。客户端加载服务器指定的插件的唯一时间是针对更改插件请求,但在这种情况下,它可以是任何插件,具体取决于用户帐户。在这种情况下,客户端必须尝试加载插件,如果该插件不可用,则错误是不可选的。
本节的第一部分描述了对第 8.2.17 节 “可插拔身份验证”中描述的可插拔身份验证框架的适用性的一般限制。第二部分描述了第三方连接器开发人员如何确定连接器可以在多大程度上利用可插拔身份验证功能,以及采取哪些步骤才能更好地兼容。
此处使用的术语““本地身份验证””指的是针对存储在mysql.user
系统表中的密码进行的身份验证。这与较旧的 MySQL 服务器(在实现可插拔身份验证之前)提供的身份验证方法相同。““Windows 本地身份验证””指的是使用已登录到 Windows 的用户的凭据进行的身份验证,如 Windows 本地身份验证插件(简称““Windows 插件””)中所实现的。
一般可插拔身份验证限制
连接器/C++:使用此连接器的客户端只能通过使用本地身份验证的帐户连接到服务器。
例外:如果连接器是构建为动态链接到
libmysqlclient
(而不是静态链接),并且它加载当前版本的libmysqlclient
(如果安装了该版本),或者如果连接器是从源代码重新编译以链接到当前版本的libmysqlclient
,则该连接器支持可插拔身份验证。有关编写连接器以处理来自服务器的有关默认服务器端身份验证插件的信息,请参阅身份验证插件连接器编写注意事项。
连接器/NET:使用连接器/NET 的客户端可以通过使用本地身份验证或 Windows 本地身份验证的帐户连接到服务器。
连接器/PHP:使用此连接器的客户端只能通过使用本地身份验证的帐户连接到服务器,当使用 PHP 的 MySQL 本地驱动程序 (
mysqlnd
) 编译时。Windows 本机身份验证: 通过使用 Windows 插件的帐户进行连接需要设置 Windows 域。否则,将使用 NTLM 身份验证,并且只能进行本地连接;也就是说,客户端和服务器必须在同一台计算机上运行。
代理用户: 只要客户端可以通过使用实现代理用户功能的插件(即可以返回与连接用户不同的用户名的插件)进行身份验证的帐户进行连接,就可以使用代理用户支持。例如,PAM 和 Windows 插件支持代理用户。
mysql_native_password
(已弃用)和sha256_password
(已弃用)身份验证插件默认不支持代理用户,但可以配置为支持;请参阅服务器对代理用户映射的支持。复制: 副本不仅可以使用采用本机身份验证的复制用户帐户,还可以通过使用非本机身份验证的复制用户帐户进行连接,前提是所需的客户端插件可用。如果该插件内置于
libmysqlclient
中,则默认情况下可用。否则,必须在副本端的plugin_dir
系统变量命名的目录中安装该插件。
可插拔身份验证和第三方连接器
第三方连接器开发人员可以使用以下准则来确定连接器是否已准备好利用可插拔身份验证功能,以及要采取哪些步骤来提高合规性
未进行任何更改的现有连接器使用本机身份验证,并且使用该连接器的客户端只能通过使用本机身份验证的帐户连接到服务器。但是,您应该使用最新版本的服务器测试连接器,以验证此类连接是否仍然可以正常工作。
例外:如果连接器动态链接到
libmysqlclient
(而不是静态链接),并且如果安装了当前版本的libmysqlclient
,它会加载该版本,则该连接器可能无需任何更改即可使用可插拔身份验证。为了利用可插拔身份验证功能,应针对当前版本的
libmysqlclient
重新链接基于libmysqlclient
的连接器。这使连接器能够支持通过现在内置于libmysqlclient
中的客户端插件(例如 PAM 身份验证所需的明文插件和 Windows 本机身份验证所需的 Windows 插件)进行的连接。与当前的libmysqlclient
链接还可以使连接器访问安装在默认 MySQL 插件目录中的客户端插件(通常是本地服务器的plugin_dir
系统变量的默认值命名的目录)。如果连接器动态链接到
libmysqlclient
,则必须确保在客户端主机上安装了较新版本的libmysqlclient
,并且连接器在运行时加载了该版本。连接器支持给定身份验证方法的另一种方法是在客户端/服务器协议中直接实现它。Connector/NET 使用此方法来提供对 Windows 本机身份验证的支持。
如果连接器应该能够从默认插件目录以外的目录加载客户端插件,则它必须实现某种方法,以便客户端用户可以指定该目录。这方面的可能性包括命令行选项或环境变量,连接器可以从中获取目录名。标准的 MySQL 客户端程序(例如 mysql 和 mysqladmin)实现了
--plugin-dir
选项。另请参阅 C API 客户端插件接口。如本节前面所述,连接器对代理用户的支持取决于其支持的身份验证方法是否允许代理用户。