Documentation Home

6.2.17 可插拔认证

当客户端连接到 MySQL 服务器时,服务器使用客户端提供的用户名和客户端主机从mysql.user 系统表中选择合适的帐户行。服务器然后对客户端进行身份验证,从帐户行确定哪个身份验证插件适用于客户端:

  • 如果服务器找不到插件,则会发生错误并拒绝连接尝试。

  • 否则,服务器调用该插件来验证用户,插件向服务器返回一个状态,指示用户是否提供了正确的密码并被允许连接。

可插入身份验证支持以下重要功能:

  • 身份验证方法的选择。  可插入身份验证使 DBA 可以轻松选择和更改用于单个 MySQL 帐户的身份验证方法。

  • 外部认证。  可插入身份验证使客户端可以使用适用于将凭据存储在mysql.user系统表以外的其他位置的身份验证方法的凭据连接到 MySQL 服务器。例如,可以创建插件以使用外部身份验证方法,如 PAM、Windows 登录 ID、LDAP 或 Kerberos。

  • 代理用户:  如果允许用户连接,身份验证插件可以向服务器返回一个与连接用户名称不同的用户名,以指示连接用户是另一个用户(被代理用户)的代理。当连接持续时,出于访问控制的目的,代理用户被视为具有被代理用户的特权。实际上,一个用户冒充另一个用户。有关详细信息,请参阅第 6.2.19 节,“代理用户”

笔记

如果使用该 --skip-grant-tables选项启动服务器,即使加载了身份验证插件也不会使用,因为服务器不执行客户端身份验证并允许任何客户端连接。因为这是不安全的,如果服务器以该--skip-grant-tables 选项启动,它还会通过启用来禁用远程连接 skip_networking

可用的身份验证插件

MySQL 8.0 提供了这些身份验证插件:

笔记

有关使用可插入身份验证的当前限制的信息,包括哪些连接器支持哪些插件,请参阅 可插入身份验证的限制

第三方连接器开发人员应阅读该部分以确定连接器可以在多大程度上利用可插入身份验证功能以及采取哪些步骤来变得更加合规。

如果您有兴趣编写自己的身份验证插件,请参阅编写身份验证插件

默认身份验证插件

CREATE USERand ALTER USER语句具有指定帐户身份验证方式的语法 。此语法的某些形式没有明确命名身份验证插件(没有IDENTIFIED WITH子句)。例如:

CREATE USER 'jeffrey'@'localhost' IDENTIFIED BY 'password';

在这种情况下,服务器会将默认身份验证插件分配给该帐户。在 MySQL 8.0.27 之前,这个默认值是 default_authentication_plugin 系统变量的值。

从引入多因素身份验证的 MySQL 8.0.27 开始,最多可以有三个子句来指定帐户如何进行身份验证。确定没有命名插件的身份验证方法的默认身份验证插件的规则是特定于因素的:

  • 因素 1:如果 authentication_policy 元素 1 命名了一个身份验证插件,则该插件是默认插件。如果 authentication_policy 元素 1 是*,则值为 default_authentication_plugin 默认值。

    鉴于上述规则,以下语句创建一个双因素身份验证帐户,第一因素身份验证方法由 authentication_policyor default_authentication_plugin 设置确定:

    CREATE USER 'wei'@'localhost' IDENTIFIED BY 'password'
      AND IDENTIFIED WITH authentication_ldap_simple;

    同样,这个例子创建了一个三因素认证账户:

    CREATE USER 'mateo'@'localhost' IDENTIFIED BY 'password'
      AND IDENTIFIED WITH authentication_ldap_simple
      AND IDENTIFIED WITH authentication_fido;

    您可以使用SHOW CREATE USER 查看应用的身份验证方法。

  • 因素 2 或 3:如果相应的 authentication_policy 元素命名了一个身份验证插件,则该插件是默认插件。如果 authentication_policy 元素为*空,则没有默认值;尝试在不命名插件的情况下为因子定义帐户身份验证方法是错误的,如以下示例所示:

    mysql> CREATE USER 'sofia'@'localhost' IDENTIFIED WITH authentication_ldap_simple 
           AND IDENTIFIED BY 'abc';
    ERROR 1524 (HY000): Plugin '' is not loaded
    
    mysql> CREATE USER 'sofia'@'localhost' IDENTIFIED WITH authentication_ldap_simple 
           AND IDENTIFIED BY 'abc';
    ERROR 1524 (HY000): Plugin '*' is not loaded

身份验证插件使用

本节提供安装和使用身份验证插件的一般说明。有关特定于给定插件的说明,请参阅 第 6.4.1 节“身份验证插件”下描述该插件的部分。

通常,可插入身份验证在服务器端和客户端使用一对相应的插件,因此您可以像这样使用给定的身份验证方法:

  • 如有必要,安装插件库或包含适当插件的库。在服务器主机上,安装包含服务器端插件的库,以便服务器可以使用它来验证客户端连接。同样,在每个客户端主机上,安装包含客户端插件的库以供客户端程序使用。无需安装内置的身份验证插件。

  • 对于您创建的每个 MySQL 帐户,指定适当的服务器端插件以用于身份验证。如果帐户要使用默认的身份验证插件,则帐户创建语句不需要明确指定插件。服务器分配默认身份验证插件,如 默认身份验证插件中所述确定。

  • 当客户端连接时,服务器端插件会告诉客户端程序使用哪个客户端插件进行身份验证。

如果帐户使用服务器和客户端程序默认的身份验证方法,则服务器无需与客户端通信使用哪个客户端插件,并且可以在客户端/服务器协商中进行往返避免了。

对于标准的 MySQL 客户端,如mysqlmysqladmin, 可以在命令行上指定选项作为程序可以使用哪个客户端插件的提示,尽管如果服务器端插件与用户关联,服务器会覆盖它帐户需要不同的客户端插件。 --default-auth=plugin_name

如果客户端程序没有找到客户端插件库文件,则指定一个 选项来指示插件库目录位置。 --plugin-dir=dir_name

身份验证插件客户端/服务器兼容性

Pluggable authentication可以灵活选择MySQL账户的认证方式,但在某些情况下,由于客户端和服务器之间的认证插件不兼容,无法建立客户端连接。

客户端成功连接到给定服务器上给定帐户的一般兼容性原则是客户端和服务器都必须支持 该帐户所需的身份验证方法。因为认证方式是通过认证插件实现的,所以客户端和服务端都必须支持账号需要 的认证插件。

身份验证插件不兼容可能以各种方式出现。例子:

  • 使用 5.7.22 或更低版本的 MySQL 5.7 客户端连接到使用 caching_sha2_password. 失败是因为 5.7 客户端无法识别 MySQL 8.0 中引入的插件。(当 caching_sha2_password客户端支持添加到 MySQL 客户端库和客户端程序时,从 5.7.23 开始的 MySQL 5.7 中解决了这个问题。)

  • 使用 MySQL 5.7 客户端连接到使用 mysql_old_password. 由于多种原因,这失败了。首先,这样的连接需要 --secure-auth=0,这不再是受支持的选项。即使支持,5.7 客户端也无法识别该插件,因为它已在 MySQL 5.7 中删除。

  • 使用 MySQL 5.7 客户端从社区分发连接到 MySQL 5.7 企业服务器帐户,该帐户使用仅限企业的 LDAP 身份验证插件之一进行身份验证。这会失败,因为社区客户端无权访问企业插件。

通常,当来自同一 MySQL 发行版的客户端和服务器之间建立连接时,不会出现这些兼容性问题。当来自不同 MySQL 系列的客户端和服务器之间建立连接时,可能会出现问题。当 MySQL 引入新的身份验证插件或删除旧插件时,这些问题是开发过程中固有的。为了尽量减少不兼容的可能性,请定期及时升级服务器、客户端和连接器。

Authentication Plugin Connector-编写注意事项

存在 MySQL 客户端/服务器协议的各种实现。libmysqlclientC API 客户端库是一种实现。一些 MySQL 连接器(通常是那些不是用 C 编写的)提供了自己的实现。但是,并非所有协议实现都以相同的方式处理插件身份验证。本节描述协议实施者应考虑的身份验证问题。

在客户端/服务器协议中,服务器告诉连接的客户端它认为哪个身份验证插件是默认的。如果客户端使用的协议实现尝试加载默认插件,而该插件在客户端不存在,则加载操作失败。如果默认插件不是客户端尝试连接的帐户实际需要的插件,则这是不必要的失败。

如果客户端/服务器协议实现没有自己的默认身份验证插件概念,并且总是尝试加载服务器指定的默认插件,那么如果该插件不可用,它就会失败并出现错误。

为了避免这个问题,客户端使用的协议实现应该有自己的默认插件,并将其作为首选(或者,如果无法加载服务器指定的默认插件,则回退到这个默认值) . 例子:

  • 在 MySQL 5.7 中,libmysqlclient使用作为其默认选择 或通过 选项mysql_native_password指定的插件。 MYSQL_DEFAULT_AUTHmysql_options()

  • 当 5.7 客户端尝试连接到 8.0 服务器时,服务器将指定caching_sha2_password为其默认身份验证插件,但客户端仍会根据 mysql_native_password通过MYSQL_DEFAULT_AUTH.

  • 客户端加载服务器指定的插件的唯一时间是更改插件请求,但在这种情况下,它可以是任何插件,具体取决于用户帐户。在这种情况下,客户端必须尝试加载插件,如果该插件不可用,则错误不是可选的。

可插入身份验证的限制

本节的第一部分描述了第 6.2.17 节“可插入身份验证”中描述的可插入身份验证框架的适用性的一般限制。第二部分描述了第三方连接器开发人员如何确定连接器可以在多大程度上利用可插入的身份验证功能以及采取哪些步骤来变得更加合规。

这里使用的术语本机身份验证是指针对存储在 mysql.user系统表中的密码进行身份验证。在实现可插入身份验证之前,这与旧版 MySQL 服务器提供的身份验证方法相同。Windows native authentication是指使用已经登录Windows的用户的凭据进行身份验证,由Windows Native Authentication plugin(简称Windows plugin)实现。

一般可插入身份验证限制
  • 连接器/C++:使用此连接器的客户端只能通过使用本机身份验证的帐户连接到服务器。

    例外:如果连接器被构建为libmysqlclient 动态链接(而不是静态)并且它加载当前版本(libmysqlclient如果安装了该版本),或者如果连接器从源代码重新编译以链接到当前 libmysqlclient.

    有关编写连接器以处理来自服务器的有关默认服务器端身份验证插件的信息的信息,请参阅 身份验证插件连接器编写注意事项

  • Connector/NET:使用 Connector/NET 的客户端可以通过使用本机身份验证或 Windows 本机身份验证的帐户连接到服务器。

  • 连接器/PHP:使用此连接器的客户端只能通过使用本地身份验证的帐户连接到服务器,当使用 PHP 的 MySQL 本机驱动程序编译时 (mysqlnd)。

  • Windows 本机身份验证:通过使用 Windows 插件的帐户连接需要 Windows 域设置。没有它,将使用 NTLM 身份验证,然后只能进行本地连接;也就是说,客户端和服务器必须运行在同一台计算机上。

  • 代理用户:代理用户支持在客户端可以通过使用实现代理用户功能的插件(即可以返回与连接用户不同的用户名的插件)进行身份验证的帐户进行连接的范围内可用。例如,PAM 和 Windows 插件支持代理用户。和认证插件默认不支持代理用户,但可以配置支持mysql_native_passwordsha256_password请参阅 代理用户映射的服务器支持

  • 复制:副本不仅可以使用使用本机身份验证的复制用户帐户,而且如果所需的客户端插件可用,还可以通过使用非本机身份验证的复制用户帐户进行连接。如果插件内置于libmysqlclient中,则默认可用。否则,插件必须安装在副本端的副本plugin_dir系统变量命名的目录中。

  • FEDERATED tables:FEDERATED 只能通过远程服务器上使用本机身份验证的帐户访问远程表。

可插拔身份验证和第三方连接器

第三方连接器开发人员可以使用以下准则来确定连接器是否准备好利用可插入身份验证功能以及采取哪些步骤来变得更加合规:

  • 未进行任何更改的现有连接器使用本机身份验证,使用该连接器的客户端只能通过使用本机身份验证的帐户连接到服务器。但是,您应该针对最新版本的服务器测试连接器,以验证此类连接是否仍然可以正常工作。

    例外:如果连接器 libmysqlclient动态(而不是静态)链接到并加载当前版本( libmysqlclient如果安装了该版本),则连接器可能无需任何更改即可使用可插入身份验证。

  • 要利用可插入的身份验证功能,libmysqlclient基于 libmysqlclient. 这使连接器能够支持通过现在内置的需要客户端插件的帐​​户进行连接 libmysqlclient(例如 PAM 身份验证所需的明文插件和 Windows 本机身份验证所需的 Windows 插件)。与当前链接libmysqlclient还使连接器能够访问安装在默认 MySQL 插件目录中的客户端插件(通常是本地服务器的默认值命名的目录) plugin_dir系统变量)。

    如果连接器libmysqlclient 动态链接,则必须确保 libmysqlclient客户端主机上安装了较新版本,并且连接器在运行时加载它。

  • 连接器支持给定身份验证方法的另一种方法是直接在客户端/服务器协议中实现它。Connector/NET 使用这种方法来提供对 Windows 本机身份验证的支持。

  • 如果连接器应该能够从与默认插件目录不同的目录加载客户端插件,则它必须实现一些方法让客户端用户指定目录。这可能包括命令行选项或环境变量,连接器可以从中获取目录名称。mysqlmysqladmin等标准 MySQL 客户端程序实现了一个 --plugin-dir选项。另请参阅 C API 客户端插件接口

  • 如本节前面所述,连接器对代理用户的支持取决于它支持的身份验证方法是否允许代理用户。