### 6.2.17 可插拔身份验证

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

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

-   否则，服务器调用该插件对用户进行身份验证，并且插件向服务器返回一个状态，指示用户是否提供了正确的密码并被允许连接。

    可插拔身份验证支持以下重要功能：

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

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

-   **代理用户：**如果允许用户连接，则认证插件可以向服务器返回与连接用户名不同的用户名，以表明连接用户是另一个用户（被代理用户）的代理。在连接持续期间，出于访问控制的目的，代理用户被视为具有代理用户的权限。实际上，一个用户冒充另一个用户。有关详细信息，请参阅[第 6.2.19 节，“代理用户”](proxy-users.html).

笔记

如果您使用以下命令启动服务器[`--skip-grant-tables`](server-options.html#option_mysqld_skip-grant-tables)选项，即使加载了身份验证插件也不会使用，因为服务器不执行客户端身份验证并允许任何客户端连接。因为这是不安全的，如果服务器以[`--skip-grant-tables`](server-options.html#option_mysqld_skip-grant-tables)选项，它还通过启用禁用远程连接[`跳过网络`](server-system-variables.html#sysvar_skip_networking).

-   [可用的身份验证插件](pluggable-authentication.html#pluggable-authentication-available-plugins)

-   [默认身份验证插件](pluggable-authentication.html#pluggable-authentication-default-plugin)

-   [身份验证插件使用](pluggable-authentication.html#pluggable-authentication-usage)

-   [身份验证插件客户端/服务器兼容性](pluggable-authentication.html#pluggable-authentication-compatibility)

-   [身份验证插件连接器 - 编写注意事项](pluggable-authentication.html#pluggable-authentication-connector-writing)

-   [可插拔身份验证的限制](pluggable-authentication.html#pluggable-authentication-restrictions)

#### 可用的身份验证插件

MySQL 8.0 提供了这些认证插件：

-   执行本机身份验证的插件；也就是说，在 MySQL 中引入可插入身份验证之前使用的基于密码散列方法的身份验证。这`mysql_native_password`插件基于此本机密码散列方法实现身份验证。看[第 6.4.1.1 节，“本机可插入身份验证”](native-pluggable-authentication.html).

-   使用 SHA-256 密码哈希执行身份验证的插件。这比本机身份验证提供的加密更强。看[第 6.4.1.2 节，“缓存 SHA-2 可插入身份验证”](caching-sha2-pluggable-authentication.html)， 和[第 6.4.1.3 节，“SHA-256 可插入身份验证”](sha256-pluggable-authentication.html).

-   一个客户端插件，无需散列或加密即可将密码发送到服务器。此插件与需要完全按照客户端用户提供的密码访问的服务器端插件一起使用。看[第 6.4.1.4 节，“客户端明文可插入身份验证”](cleartext-pluggable-authentication.html).

-   一个使用 PAM（Pluggable Authentication Modules）执行外部身份验证的插件，使 MySQL Server 能够使用 PAM 来验证 MySQL 用户。这个插件也支持代理用户。看[第 6.4.1.5 节，“PAM 可插入身份验证”](pam-pluggable-authentication.html).

-   一个在 Windows 上执行外部身份验证的插件，使 MySQL Server 能够使用本机 Windows 服务来验证客户端连接。登录到 Windows 的用户可以根据其环境中的信息从 MySQL 客户端程序连接到服务器，而无需指定额外的密码。这个插件也支持代理用户。看[第 6.4.1.6 节，“Windows 可插入身份验证”](windows-pluggable-authentication.html).

-   使用 LDAP（轻量级目录访问协议）执行身份验证的插件，通过访问 X.500 等目录服务来验证 MySQL 用户。这些插件也支持代理用户。看[第 6.4.1.7 节，“LDAP 可插入身份验证”](ldap-pluggable-authentication.html).

-   一个使用 Kerberos 执行身份验证的插件，以对与 Kerberos 主体相对应的 MySQL 用户进行身份验证。看[第 6.4.1.8 节，“Kerberos 可插入身份验证”](kerberos-pluggable-authentication.html).

-   一个插件，可防止所有客户端连接到使用它的任何帐户。此插件的用例包括不应允许直接登录但只能通过代理帐户访问的代理帐户，以及必须能够以提升的权限执行存储的程序和视图而不将这些权限暴露给普通用户的帐户。看[第 6.4.1.9 节，“非登录可插入身份验证”](no-login-pluggable-authentication.html).

-   通过 Unix 套接字文件对从本地主机连接的客户端进行身份验证的插件。看[第 6.4.1.10 节，“Socket Peer-Credential Pluggable Authentication”](socket-pluggable-authentication.html).

-   使用 FIDO 身份验证对 MySQL 服务器进行用户身份验证的插件。看[第 6.4.1.11 节，“FIDO 可插入身份验证”](fido-pluggable-authentication.html).

-   一个测试插件，用于检查帐户凭据并将成功或失败记录到服务器错误日志中。此插件旨在用于测试和开发目的，并作为如何编写身份验证插件的示例。看[第 6.4.1.12 节，“测试可插入身份验证”](test-pluggable-authentication.html).

笔记

有关使用可插入身份验证的当前限制的信息，包括哪些连接器支持哪些插件，请参阅[可插拔身份验证的限制](pluggable-authentication.html#pluggable-authentication-restrictions).

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

如果您有兴趣编写自己的身份验证插件，请参阅[编写身份验证插件](https://dev.mysql.com/doc/extending-mysql/8.0/en/writing-authentication-plugins.html).

#### 默认身份验证插件

[](<>)[](<>)[](<>)[](<>)[](<>)[](<>)

这[`创建用户`](create-user.html)和[`更改用户`](alter-user.html)语句具有用于指定帐户如何进行身份验证的语法。这种语法的某些形式没有明确命名身份验证插件（没有`标识为`条款）。例如：

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

在这种情况下，服务器将默认身份验证插件分配给帐户。在 MySQL 8.0.27 之前，这个默认值是[`default_authentication_plugin`](server-system-variables.html#sysvar_default_authentication_plugin)系统变量。

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

-   因素 1：如果[`身份验证策略`](server-system-variables.html#sysvar_authentication_policy)元素 1 命名身份验证插件，该插件是默认插件。如果[`身份验证策略`](server-system-variables.html#sysvar_authentication_policy)元素 1 是`*`， 的价值[`default_authentication_plugin`](server-system-variables.html#sysvar_default_authentication_plugin)是默认值。

    鉴于上述规则，以下语句创建一个双因素身份验证帐户，第一因素身份验证方法由[`身份验证策略`](server-system-variables.html#sysvar_authentication_policy)要么[`default_authentication_plugin`](server-system-variables.html#sysvar_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.html)查看应用的身份验证方法。

-   因素 2 或 3：如果相应的[`身份验证策略`](server-system-variables.html#sysvar_authentication_policy)元素命名身份验证插件，该插件是默认插件。如果[`身份验证策略`](server-system-variables.html#sysvar_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 节，“身份验证插件”](authentication-plugins.html).

通常，可插拔身份验证在服务器端和客户端使用一对对应的插件，因此您使用给定的身份验证方法，如下所示：

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

-   对于您创建的每个MySQL帐户，指定用于身份验证的适当服务器端插件。如果帐户要使用默认的身份验证插件，则帐户创建语句无需明确指定插件。服务器将默认身份验证插件分配给服务器，如中所述[默认的身份验证插件](pluggable-authentication.html#pluggable-authentication-default-plugin).

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

    在帐户使用服务器和客户端程序默认的身份验证方法的情况下，服务器不需要与客户端通信要使用哪个客户端插件，并且可以避免客户端/服务器协商中的往返。

    对于标准的MySQL客户端，例如[**mysql**](mysql.html)和[**mysqladmin**](mysqladmin.html)这个[`--默认身份验证=*`插件名称`*`](mysql-command-options.html#option_mysql_default-auth)选项可以在命令行上指定，作为程序预期使用的客户端插件的提示，尽管如果与用户帐户关联的服务器端插件需要不同的客户端插件，服务器会覆盖该选项。

    如果客户端程序找不到客户端插件库文件，请指定[`--插件目录=*`目录名`*`](mysql-command-options.html#option_mysql_plugin-dir)选项指示插件库目录位置。

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

[](<>)

可插拔身份验证允许灵活选择MySQL帐户的身份验证方法，但在某些情况下，由于客户端和服务器之间的身份验证插件不兼容，无法建立客户端连接。

成功地将客户端连接到给定服务器上的给定帐户的一般兼容性原则是，客户端和服务器都必须支持身份验证*方法*账户要求的。由于身份验证方法由身份验证插件实现，因此客户端和服务器都必须支持身份验证*插件*账户要求的。

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

-   使用5.7.22或更低版本的MySQL 5.7客户端连接到通过身份验证的MySQL 8.0服务器帐户`缓存_sha2_密码`.这失败了，因为5.7客户端无法识别MySQL 8.0中引入的插件。（从5.7.23开始，MySQL 5.7中解决了这个问题，当`缓存_sha2_密码`MySQL客户端库和客户端程序中添加了客户端支持。）

-   使用MySQL 5.7客户端连接到使用`mysql_旧密码`.这失败有多种原因。首先，这种联系需要`--安全身份验证=0`，不再是受支持的选项。即使支持，5.7客户端也无法识别该插件，因为它在MySQL 5.7中被删除。

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

    一般来说，在同一MySQL发行版的客户机和服务器之间建立连接时，不会出现这些兼容性问题。当在不同MySQL系列的客户机和服务器之间建立连接时，可能会出现问题。当MySQL引入新的身份验证插件或删除旧插件时，这些问题是开发过程中固有的。为了将不兼容的可能性降至最低，请定期及时升级服务器、客户端和连接器。

#### 身份验证插件连接器编写注意事项

[](<>)

MySQL客户机/服务器协议的各种实现都存在。这个`libmysqlclient`C API客户端库就是一种实现。一些MySQL连接器（通常不是用C编写的）提供了自己的实现。然而，并非所有协议实现都以相同的方式处理插件身份验证。本节描述协议实现者应该考虑的身份验证问题。

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

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

为了避免这个问题，客户端使用的协议实现应该有自己的默认插件，并且应该将其作为第一选择（或者，如果无法加载服务器指定的默认插件，则返回到此默认值）。例子：

-   在MySQL 5.7中，`libmysqlclient`使用作为其默认选项`mysql_本机_密码`或者通过`MYSQL\u默认值\u身份验证`选择[`mysql_选项（）`](https://dev.mysql.com/doc/c-api/8.0/en/mysql-options.html).

-   当5.7客户端尝试连接到8.0服务器时，服务器会指定`缓存_sha2_密码`作为其默认的身份验证插件，但客户端仍会根据`mysql_本机_密码`或者任何通过`MYSQL\u默认值\u身份验证`.

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

#### 对可插拔身份验证的限制

[](<>)[](<>)

本节的第一部分介绍了对可插拔身份验证框架适用性的一般限制[第6.2.17节，“可插拔认证”](pluggable-authentication.html)第二部分描述了第三方连接器开发人员如何确定连接器可以在多大程度上利用可插拔身份验证功能，以及采取哪些步骤来提高兼容性。

这里使用的术语“本机身份验证”指的是针对存储在`mysql。使用者`系统表。这与较早的MySQL服务器在实现可插拔身份验证之前提供的身份验证方法相同。“Windows本机身份验证”是指使用已登录Windows的用户的凭据进行身份验证，由Windows本机身份验证插件（简称“Windows插件”）实现。

-   [通用可插拔身份验证限制](pluggable-authentication.html#pluggable-authentication-restrictions-general)

-   [可插拔身份验证和第三方连接器](pluggable-authentication.html#pluggable-authentication-restrictions-third-party-connectors)

##### 通用可插拔身份验证限制

-   **连接器/C++：**使用此连接器的客户端只能通过使用本机身份验证的帐户连接到服务器。

    例外情况：如果连接器是为链接而构建的，则它支持可插拔身份验证`libmysqlclient`动态（而非静态）加载当前版本的`libmysqlclient`如果安装了该版本，或者根据当前版本从源到链接重新编译连接器`libmysqlclient`.

    有关写入连接器以处理来自服务器的有关默认服务器端身份验证插件的信息的信息，请参阅[身份验证插件连接器编写注意事项](pluggable-authentication.html#pluggable-authentication-connector-writing).

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

-   **连接器/PHP：**当使用MySQL原生PHP驱动程序编译时，使用此连接器的客户端只能通过使用本机身份验证的帐户连接到服务器(`mysqlnd`).

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

-   **代理用户：**代理用户支持的范围是，客户端可以通过使用实现代理用户功能的插件（即可以返回与连接用户不同的用户名的插件）验证的帐户进行连接。例如，PAM和Windows插件支持代理用户。这个`mysql_本机_密码`和`shau密码`默认情况下，身份验证插件不支持代理用户，但可以配置为支持代理用户；看见[服务器对代理用户映射的支持](proxy-users.html#proxy-users-server-user-mapping).

-   **复制**：复制副本不仅可以使用使用本机身份验证的复制用户帐户，还可以通过使用非本机身份验证的复制用户帐户进行连接（如果所需的客户端插件可用）。如果插件内置在`libmysqlclient`，默认情况下该选项可用。否则，插件必须安装在副本端的副本名称目录中[`插件目录`](server-system-variables.html#sysvar_plugin_dir)系统变量。

-   **[`联邦的`](federated-storage-engine.html)桌子：**A.[`联邦的`](federated-storage-engine.html)表只能通过远程服务器上使用本机身份验证的帐户访问远程表。

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

第三方连接器开发人员可以使用以下准则来确定连接器是否准备好利用可插拔身份验证功能，以及采取哪些步骤来提高兼容性：

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

    例外：如果连接器链接到`libmysqlclient`动态（而非静态）加载当前版本的`libmysqlclient`如果安装了该版本。

-   为了利用可插拔身份验证功能，一个`libmysqlclient`-应根据的当前版本重新链接`libmysqlclient`。这使连接器能够通过需要内置客户端插件的帐户支持连接`libmysqlclient`（例如PAM身份验证所需的明文插件和Windows本机身份验证所需的Windows插件）。与电流连接`libmysqlclient`还允许连接器访问安装在默认MySQL插件目录（通常是以本地服务器的默认值命名的目录）中的客户端插件[`插件目录`](server-system-variables.html#sysvar_plugin_dir)系统变量）。

    如果连接器链接到`libmysqlclient`在动态方面，必须确保更新版本的`libmysqlclient`安装在客户端主机上，并且连接器在运行时加载它。

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

-   如果连接器应该能够从不同于默认插件目录的目录加载客户端插件，那么它必须为客户端用户实现一些指定目录的方法。这可能包括一个命令行选项或环境变量，连接器可以从中获取目录名。标准MySQL客户端程序，例如[**mysql**](mysql.html)和[**mysqladmin**](mysqladmin.html)实施`--插件目录`选项另见[C API客户端插件接口](https://dev.mysql.com/doc/c-api/8.0/en/c-api-plugin-interface.html).

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