#### 6.4.1.7 LDAP 可插拔身份验证

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

笔记

LDAP 可插入身份验证是商业产品 MySQL 企业版中包含的扩展。要了解有关商业产品的更多信息，请参阅<https://www.mysql.com/products/>.

MySQL Enterprise Edition 支持一种身份验证方法，使 MySQL Server 能够使用 LDAP（轻量级目录访问协议）通过访问 X.500 等目录服务来验证 MySQL 用户。MySQL 使用 LDAP 来获取用户、凭证和组信息。

LDAP 可插入身份验证提供以下功能：

-   外部身份验证：LDAP 身份验证使 MySQL 服务器能够接受来自 LDAP 目录中 MySQL 授权表之外定义的用户的连接。

-   代理用户支持：LDAP 身份验证可以根据外部用户所属的 LDAP 组向 MySQL 返回一个不同于客户端程序传递的外部用户名的用户名。这意味着 LDAP 插件可以返回 MySQL 用户，该用户定义了外部 LDAP 身份验证用户应具有的权限。例如，一个名为`乔`可以连接并拥有名为的 MySQL 用户的权限`开发商`，如果 LDAP 组为`乔`是`开发商`.

-   安全性：使用 TLS，与 LDAP 服务器的连接可以是安全的。

    下表显示了用于简单和基于 SASL 的 LDAP 身份验证的插件和库文件名。您的系统上的文件名后缀可能不同。文件必须位于由[`插件目录`](server-system-variables.html#sysvar_plugin_dir)系统变量。

[](<>)

**表 6.21 简单 LDAP 身份验证的插件和库名称**

| 插件或文件 | 插件或文件名 |
| ----- | ------ |
| 服务器端插件名称 | `authentication_ldap_simple` |
| 客户端插件名称 | `mysql_clear_password` |
| 库文件名 | `authentication_ldap_simple.so` |

[](<>)

**表 6.22 基于 SASL 的 LDAP 身份验证的插件和库名称**

| 插件或文件 | 插件或文件名 |
| ----- | ------ |
| 服务器端插件名称 | `authentication_ldap_sasl` |
| 客户端插件名称 | `authentication_ldap_sasl_client` |
| 库文件名 | `authentication_ldap_sasl.so`,`authentication_ldap_sasl_client.so` |

库文件仅包括`身份验证_ldap_*`XXX`*`身份验证插件。客户端`mysql_clear_password`插件内置于`libmysql客户端`客户端库。

每个服务器端 LDAP 插件都与特定的客户端插件一起使用：

-   服务器端`authentication_ldap_simple`插件执行简单的 LDAP 身份验证。对于使用此插件的帐户的连接，客户端程序使用客户端`mysql_clear_password`插件，它将密码以明文形式发送到服务器。不使用密码散列或加密，因此建议在 MySQL 客户端和服务器之间建立安全连接，以防止密码泄露。

-   服务器端`authentication_ldap_sasl`插件执行基于 SASL 的 LDAP 身份验证。对于使用此插件的帐户的连接，客户端程序使用客户端`authentication_ldap_sasl_client`插入。客户端和服务器端 SASL LDAP 插件使用 SASL 消息在 LDAP 协议中安全传输凭据，以避免在 MySQL 客户端和服务器之间发送明文密码。

    服务器端 LDAP 身份验证插件仅包含在 MySQL 企业版中。它们不包含在 MySQL 社区发行版中。客户端 SASL LDAP 插件包含在所有发行版中，包括社区发行版，并且如前所述，客户端`mysql_clear_password`插件内置于`libmysql客户端`客户端库，它也包含在所有发行版中。这使来自任何发行版的客户端都可以连接到加载了适当的服务器端插件的服务器。

    以下部分提供特定于 LDAP 可插入身份验证的安装和使用信息：

-   [LDAP 可插入身份验证的先决条件](ldap-pluggable-authentication.html#ldap-pluggable-authentication-prerequisites)

-   [MySQL 用户的 LDAP 身份验证如何工作](ldap-pluggable-authentication.html#ldap-pluggable-authentication-process)

-   [安装 LDAP 可插入身份验证](ldap-pluggable-authentication.html#ldap-pluggable-authentication-installation)

-   [卸载 LDAP 可插入身份验证](ldap-pluggable-authentication.html#ldap-pluggable-authentication-uninstallation)

-   [LDAP 可插入身份验证和 ldap.conf](ldap-pluggable-authentication.html#ldap-pluggable-authentication-ldap-conf)

-   [使用 LDAP 可插入身份验证](ldap-pluggable-authentication.html#ldap-pluggable-authentication-usage)

-   [简单的 LDAP 身份验证](ldap-pluggable-authentication.html#ldap-pluggable-authentication-usage-simple)

-   [基于 SASL 的 LDAP 身份验证](ldap-pluggable-authentication.html#ldap-pluggable-authentication-usage-sasl)

-   [使用代理的 LDAP 身份验证](ldap-pluggable-authentication.html#ldap-pluggable-authentication-usage-proxying)

-   [LDAP 身份验证组首选项和映射规范](ldap-pluggable-authentication.html#ldap-pluggable-authentication-usage-group-mapping)

-   [LDAP 身份验证用户 DN 后缀](ldap-pluggable-authentication.html#ldap-pluggable-authentication-usage-user-dn-suffix)

-   [LDAP 身份验证方法](ldap-pluggable-authentication.html#ldap-pluggable-authentication-auth-methods)

-   [GSSAPI/Kerberos 身份验证方法](ldap-pluggable-authentication.html#ldap-pluggable-authentication-gssapi)

-   [LDAP 搜索推荐](ldap-pluggable-authentication.html#ldap-pluggable-authentication-ldap-referral)

    有关 MySQL 中可插入身份验证的一般信息，请参阅[第 6.2.17 节，“可插拔身份验证”](pluggable-authentication.html).有关信息`mysql_clear_password`插件，见[第 6.4.1.4 节，“客户端明文可插入身份验证”](cleartext-pluggable-authentication.html).有关代理用户信息，请参阅[第 6.2.19 节，“代理用户”](proxy-users.html).

笔记

如果您的系统支持 PAM 并允许 LDAP 作为 PAM 身份验证方法，则使用 LDAP 进行 MySQL 用户身份验证的另一种方法是使用服务器端`身份验证_pam`插入。看[第 6.4.1.5 节，“PAM 可插入身份验证”](pam-pluggable-authentication.html).

##### LDAP 可插入身份验证的先决条件

要对 MySQL 使用 LDAP 可插入身份验证，必须满足以下先决条件：

-   LDAP 服务器必须可供 LDAP 身份验证插件与之通信。

-   要被 MySQL 认证的 LDAP 用户必须存在于 LDAP 服务器管理的目录中。

-   LDAP 客户端库必须在服务器端的系统上可用`authentication_ldap_sasl`要么`authentication_ldap_simple`使用插件。目前，支持的库是 Windows 本机 LDAP 库，或非 Windows 系统上的 OpenLDAP 库。

-   要使用基于 SASL 的 LDAP 身份验证：

    -   LDAP 服务器必须配置为与 SASL 服务器通信。

    -   SASL 客户端库必须在客户端的系统上可用`authentication_ldap_sasl_client`使用插件。目前，唯一支持的库是 Cyrus SASL 库。

    -   要使用特定的 SASL 身份验证方法，该方法所需的任何其他服务都必须可用。例如，要使用 GSSAPI/Kerberos，GSSAPI 库和 Kerberos 服务必须可用。

##### MySQL 用户的 LDAP 身份验证如何工作

本节概述 MySQL 和 LDAP 如何协同工作以验证 MySQL 用户。有关显示如何设置 MySQL 帐户以使用特定 LDAP 身份验证插件的示例，请参阅[使用 LDAP 可插入身份验证](ldap-pluggable-authentication.html#ldap-pluggable-authentication-usage).有关 LDAP 插件可用的身份验证方法的信息，请参阅[LDAP 身份验证方法](ldap-pluggable-authentication.html#ldap-pluggable-authentication-auth-methods).

客户端连接到 MySQL 服务器，提供 MySQL 客户端用户名和密码：

-   对于简单的 LDAP 身份验证，客户端和服务器端插件以明文形式传递密码。建议在 MySQL 客户端和服务器之间建立安全连接，以防止密码泄露。

-   对于基于 SASL 的 LDAP 身份验证，客户端和服务器端插件避免在 MySQL 客户端和服务器之间发送明文密码。例如，插件可能使用 SASL 消息在 LDAP 协议中安全传输凭据。对于 GSSAPI 身份验证方法，客户端和服务器端插件使用 Kerberos 进行安全通信，而无需直接使用 LDAP 消息。

    如果客户端用户名和主机名不匹配 MySQL 帐户，则连接被拒绝。

    如果存在匹配的 MySQL 帐户，则会针对 LDAP 进行身份验证。LDAP 服务器查找与用户匹配的条目并根据 LDAP 密码验证该条目：

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

-   如果 MySQL 帐户命名 LDAP 用户专有名称 (DN)，则 LDAP 身份验证使用该值和客户端提供的 LDAP 密码。（要将 LDAP 用户 DN 与 MySQL 帐户相关联，请包括`经过`子句在[`创建用户`](create-user.html)创建帐户的语句。）

-   如果 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 身份验证插件。有关安装插件的一般信息，请参阅[第 5.6.1 节，“安装和卸载插件”](plugin-loading.html).

要被服务器使用，插件库文件必须位于 MySQL 插件目录（由[`插件目录`](server-system-variables.html#sysvar_plugin_dir)系统变量）。如有必要，通过设置值来配置插件目录位置[`插件目录`](server-system-variables.html#sysvar_plugin_dir)在服务器启动时。

服务器端插件库文件的基本名称是`authentication_ldap_simple`和`authentication_ldap_sasl`.文件名后缀因平台而异（例如，`。所以`对于 Unix 和类 Unix 系统，`.dll`对于 Windows）。

要在服务器启动时加载插件，请使用[`--plugin-load-add`](server-options.html#option_mysqld_plugin-load-add)选项来命名包含它们的库文件。使用这种插件加载方法，每次服务器启动时都必须提供选项。此外，为您希望配置的任何插件提供的系统变量指定值。

每个服务器端 LDAP 插件都公开了一组系统变量，可以配置其操作。设置其中大部分是可选的，但您必须设置指定 LDAP 服务器主机的变量（以便插件知道连接的位置）和 LDAP 绑定操作的基本专有名称（以限制搜索范围并获得更快的搜索）。有关所有 LDAP 系统变量的详细信息，请参阅[第 6.4.1.13 节，“可插入的身份验证系统变量”](pluggable-authentication-system-variables.html).

要加载插件并为 LDAP 绑定操作设置 LDAP 服务器主机和基本专有名称，请在您的`我的.cnf`文件，调整`。所以`根据需要为您的平台添加后缀：

```
[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"
```

修改后`我的.cnf`, 重启服务器使新设置生效。

或者，要在运行时加载插件，请使用这些语句，调整`。所以`根据需要为您的平台添加后缀：

```
INSTALL PLUGIN authentication_ldap_simple
  SONAME 'authentication_ldap_simple.so';
INSTALL PLUGIN authentication_ldap_sasl
  SONAME 'authentication_ldap_sasl.so';
```

[`安装插件`](install-plugin.html)立即加载插件，并将其注册到`mysql.plugins`系统表，以使服务器在每次后续正常启动时加载它，而无需[`--plugin-load-add`](server-options.html#option_mysqld_plugin-load-add).

在运行时安装插件后，它们公开的系统变量变得可用，您可以将它们的设置添加到您的`我的.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"
```

修改后`我的.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-variable.html)为正在运行的 MySQL 实例设置一个值。它还保存该值，使其延续到后续服务器重新启动。要更改正在运行的 MySQL 实例的值而不使其延续到后续重新启动，请使用`全球的`关键字而不是`坚持`.看[第 13.7.6.1 节，“变量赋值的 SET 语法”](set-variable.html).

要验证插件安装，请检查[`INFORMATION_SCHEMA.PLUGINS`](information-schema-plugins-table.html)表或使用[`显示插件`](show-plugins.html)声明（见[第 5.6.2 节，“获取服务器插件信息”](obtaining-plugin-information.html)）。例如：

```
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 可插入身份验证](ldap-pluggable-authentication.html#ldap-pluggable-authentication-usage).

SELinux 的附加说明

[](<>)

在启用了 SELinux 的运行 EL6 或 EL 的系统上，需要更改 SELinux 策略以启用 MySQL LDAP 插件与 LDAP 服务通信：

1.  创建文件`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;
    ```

2.  将安全策略模块编译成二进制表示：

    ```
    checkmodule -M -m mysqlldap.te -o mysqlldap.mod
    ```

3.  创建 SELinux 策略模块包：

    ```
    semodule_package -m mysqlldap.mod  -o mysqlldap.pp
    ```

4.  安装模块包：

    ```
    semodule -i mysqlldap.pp
    ```

5.  完成 SELinux 策略更改后，重新启动 MySQL 服务器：

    ```
    service mysqld restart
    ```

##### 卸载 LDAP 可插入身份验证

用于卸载 LDAP 身份验证插件的方法取决于您安装它们的方式：

-   如果您在服务器启动时使用[`--plugin-load-add`](server-options.html#option_mysqld_plugin-load-add)选项，在没有这些选项的情况下重新启动服务器。

-   如果您在运行时使用[`安装插件`](install-plugin.html)，它们在服务器重新启动时仍然安装。要卸载它们，请使用[`卸载插件`](uninstall-plugin.html)：

    ```
    UNINSTALL PLUGIN authentication_ldap_simple;
    UNINSTALL PLUGIN authentication_ldap_sasl;
    ```

    此外，从您的`我的.cnf`归档任何设置 LDAP 插件相关系统变量的启动选项。如果你用过[`设置坚持`](set-variable.html)要持久化 LDAP 系统变量，请使用[`重置坚持`](reset-persist.html)删除设置。

##### LDAP 可插入身份验证和 ldap.conf

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

对于使用 OpenLDAP 的安装，`ldap.conf`文件为 LDAP 客户端提供全局默认值。可以在此文件中设置选项以影响 LDAP 客户端，包括 LDAP 身份验证插件。OpenLDAP 按以下优先顺序使用配置选项：

-   由 LDAP 客户端指定的配置。

-   中指定的配置`ldap.conf`文件。要禁用此文件，请设置`LDAPNOINIT`环境变量。

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

-   OpenLDAP 库内置默认值。

    如果库默认或`ldap.conf`值不会产生适当的选项值，LDAP 身份验证插件可能能够设置相关变量以直接影响 LDAP 配置。例如，LDAP 插件可以覆盖`ldap.conf`对于这些参数：

-   TLS 配置：系统变量可用于启用 TLS 和控制 CA 配置，例如[`authentication_ldap_simple_tls`](pluggable-authentication-system-variables.html#sysvar_authentication_ldap_simple_tls)和[`authentication_ldap_simple_ca_path`](pluggable-authentication-system-variables.html#sysvar_authentication_ldap_simple_ca_path)用于简单的 LDAP 身份验证，以及[`authentication_ldap_sasl_tls`](pluggable-authentication-system-variables.html#sysvar_authentication_ldap_sasl_tls)和[`authentication_ldap_sasl_ca_path`](pluggable-authentication-system-variables.html#sysvar_authentication_ldap_sasl_ca_path)用于 SASL LDAP 身份验证。

-   LDAP 引用。看[LDAP 搜索推荐](ldap-pluggable-authentication.html#ldap-pluggable-authentication-ldap-referral).

    有关更多信息`ldap.conf`咨询`ldap.conf(5)`手册页。

##### 使用 LDAP 可插入身份验证

本节介绍如何使 MySQL 帐户使用 LDAP 可插入身份验证连接到 MySQL 服务器。假设服务器在启用了适当的服务器端插件的情况下运行，如中所述[安装 LDAP 可插入身份验证](ldap-pluggable-authentication.html#ldap-pluggable-authentication-installation)，并且客户端主机上提供了适当的客户端插件。

本节不介绍 LDAP 配置或管理。假定您熟悉这些主题。

这两个服务器端 LDAP 插件每个都与特定的客户端插件一起使用：

-   服务器端`authentication_ldap_simple`插件执行简单的 LDAP 身份验证。对于使用此插件的帐户的连接，客户端程序使用客户端`mysql_clear_password`插件，它将密码以明文形式发送到服务器。不使用密码散列或加密，因此建议在 MySQL 客户端和服务器之间建立安全连接，以防止密码泄露。

-   服务器端`authentication_ldap_sasl`插件执行基于 SASL 的 LDAP 身份验证。对于使用此插件的帐户的连接，客户端程序使用客户端`authentication_ldap_sasl_client`插入。客户端和服务器端 SASL LDAP 插件使用 SASL 消息在 LDAP 协议中安全传输凭据，以避免在 MySQL 客户端和服务器之间发送明文密码。

    MySQL用户LDAP认证的总体要求：

-   每个用户都必须有一个 LDAP 目录条目才能进行身份验证。

-   必须有一个 MySQL 用户帐户来指定服务器端 LDAP 身份验证插件，并可选择命名关联的 LDAP 用户专有名称 (DN)。（要将 LDAP 用户 DN 与 MySQL 帐户相关联，请包括`经过`条款中的[`创建用户`](create-user.html)创建帐户的语句。）如果帐户名称没有 LDAP 字符串，则 LDAP 身份验证使用客户端指定的用户名来查找 LDAP 条目。

-   客户端程序使用适用于 MySQL 帐户使用的服务器端身份验证插件的连接方法进行连接。对于 LDAP 身份验证，连接需要 MySQL 用户名和 LDAP 密码。此外，对于使用服务器端的帐户`authentication_ldap_simple`插件，调用客户端程序`--启用明文插件`启用客户端的选项`mysql_clear_password`插入。

    此处的说明假设以下情况：

-   MySQL 用户`贝茜`和`鲍里斯`对 LDAP 条目进行身份验证`betsy_ldap`和`鲍里斯·尤`分别地（MySQL和LDAP用户名没有必要不同。在本讨论中使用不同的名称有助于澄清操作上下文是MySQL还是LDAP。）

-   LDAP条目使用`液体`属性指定用户名。这可能因LDAP服务器而异。一些LDAP服务器使用`cn`属性，而不是用户名`液体`。要更改属性，请修改[`身份验证\u ldap\u简单\u用户\u搜索\u属性`](pluggable-authentication-system-variables.html#sysvar_authentication_ldap_simple_user_search_attr)或[`身份验证\u ldap\u sasl\u用户\u搜索\u属性`](pluggable-authentication-system-variables.html#sysvar_authentication_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.html)创建MySQL帐户的语句在`通过`子句，指示MySQL帐户根据哪个LDAP条目进行身份验证。

    设置使用LDAP身份验证的帐户的说明取决于使用哪个服务器端LDAP插件。以下部分描述了几种使用场景。

##### 简单LDAP身份验证

要为简单的LDAP身份验证配置MySQL帐户[`创建用户`](create-user.html)语句指定`身份验证\u ldap\u简单`插件，并可选地命名LDAP用户可分辨名称（DN）：

```
CREATE USER user
  IDENTIFIED WITH authentication_ldap_simple
  [BY 'LDAP user DN'];
```

假设MySQL用户`贝齐`LDAP目录中有以下条目：

```
uid=betsy_ldap,ou=People,dc=example,dc=com
```

然后是创建MySQL帐户的语句`贝茜`看起来像这样：

```
CREATE USER 'betsy'@'localhost'
  IDENTIFIED WITH authentication_ldap_simple
  AS 'uid=betsy_ldap,ou=People,dc=example,dc=com';
```

中指定的身份验证字符串`经过`子句不包括 LDAP 密码。这必须由客户端用户在连接时提供。

客户端通过提供 MySQL 用户名和 LDAP 密码以及启用客户端连接到 MySQL 服务器`mysql_clear_password`插入：

```
$> 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 客户端必须显式启用它（例如，使用`--启用明文插件`选项）。看[第 6.4.1.4 节，“客户端明文可插入身份验证”](cleartext-pluggable-authentication.html).

-   为避免密码泄露`mysql_clear_password`启用插件后，MySQL 客户端应使用加密连接连接到 MySQL 服务器。看[第 6.3.1 节，“配置 MySQL 以使用加密连接”](using-encrypted-connections.html).

    认证过程如下：

1.  客户端插件发送`贝茜`和*`betsy_password`*作为 MySQL 服务器的客户端用户名和 LDAP 密码。

2.  连接尝试与`'贝西'@'本地主机'`帐户。服务端 LDAP 插件发现这个账户有一个认证字符串`'uid=betsy_ldap,ou=人,dc=example,dc=com'`命名 LDAP 用户 DN。插件将此字符串和 LDAP 密码发送到 LDAP 服务器。

3.  LDAP 服务器找到 LDAP 条目`betsy_ldap`并且密码匹配，因此 LDAP 身份验证成功。

4.  LDAP 条目没有组属性，因此服务器端插件返回客户端用户名 (`贝茜`) 作为经过身份验证的用户。这是客户端提供的相同用户名，因此不会发生代理，客户端会话使用`'贝西'@'本地主机'`用于权限检查的帐户。

    如果匹配的 LDAP 条目包含组属性，则该属性值将是经过身份验证的用户名，并且如果该值不同于`贝茜`, 代理会发生。有关使用 group 属性的示例，请参阅[使用代理的 LDAP 身份验证](ldap-pluggable-authentication.html#ldap-pluggable-authentication-usage-proxying).

    有[`创建用户`](create-user.html)声明不包含`经过`条款来指定`betsy_ldap`LDAP 专有名称，身份验证尝试将使用客户端提供的用户名（在这种情况下，`贝茜`）。在没有 LDAP 条目的情况下`贝茜`，身份验证将失败。

##### 基于 SASL 的 LDAP 身份验证

要为 SASL LDAP 身份验证配置 MySQL 帐户，[`创建用户`](create-user.html)声明指定`authentication_ldap_sasl`插件，并可选择命名 LDAP 用户专有名称 (DN)：

```
CREATE USER user
  IDENTIFIED WITH authentication_ldap_sasl
  [BY 'LDAP user DN'];
```

假设 MySQL 用户`鲍里斯`在 LDAP 目录中有这个条目：

```
uid=boris_ldap,ou=People,dc=example,dc=com
```

然后是创建 MySQL 帐户的语句`鲍里斯`看起来像这样：

```
CREATE USER 'boris'@'localhost'
  IDENTIFIED WITH authentication_ldap_sasl
  AS 'uid=boris_ldap,ou=People,dc=example,dc=com';
```

中指定的身份验证字符串`经过`子句不包括 LDAP 密码。这必须由客户端用户在连接时提供。

客户端通过提供 MySQL 用户名和 LDAP 密码连接到 MySQL 服务器：

```
$> mysql --user=boris --password
Enter password: boris_password (boris_ldap LDAP password)
```

对于服务器端`authentication_ldap_sasl`插件，客户端使用客户端`authentication_ldap_sasl_client`插入。如果客户端程序找不到客户端插件，请指定一个`--插件目录`命名插件库文件安装目录的选项。

认证过程为`鲍里斯`类似于前面描述的`贝茜`使用简单的 LDAP 身份验证，除了客户端和服务器端 SASL LDAP 插件使用 SASL 消息在 LDAP 协议内安全传输凭据，以避免在 MySQL 客户端和服务器之间发送明文密码。

##### 使用代理的 LDAP 身份验证

[](<>)

LDAP 身份验证插件支持代理，使用户能够以一个用户身份连接到 MySQL 服务器，但承担不同用户的权限。本节介绍基本的 LDAP 插件代理支持。LDAP 插件还支持组偏好和代理用户映射的规范；看[LDAP 身份验证组首选项和映射规范](ldap-pluggable-authentication.html#ldap-pluggable-authentication-usage-group-mapping).

此处描述的代理实现基于使用 LDAP 组属性值将使用 LDAP 进行身份验证的连接 MySQL 用户映射到定义不同权限集的其他 MySQL 帐户。用户不直接通过定义权限的帐户进行连接。相反，它们通过使用 LDAP 验证的默认代理帐户进行连接，以便所有外部登录都映射到拥有权限的代理 MySQL 帐户。使用代理帐户连接的任何用户都将映射到这些代理 MySQL 帐户之一，其权限决定了允许外部用户执行的数据库操作。

此处的说明假设以下情况：

-   LDAP 条目使用`uid`和`cn`属性分别指定用户名和组值。要使用不同的用户和组属性名称，请设置适当的插件特定系统变量：

    -   为了`authentication_ldap_simple`插件：设置[`authentication_ldap_simple_user_search_attr`](pluggable-authentication-system-variables.html#sysvar_authentication_ldap_simple_user_search_attr)和[`authentication_ldap_simple_group_search_attr`](pluggable-authentication-system-variables.html#sysvar_authentication_ldap_simple_group_search_attr).

    -   为了`authentication_ldap_sasl`插件：设置[`authentication_ldap_sasl_user_search_attr`](pluggable-authentication-system-variables.html#sysvar_authentication_ldap_sasl_user_search_attr)和[`authentication_ldap_sasl_group_search_attr`](pluggable-authentication-system-variables.html#sysvar_authentication_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
    ```

    在连接时，组属性值成为经过身份验证的用户名，因此他们命名`会计`和`前台`代理账户。

-   这些示例假定使用 SASL LDAP 身份验证。对简单的 LDAP 身份验证进行适当的调整。

    创建默认代理 MySQL 帐户：


```
CREATE USER ''@'%'
  IDENTIFIED WITH authentication_ldap_sasl;
```

代理帐户定义没有`作为 '*`auth_string`*'`子句来命名 LDAP 用户 DN。因此：

-   当客户端连接时，客户端用户名将成为要搜索的 LDAP 用户名。

-   匹配的 LDAP 条目应包含一个组属性，该属性命名代理 MySQL 帐户，该帐户定义客户端应具有的权限。

笔记

如果您的 MySQL 安装有匿名用户，他们可能与默认代理用户冲突。有关此问题以及处理方法的更多信息，请参阅[默认代理用户和匿名用户冲突](proxy-users.html#proxy-users-conflicts).

创建代理帐户并授予每个帐户应具有的权限：

```
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`插件已安装。有关说明，请参阅[第 6.4.1.9 节，“非登录可插入身份验证”](no-login-pluggable-authentication.html).) 有关保护代理帐户不被直接使用的替代方法，请参阅[防止直接登录代理帐户](proxy-users.html#preventing-proxied-account-direct-login).

授予代理帐户[`代理`](privileges-provided.html#priv_proxy)每个代理帐户的特权：

```
GRANT PROXY
  ON 'accounting'@'localhost'
  TO ''@'%';
GRANT PROXY
  ON 'front_office'@'localhost'
  TO ''@'%';
```

使用[**mysql**](mysql.html)用于连接 MySQL 服务器的命令行客户端`芭莎`.

```
$> mysql --user=basha --password
Enter password: basha_password (basha LDAP password)
```

身份验证发生如下：

1.  服务器使用默认值对连接进行身份验证`''@'%'`代理帐户，用于客户端用户`芭莎`.

2.  匹配的 LDAP 条目是：

    ```
    uid=basha,ou=People,dc=example,dc=com,cn=accounting
    ```

3.  匹配的 LDAP 条目具有组属性`cn=会计`， 所以`会计`成为经过身份验证的代理用户。

4.  认证用户与客户端用户名不同`芭莎`, 结果是`芭莎`被视为代理`会计`， 和`芭莎`承担被代理人的特权`会计`帐户。以下查询返回输出，如下所示：

    ```
    mysql> SELECT USER(), CURRENT_USER(), @@proxy_user;
    +-----------------+----------------------+--------------+
    | USER()          | CURRENT_USER()       | @@proxy_user |
    +-----------------+----------------------+--------------+
    | basha@localhost | accounting@localhost | ''@'%'       |
    +-----------------+----------------------+--------------+
    ```

    这表明`芭莎`使用授予代理的权限`会计`MySQL 帐户，并且该代理通过默认代理用户帐户进行。

    现在连接为`罗勒`反而：


```
$> mysql --user=basil --password
Enter password: basil_password (basil LDAP password)
```

认证过程为`罗勒`类似于前面描述的`芭莎`：

1.  服务器使用默认值对连接进行身份验证`''@'%'`代理帐户，用于客户端用户`罗勒`.

2.  匹配的 LDAP 条目是：

    ```
    uid=basil,ou=People,dc=example,dc=com,cn=front_office
    ```

3.  匹配的 LDAP 条目具有组属性`cn=front_office`， 所以`前台`成为经过身份验证的代理用户。

4.  认证用户与客户端用户名不同`罗勒`, 结果是`罗勒`被视为代理`前台`， 和`罗勒`承担被代理人的特权`前台`帐户。以下查询返回输出，如下所示：

    ```
    mysql> SELECT USER(), CURRENT_USER(), @@proxy_user;
    +-----------------+------------------------+--------------+
    | USER()          | CURRENT_USER()         | @@proxy_user |
    +-----------------+------------------------+--------------+
    | basil@localhost | front_office@localhost | ''@'%'       |
    +-----------------+------------------------+--------------+
    ```

    这表明`罗勒`使用授予代理的权限`前台`MySQL 帐户，并且该代理通过默认代理用户帐户进行。

##### LDAP 身份验证组首选项和映射规范

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

如中所述[使用代理的 LDAP 身份验证](ldap-pluggable-authentication.html#ldap-pluggable-authentication-usage-proxying)，基本 LDAP 身份验证代理的工作原理是插件使用 LDAP 服务器返回的第一个组名作为 MySQL 代理用户帐户名。如果 LDAP 服务器返回多个组名，或者指定组名以外的任何名称作为代理用户名，此简单功能无法指定关于使用哪个组名的任何首选项。

从 MySQL 8.0.14 开始，对于使用 LDAP 身份验证的 MySQL 帐户，身份验证字符串可以指定以下信息以实现更大的代理灵活性：

-   按优先顺序排列的组列表，以便插件使用列表中与 LDAP 服务器返回的组匹配的第一个组名。

-   从组名到代理用户名的映射，这样组名在匹配时可以提供指定的名称以用作代理用户。这提供了使用组名作为代理用户的替代方法。

    考虑以下 MySQL 代理帐户定义：


```
CREATE USER ''@'%'
  IDENTIFIED WITH authentication_ldap_sasl
  AS '+ou=People,dc=example,dc=com#grp1=usera,grp2,grp3=userc';
```

身份验证字符串具有用户 DN 后缀`ou=人,dc=example,dc=com`前缀为`+`特点。因此，如中所述[LDAP 身份验证用户 DN 后缀](ldap-pluggable-authentication.html#ldap-pluggable-authentication-usage-user-dn-suffix)，完整的用户 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`, 这些在身份验证字符串中与用户名相关联`用户`和`用户c`， 分别。该插件使用相应的关联用户名作为代理用户名。

-   如果匹配的组名是`grp2`，身份验证字符串中没有关联的用户名。该插件使用`grp2`作为代理用户名。

    如果 LDAP 服务器返回 DN 格式的组，LDAP 插件会解析组 DN 以从中提取组名。

    要指定 LDAP 组首选项和映射信息，以下原则适用：

-   以组首选项和身份验证字符串的映射部分开头`#`前缀字符。

-   组首选项和映射规范是一个或多个项目的列表，以逗号分隔。每个项目都有表格`*`组的名字`*=*`用户名`*`要么*`组的名字`*.项目应按组名优先顺序列出。对于插件从 LDAP 服务器返回的组名集合中选择的组名作为匹配项，两种语法的效果不同，如下所示：

    -   对于指定为的项目`*`组的名字`*=*`用户名`*`（带有用户名），组名映射到用户名，用作 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"
    ```

-   要转义字符，请在其前面加上反斜杠 (`\`）。这对于包含文字双引号或反斜杠特别有用，否则它们不会包含在字面上。

-   用户 DN 不需要出现在身份验证字符串中，但如果出现，它必须位于组首选项和映射部分之前。用户 DN 可以作为完整的用户 DN 给出，也可以作为用户 DN 后缀给出`+`前缀字符。（看[LDAP 身份验证用户 DN 后缀](ldap-pluggable-authentication.html#ldap-pluggable-authentication-usage-user-dn-suffix).)

##### LDAP 身份验证用户 DN 后缀

LDAP 身份验证插件允许提供用户 DN 信息的身份验证字符串以`+`前缀字符：

-   在没有一个`+`字符，认证字符串值被视为原样，无需修改。

-   如果身份验证字符串以`+`，插件从客户端发送的用户名中构造完整的用户 DN 值，以及身份验证字符串中指定的 DN（带有`+`删除）。在构造的 DN 中，客户端用户名成为指定 LDAP 用户名的属性的值。这是`uid`默认;要更改属性，请修改相应的系统变量 ([`authentication_ldap_simple_user_search_attr`](pluggable-authentication-system-variables.html#sysvar_authentication_ldap_simple_user_search_attr)要么[`authentication_ldap_sasl_user_search_attr`](pluggable-authentication-system-variables.html#sysvar_authentication_ldap_sasl_user_search_attr)）。身份验证字符串存储为`mysql.user`系统表，在身份验证之前动态构建完整的用户 DN。

    此帐户身份验证字符串没有`+`开头，因此将其作为完整的用户 DN：


```
CREATE USER 'baldwin'
  IDENTIFIED WITH authentication_ldap_simple
  AS 'uid=admin,ou=People,dc=example,dc=com';
```

客户端使用帐户中指定的用户名连接（`鲍德温`）。在这种情况下，不使用该名称，因为身份验证字符串没有前缀，因此完全指定了用户 DN。

此帐户身份验证字符串确实有`+`开头，所以它只是作为用户 DN 的一部分：

```
CREATE USER 'accounting'
  IDENTIFIED WITH authentication_ldap_simple
  AS '+ou=People,dc=example,dc=com';
```

客户端使用帐户中指定的用户名连接（`会计`)，在这种情况下用作`uid`属性与身份验证字符串一起构造用户 DN：`uid=会计,ou=人,dc=example,dc=com`

前面示例中的帐户具有非空用户名，因此客户端始终使用与帐户定义中指定的名称相同的名称连接到 MySQL 服务器。如果帐户的用户名为空，例如默认匿名`''@'%'`中描述的代理帐户[使用代理的 LDAP 身份验证](ldap-pluggable-authentication.html#ldap-pluggable-authentication-usage-proxying)，客户端可能会使用不同的用户名连接到 MySQL 服务器。但原理是一样的：如果认证字符串以`+`，插件使用客户端发送的用户名和认证字符串一起构造用户DN。

##### LDAP 身份验证方法

LDAP 身份验证插件使用可配置的身份验证方法。适当的系统变量和可用的方法选择是插件特定的：

-   为了`authentication_ldap_simple`插件：设置[`authentication_ldap_simple_auth_method_name`](pluggable-authentication-system-variables.html#sysvar_authentication_ldap_simple_auth_method_name)系统变量来配置方法。允许的选择是`简单的`和`广告森林`.

-   为了`authentication_ldap_sasl`插件：设置[`authentication_ldap_sasl_auth_method_name`](pluggable-authentication-system-variables.html#sysvar_authentication_ldap_sasl_auth_method_name)系统变量来配置方法。允许的选择是`SCRAM-SHA-1`,`SCRAM-SHA-256`， 和`GSSAPI`.（要确定主机系统上实际可用的 SASL LDAP 方法，请检查[`Authentication_ldap_sasl_supported_methods`](server-status-variables.html#statvar_Authentication_ldap_sasl_supported_methods)状态变量。）

    有关每个允许的方法的信息，请参阅系统变量描述。此外，根据方法的不同，可能需要额外的配置，如以下部分所述。

##### GSSAPI/Kerberos 身份验证方法

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

通用安全服务应用程序接口 (GSSAPI) 是一个安全抽象接口。Kerberos 是可以通过该抽象接口使用的特定安全协议的一个实例。使用 GSSAPI，应用程序向 Kerberos 进行身份验证以获取服务凭证，然后依次使用这些凭证来启用对其他服务的安全访问。

其中一项服务是 LDAP，由客户端和服务器端 SASL LDAP 身份验证插件使用。当。。。的时候[`authentication_ldap_sasl_auth_method_name`](pluggable-authentication-system-variables.html#sysvar_authentication_ldap_sasl_auth_method_name)系统变量设置为`GSSAPI`，这些插件使用 GSSAPI/Kerberos 身份验证方法。在这种情况下，插件使用 Kerberos 进行安全通信，而无需直接使用 LDAP 消息。然后，服务器端插件与 LDAP 服务器通信以解释 LDAP 身份验证消息并检索 LDAP 组。

支持 GSSAPI/Kerberos 作为 Linux 上 MySQL 服务器和客户端的 LDAP 身份验证方法。它在应用程序可以通过 Microsoft Active Directory 访问 LDAP 的 Linux 环境中非常有用，Microsoft Active Directory 默认启用了 Kerberos。

以下讨论提供了有关使用 GSSAPI 方法的配置要求的信息。假定熟悉 Kerberos 概念和操作。以下列表简要定义了几个常见的 Kerberos 术语。您还可以找到词汇表部分[RFC 4120](https://tools.ietf.org/html/rfc4120)有帮助。

-   [主要的](glossary.html#glos_principal)：命名实体，例如用户或服务器。

-   [KDC](glossary.html#glos_key_distribution_center)：密钥分发中心，包括 AS 和 TGS：

    -   [作为](glossary.html#glos_authentication_server)：认证服务器；提供获得额外票证所需的初始票证授予票证。

    -   [TGS](glossary.html#glos_ticket_granting_server)：票证授予服务器；向拥有有效 TGT 的 Kerberos 客户端提供额外的票证。

-   [TGT](glossary.html#glos_ticket_granting_ticket)：授予票证的票证；提交给 TGS 以获得服务访问的服务票证。

    使用 Kerberos 的 LDAP 身份验证需要 KDC 服务器和 LDAP 服务器。可以通过不同的方式满足此要求：

-   Active Directory 包括这两个服务器，默认情况下在 Active Directory LDAP 服务器中启用 Kerberos 身份验证。

-   OpenLDAP 提供了一个 LDAP 服务器，但可能需要一个单独的 KDC 服务器，并且需要额外的 Kerberos 设置。

    Kerberos 还必须在客户端主机上可用。客户端使用密码联系 AS 以获取 TGT。然后，客户端使用 TGT 从 TGS 获取对其他服务（例如 LDAP）的访问。

    以下部分讨论在 MySQL 中使用 GSSAPI/Kerberos 进行 SASL LDAP 身份验证的配置步骤：

-   [验证 Kerberos 和 LDAP 可用性](ldap-pluggable-authentication.html#ldap-gssapi-kerberos-setup)

-   [为 GSSAPI/Kerberos 配置服务器端 SASL LDAP 身份验证插件](ldap-pluggable-authentication.html#ldap-gssapi-ldap-setup)

-   [创建使用 GSSAPI/Kerberos 进行 LDAP 身份验证的 MySQL 帐户](ldap-pluggable-authentication.html#ldap-gssapi-mysql-account-setup)

-   [使用 MySQL 帐户连接到 MySQL 服务器](ldap-pluggable-authentication.html#ldap-gssapi-mysql-client-usage)

-   [LDAP 身份验证的客户端配置参数](ldap-pluggable-authentication.html#ldap-gssapi-mysql-client-config-parameters)

###### 验证 Kerberos 和 LDAP 可用性

以下示例显示了如何在 Active Directory 中测试 Kerberos 的可用性。该示例做出以下假设：

-   Active Directory 正在名为的主机上运行`ldap_auth.example.com`带 IP 地址`198.51.100.10`.

-   MySQL 相关的 Kerberos 身份验证和 LDAP 查找使用`MYSQL.LOCAL`领域。

-   一位名叫`布雷登@MYSQL.LOCAL`已在 KDC 注册。（在后面的讨论中，这个主体名称还与使用 GSSAPI/Kerberos 向 MySQL 服务器进行身份验证的 MySQL 帐户相关联。）

    满足这些假设后，请遵循以下程序：

1.  验证 Kerberos 库是否已在操作系统中正确安装和配置。例如，要配置一个`MYSQL.LOCAL`在 MySQL 身份验证期间使用的域，`/etc/krb5.conf`Kerberos 配置文件应该包含如下内容：

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

    ```
    [realms]
      MYSQL.LOCAL = {
        kdc = ldap_auth.example.com
        admin_server = ldap_auth.example.com
        default_domain = MYSQL.LOCAL
      }
    ```

2.  您可能需要添加一个条目`/etc/hosts`对于服务器主机：

    ```
    198.51.100.10 ldap_auth ldap_auth.example.com
    ```

3.  检查 Kerberos 身份验证是否正常工作：

    1.  采用**基尼特**向 Kerberos 进行身份验证：

        ```
        $> kinit bredon@MYSQL.LOCAL
        Password for bredon@MYSQL.LOCAL: (enter password here)
        ```

        该命令对名为的 Kerberos 主体进行身份验证`布雷登@MYSQL.LOCAL`.在命令提示时输入主体的密码。KDC 返回一个缓存在客户端的 TGT，供其他支持 Kerberos 的应用程序使用。

    2.  采用**列表**检查是否正确获取了 TGT。输出应该与此类似：

        ```
        $> klist
        Ticket cache: FILE:/tmp/krb5cc_244306
        Default principal: bredon@MYSQL.LOCAL

        Valid starting       Expires              Service principal
        03/23/2021 08:18:33  03/23/2021 18:18:33  krbtgt/MYSQL.LOCAL@MYSQL.LOCAL
        ```

4.  检查是否**ldapsearch**使用此命令与 Kerberos TGT 一起工作，该命令在`MYSQL.LOCAL`领域：

    ```
    ldapsearch -h 198.51.100.10 -Y GSSAPI -b "dc=MYSQL,dc=LOCAL"
    ```

###### 为 GSSAPI/Kerberos 配置服务器端 SASL LDAP 身份验证插件

假设 LDAP 服务器可以通过刚才描述的 Kerberos 访问，请将服务器端 SASL LDAP 身份验证插件配置为使用 GSSAPI/Kerberos 身份验证方法。（有关一般 LDAP 插件安装信息，请参阅[安装 LDAP 可插入身份验证](ldap-pluggable-authentication.html#ldap-pluggable-authentication-installation).) 这是服务器插件相关设置的示例`我的.cnf`文件可能包含：

```
[mysqld]
plugin-load-add=authentication_ldap_sasl.so
authentication_ldap_sasl_auth_method_name="GSSAPI"
authentication_ldap_sasl_server_host=198.51.100.10
authentication_ldap_sasl_server_port=389
authentication_ldap_sasl_bind_root_dn="cn=admin,cn=users,dc=MYSQL,dc=LOCAL"
authentication_ldap_sasl_bind_root_pwd="password"
authentication_ldap_sasl_bind_base_dn="cn=users,dc=MYSQL,dc=LOCAL"
authentication_ldap_sasl_user_search_attr="sAMAccountName"
```

这些选项文件设置配置 SASL LDAP 插件，如下所示：

-   这[`--plugin-load-add`](server-options.html#option_mysqld_plugin-load-add)选项加​​载插件（调整`。所以`必要时为您的平台添加后缀）。如果您之前使用[`安装插件`](install-plugin.html)声明，这个选项是不必要的。

-   [`authentication_ldap_sasl_auth_method_name`](pluggable-authentication-system-variables.html#sysvar_authentication_ldap_sasl_auth_method_name)必须设置为`GSSAPI`使用 GSSAPI/Kerberos 作为 SASL LDAP 身份验证方法。

-   [`authentication_ldap_sasl_server_host`](pluggable-authentication-system-variables.html#sysvar_authentication_ldap_sasl_server_host)和[`authentication_ldap_sasl_server_port`](pluggable-authentication-system-variables.html#sysvar_authentication_ldap_sasl_server_port)指示用于身份验证的 Active Directory 服务器主机的 IP 地址和端口号。

-   [`authentication_ldap_sasl_bind_root_dn`](pluggable-authentication-system-variables.html#sysvar_authentication_ldap_sasl_bind_root_dn)和[`authentication_ldap_sasl_bind_root_pwd`](pluggable-authentication-system-variables.html#sysvar_authentication_ldap_sasl_bind_root_pwd)配置组搜索功能的根 DN 和密码。此功能是必需的，但用户可能没有搜索权限。在这种情况下，有必要提供根 DN 信息：

    -   在 DN 选项值中，`行政`应该是具有执行用户搜索权限的管理 LDAP 帐户的名称。

    -   在密码选项值中，*`密码`*应该是`行政`户口密码。

-   [`authentication_ldap_sasl_bind_base_dn`](pluggable-authentication-system-variables.html#sysvar_authentication_ldap_sasl_bind_base_dn)表示用户 DN 基本路径，以便搜索在`MYSQL.LOCAL`领域。

-   [`authentication_ldap_sasl_user_search_attr`](pluggable-authentication-system-variables.html#sysvar_authentication_ldap_sasl_user_search_attr)指定标准 Active Directory 搜索属性，`sAMAccountName`.此属性用于搜索以匹配登录名；属性值与用户 DN 值不同。

###### 创建使用 GSSAPI/Kerberos 进行 LDAP 身份验证的 MySQL 帐户

使用带有 GSSAPI/Kerberos 方法的 SASL LDAP 身份验证插件的 MySQL 身份验证基于作为 Kerberos 主体的用户。下面的讨论使用了一个名为`布雷登@MYSQL.LOCAL`作为这个用户，必须在几个地方注册：

-   Kerberos 管理员应将用户名注册为 Kerberos 主体。此名称应包含域名。客户端使用主体名称和密码向 Kerberos 进行身份验证并获取 TGT。

-   LDAP 管理员应在 LDAP 条目中注册用户名。例如：

    ```
    uid=bredon,dc=MYSQL,dc=LOCAL
    ```

    笔记

    在 Active Directory（使用 Kerberos 作为默认身份验证方法）中，创建用户会同时创建 Kerberos 主体和 LDAP 条目。

-   MySQL DBA 应该创建一个以 Kerberos 主体名称作为用户名并使用 SASL LDAP 插件进行身份验证的帐户。

    假设 Kerberos 主体和 LDAP 条目已由相应的服务管理员注册，并且如前面在[安装 LDAP 可插入身份验证](ldap-pluggable-authentication.html#ldap-pluggable-authentication-installation)， 和[为 GSSAPI/Kerberos 配置服务器端 SASL LDAP 身份验证插件](ldap-pluggable-authentication.html#ldap-gssapi-ldap-setup)，MySQL 服务器已使用服务器端 SASL LDAP 插件的适当配置设置启动。MySQL DBA 然后创建一个与 Kerberos 主体名称相对应的 MySQL 帐户，包括域名。

笔记

SASL LDAP 插件使用常量用户 DN 进行 Kerberos 身份验证，并忽略从 MySQL 配置的任何用户 DN。这有一定的含义：

-   对于任何使用 GSSAPI/Kerberos 身份验证的 MySQL 帐户，身份验证字符串[`创建用户`](create-user.html)要么[`更改用户`](alter-user.html)语句不应包含用户 DN，因为它没有任何作用。

-   因为身份验证字符串不包含用户 DN，所以它应该包含组映射信息，以使用户能够作为映射到所需代理用户的代理用户进行处理。有关使用 LDAP 身份验证插件进行代理的信息，请参阅[使用代理的 LDAP 身份验证](ldap-pluggable-authentication.html#ldap-pluggable-authentication-usage-proxying).

    以下语句创建一个名为的代理用户`布雷登@MYSQL.LOCAL`假定名为的代理用户的权限`proxied_krb_usr`.应该具有相同权限的其他 GSSAPI/Kerberos 用户可以类似地创建为同一代理用户的代理用户。


```
-- create proxy account
CREATE USER 'bredon@MYSQL.LOCAL'
  IDENTIFIED WITH authentication_ldap_sasl
  BY '#krb_grp=proxied_krb_user';

-- create proxied account and grant its privileges;
-- use mysql_no_login plugin to prevent direct login
CREATE USER 'proxied_krb_user'
  IDENTIFIED WITH mysql_no_login;
GRANT ALL
  ON krb_user_db.*
  TO 'proxied_krb_user';

-- grant to proxy account the
-- PROXY privilege for proxied account
GRANT PROXY
  ON 'proxied_krb_user'
  TO 'bredon@MYSQL.LOCAL';
```

仔细观察第一个代理帐户名称的引用[`创建用户`](create-user.html)声明和[`授权代理`](grant.html)陈述：

-   对于大多数 MySQL 帐户，用户和主机是帐户名称的独立部分，因此单独引用为`'*`用户名`*'@'*`主机名`*'`.

-   对于 LDAP Kerberos 身份验证，帐户名称的用户部分包括主体域，因此`'bredon@MYSQL.LOCAL'`被引用为单个值。因为没有给出主机部分，所以完整的 MySQL 帐户名称使用默认的`'%'`作为主机部分：`'bredon@MYSQL.LOCAL'@'%'`

笔记

创建使用身份验证的帐户时`authentication_ldap_sasl`具有 GSSAPI/Kerberos 身份验证方法的 SASL LDAP 身份验证插件，[`创建用户`](create-user.html)语句包括域作为用户名的一部分。这不同于创建使用`身份验证_kerberos`Kerberos 插件。对于此类账户，[`创建用户`](create-user.html)语句不包括域作为用户名的一部分。而是将领域指定为`经过`条款。看[创建使用 Kerberos 身份验证的 MySQL 帐户](kerberos-pluggable-authentication.html#kerberos-usage-mysql-account-setup).

代理帐户使用`mysql_no_login`身份验证插件，以防止客户端使用该帐户直接登录到 MySQL 服务器。相反，预计使用 LDAP 进行身份验证的用户使用`布雷登@MYSQL.LOCAL`代理帐户。（这假设`mysql_no_login`插件已安装。有关说明，请参阅[第 6.4.1.9 节，“非登录可插入身份验证”](no-login-pluggable-authentication.html).) 有关保护代理帐户不被直接使用的替代方法，请参阅[防止直接登录代理帐户](proxy-users.html#preventing-proxied-account-direct-login).

###### 使用 MySQL 帐户连接到 MySQL 服务器

设置使用 GSSAPI/Kerberos 进行身份验证的 MySQL 帐户后，客户端可以使用它连接到 MySQL 服务器。Kerberos 身份验证可以在 MySQL 客户端程序调用之前或之时进行：

-   在调用 MySQL 客户端程序之前，客户端用户可以独立于 MySQL 从 KDC 获取 TGT。例如，客户端用户可以使用**基尼特**通过提供 Kerberos 主体名称和主体密码对 Kerberos 进行身份验证：

    ```
    $> kinit bredon@MYSQL.LOCAL
    Password for bredon@MYSQL.LOCAL: (enter password here)
    ```

    生成的 TGT 被缓存并可供其他支持 Kerberos 的应用程序使用，例如使用客户端 SASL LDAP 身份验证插件的程序。在这种情况下，MySQL 客户端程序使用 TGT 对 MySQL 服务器进行身份验证，因此无需指定用户名或密码即可调用客户端：

    ```
    mysql --default-auth=authentication_ldap_sasl_client
    ```

    如前所述，当缓存 TGT 时，客户端命令中不需要用户名和密码选项。如果命令仍然包含它们，则按如下方式处理它们：

    -   如果该命令包含用户名，并且该名称与 TGT 中的主体名称不匹配，则身份验证将失败。

    -   如果命令包含密码，客户端插件将忽略它。因为认证是基于TGT的，所以可以成功*即使用户提供的密码不正确*.因此，如果发现有效的 TGT 导致密码被忽略，插件会发出警告。

-   如果 Kerberos 缓存不包含 TGT，则客户端 SASL LDAP 身份验证插件本身可以从 KDC 获取 TGT。使用与 MySQL 帐户关联的 Kerberos 主体的名称和密码选项调用客户端（在一行中输入命令，然后在出现提示时输入主体密码）：

    ```
    mysql --default-auth=authentication_ldap_sasl_client
      --user=bredon@MYSQL.LOCAL
      --password
    ```

-   如果 Kerberos 缓存不包含 TGT，并且客户端命令未指定主体名称作为用户名，则身份验证失败。

    如果您不确定 TGT 是否存在，您可以使用**列表**去检查。

    身份验证发生如下：

1.  客户端使用 TGT 使用 Kerberos 进行身份验证。

2.  服务器找到主体的 LDAP 条目，并使用它来验证主体的连接。`布雷登@MYSQL.LOCAL`MySQL 代理帐户。

3.  代理账户认证字符串中的组映射信息（`'#krb_grp=proxied_krb_user'`) 表示经过身份验证的代理用户应该是`proxied_krb_user`.

4.  `布雷登@MYSQL.LOCAL`被视为代理`proxied_krb_user`，并且以下查询返回输出，如下所示：

    ```
    mysql> SELECT USER(), CURRENT_USER(), @@proxy_user;
    +------------------------------+--------------------+--------------------------+
    | USER()                       | CURRENT_USER()     | @@proxy_user             |
    +------------------------------+--------------------+--------------------------+
    | bredon@MYSQL.LOCAL@localhost | proxied_krb_user@% | 'bredon@MYSQL.LOCAL'@'%' |
    +------------------------------+--------------------+--------------------------+
    ```

    这[`用户（）`](information-functions.html#function_user)value 表示用于客户端命令的用户名（`布雷登@MYSQL.LOCAL`) 和客户端连接的主机 (`本地主机`）。

    这[`当前用户（）`](information-functions.html#function_current-user)value 是被代理的用户帐户的全名，它由`proxied_krb_user`用户部分和`%`主机部分。

    这[`@@proxy_user`](server-system-variables.html#sysvar_proxy_user)value 表示用于连接 MySQL 服务器的帐户的全名，它由`布雷登@MYSQL.LOCAL`用户部分和`%`主机部分。

    这表明代理是通过`布雷登@MYSQL.LOCAL`代理用户帐户，以及`布雷登@MYSQL.LOCAL`假定授予的特权`proxied_krb_user`代理用户帐户。

    获得的 TGT 会缓存在客户端，无需再次指定密码即可使用直到过期。无论获取 TGT，客户端插件使用它来获取服务票证并与服务器端插件通信。

笔记

当客户端身份验证插件本身获取 TGT 时，客户端用户可能不希望 TGT 被重用。如中所述[LDAP 身份验证的客户端配置参数](ldap-pluggable-authentication.html#ldap-gssapi-mysql-client-config-parameters)， 本地的`/etc/krb5.conf`文件可用于使客户端插件在完成后销毁 TGT。

服务器端插件无法访问 TGT 本身或用于获取它的 Kerberos 密码。

LDAP 身份验证插件无法控制缓存机制（存储在本地文件中、内存中等），但 Kerberos 实用程序，例如**开关**可用于此目的。

###### LDAP 身份验证的客户端配置参数

这`authentication_ldap_sasl_client`客户端 SASL LDAP 插件读取本地`/etc/krb5.conf`文件。如果此文件丢失或无法访问，则会发生错误。假设文件是​​可访问的，它可以包含一个可选的`[应用默认值]`部分提供插件使用的信息。将信息放在`mysql`部分的一部分。例如：

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

```
[appdefaults]
  mysql = {
    ldap_server_host = "ldap_host.example.com"
    ldap_destroy_tgt = true
  }
```

客户端插件在`mysql`部分：

-   这`ldap_server_host`value 指定 LDAP 服务器主机，当该主机不同于在`[领域]`部分。默认情况下，插件使用 KDC 服务器主机作为 LDAP 服务器主机。

-   这`ldap_destroy_tgt`value 表示客户端插件获取并使用后是否销毁TGT。默认，`ldap_destroy_tgt`是`错误的`, 但可以设置为`真的`以避免 TGT 重用。（此设置仅适用于客户端插件创建的 TGT，不适用于其他插件或 MySQL 外部创建的 TGT。）

##### LDAP 搜索推荐

可以将 LDAP 服务器配置为将 LDAP 搜索委托给另一个 LDAP 服务器，这种功能称为 LDAP 引用。假设服务器`a.example.com`持有一个`“dc=示例，dc=com”`根 DN 并希望将搜索委托给另一台服务器`b.example.com`.要启用此功能，`a.example.com`将配置具有以下属性的命名引用对象：

```
dn: dc=subtree,dc=example,dc=com
objectClass: referral
objectClass: extensibleObject
dc: subtree
ref: ldap://b.example.com/dc=subtree,dc=example,dc=com
```

启用 LDAP 引用的一个问题是，当搜索基础 DN 是根 DN 并且未设置引用对象时，搜索可能会失败并出现 LDAP 操作错误。MySQL DBA 可能希望避免 LDAP 身份验证插件的此类引用错误，即使 LDAP 引用可能在`ldap.conf`配置文件。要在特定插件的基础上配置 LDAP 服务器在与每个插件通信时是否应使用 LDAP 引用，请设置[`authentication_ldap_simple_referral`](pluggable-authentication-system-variables.html#sysvar_authentication_ldap_simple_referral)和[`authentication_ldap_sasl_referral`](pluggable-authentication-system-variables.html#sysvar_authentication_ldap_sasl_referral)系统变量。将任一变量设置为`在`要么`离开`导致相应的 LDAP 身份验证插件告诉 LDAP 服务器在 MySQL 身份验证期间是否使用引用。每个变量都有特定于插件的效果，并且不会影响与 LDAP 服务器通信的其他应用程序。两个变量都是`离开`默认。
