MySQL 8.4:未使用 mysql_native_password 却报插件未加载(Plugin mysql_native_password is not loaded)?

news/2025/11/24 8:56:09/文章来源:https://www.cnblogs.com/ivictor/p/19262263

现象

最近遇到一个有趣的案例:在一个新创建的 MySQL 8.4 实例中,使用用户 u2 登录时,返回了Plugin 'mysql_native_password' is not loaded错误。

$ mysql -h127.0.0.1 -P3316 -uu2 -p123
mysql: [Warning] Using a password on the command line interface can be insecure.
ERROR 1524 (HY000): Plugin 'mysql_native_password' is not loaded

奇怪的是,检查mysql.user表后却发现:

  • 实例里并没有 u2 这个用户;
  • 现有用户中并没有用户在使用 mysql_native_password。
mysql> select host,user,plugin from mysql.user;
+-----------+------------------+-----------------------+
| host      | user             | plugin                |
+-----------+------------------+-----------------------+
| %         | root             | caching_sha2_password |
| localhost | mysql.infoschema | caching_sha2_password |
| localhost | mysql.session    | caching_sha2_password |
| localhost | mysql.sys        | caching_sha2_password |
| localhost | root             | caching_sha2_password |
+-----------+------------------+-----------------------+
5 rows in set (0.05 sec)

有意思的是,同样是不存在,如果使用 u1 登录,返回的却是Access denied for user 'xxx'@'xxx'错误:

$ mysql -h127.0.0.1 -P3316 -uu1 -p123
mysql: [Warning] Using a password on the command line interface can be insecure.
ERROR 1045 (28000): Access denied for user 'u1'@'127.0.0.1' (using password: YES)

问题来了:

  1. 同样不存在,为什么 u1 和 u2 会返回不同的错误?
  2. 明明没有用户在使用 mysql_native_password,为什么 MySQL 会提示Plugin 'mysql_native_password' is not loaded

根因分析

下面结合 MySQL 客户端与服务端的认证流程,来分析上述报错。

一、

客户端向 MySQL 服务端发起连接请求。

二、

服务端收到请求后,会调用do_auth_once()函数对客户端进行身份认证。

首次认证时,MySQL 会调用默认的密码认证插件进行认证。

在 MySQL 8.4 之前,默认的密码认证插件由 default_authentication_plugin 参数决定:

  • 5.7 默认是 mysql_native_password。
  • 8.0 改成了 caching_sha2_password。
  • 到了 8.4,移除了这个参数,默认插件被固定为 caching_sha2_password。

所以,在 MySQL 8.4 中,MySQL 会调用 caching_sha2_password 插件向客户端发送一个握手包(handshake packet)。

握手包的内容包括通信协议版本、服务端版本、随机数(盐值)、服务端能力标志、默认字符集编号、密码认证插件名称等。

三、

客户端收到握手包后,默认会根据包中指定的认证插件(在 MySQL 8.4 中是 caching_sha2_password)生成并返回一个握手响应包(handshake response)。

响应包的内容包括客户端能力标志、用户名、加密后的密码、要连接的库名、客户端使用的认证插件等。

四、

服务端收到响应包后,会调用parse_client_handshake_packet()函数进行处理。该函数主要做:

  1. 读取客户端能力标志。

  2. 如果客户端要求 SSL,则先完成 SSL 握手并重新读取一个包。

  3. 设置客户端使用的字符集。

  4. 提取用户名、密码、默认库名和认证插件。

  5. 调用find_mpvio_user初始化 mpvio( mpvio 用于存储认证过程中的用户信息、连接信息及插件交互状态)。

find_mpvio_user会根据客户端发来的用户名与 host/ip,从 ACL 用户缓存(mysql.user)中找到对应的用户记录。如果用户不存在,MySQL 不会直接暴露“用户名不存在”,而是走 decoy_user() 逻辑,为这类“未知用户”随机分配一个认证插件,构造一个看起来正常的用户记录。这样可以避免外部探测哪些用户名真实存在。

以下是 decoy_user() 函数的具体实现。

ACL_USER *decoy_user(const LEX_CSTRING &username, const LEX_CSTRING &hostname,
                     MEM_ROOT *mem, struct rand_struct *rand,
                     bool is_initialized) {
  ...
if (is_initialized) {
    // 根据用户名和 host/ip 生成一个 key
    Auth_id key(user);
     
    uint value;
    // 如果该 unknown user 已经出现过,则复用之前分配的认证插件。
    // 这样可以保证同一个客户端每次收到的登录验证行为一致,避免泄露用户名是否存在的信息。
    if (unknown_accounts->find(key, value)) {
      user->plugin = Cached_authentication_plugins::cached_plugins_names[value];
    } else {
      // 对于首次遇到的 unknown user,会从 cached_plugins_names 中随机分配一个认证插件。
      constint DECIMAL_SHIFT = 1000;
      constint random_number = static_cast<int>(my_rnd(rand) * DECIMAL_SHIFT);
      uint plugin_num = (uint)(random_number % ((uint)PLUGIN_LAST));
      user->plugin =
          Cached_authentication_plugins::cached_plugins_names[plugin_num];
      unknown_accounts->clear_if_greater(MAX_UNKNOWN_ACCOUNTS);
      // 将客户端及分配的插件记录到 unknown_accounts 缓存中
      if (!unknown_accounts->insert(key, plugin_num)) {
        if (!unknown_accounts->find(key, plugin_num))
          user->plugin = default_auth_plugin_name;
        else
          user->plugin =
              Cached_authentication_plugins::cached_plugins_names[plugin_num];
      }
    }
  }
  ...
return user;
}
// cached_plugins_names 的定义
const LEX_CSTRING Cached_authentication_plugins::cached_plugins_names[(
    uint)PLUGIN_LAST] = {{STRING_WITH_LEN("caching_sha2_password")},
                         {STRING_WITH_LEN("mysql_native_password")},
                         {STRING_WITH_LEN("sha256_password")}};

对于 u1 用户,随机分配到的认证插件可能是 caching_sha2_password 或 sha256_password,对于 u2 用户,则恰好分配到了 mysql_native_password。

五、

parse_client_handshake_packet()函数中,如果发现客户端使用的密码认证插件与mysql.user表中记录的插件不一致(对于“伪用户”,则是随机分配的插件),MySQL 会调用do_auth_once()进行二次认证。

此时,认证会使用mysql.user表中的插件,或者伪用户被随机分配的插件。

如果指定的认证插件在服务端不存在,则会触发Plugin 'xxx' is not loaded错误。

do_auth_once()的具体实现如下:

static int do_auth_once(THD *thd, const LEX_CSTRING &auth_plugin_name,
                        MPVIO_EXT *mpvio) {
  DBUG_TRACE;
int res = CR_OK, old_status = MPVIO_EXT::FAILURE;
bool unlock_plugin = false;
// 先尝试从缓存中获取指定插件
  plugin_ref plugin =
      g_cached_authentication_plugins->get_cached_plugin_ref(&auth_plugin_name);
// 若缓存中不存在,则按名称加载插件
if (!plugin) {
    if ((plugin = my_plugin_lock_by_name(thd, auth_plugin_name,
                                         MYSQL_AUTHENTICATION_PLUGIN)))
      unlock_plugin = true;
  }

  mpvio->plugin = plugin;
  old_status = mpvio->status;
// 如果插件存在,则调用对应的 authenticate_user() 方法与客户端进行认证交互
if (plugin) {
    st_mysql_auth *auth = (st_mysql_auth *)plugin_decl(plugin)->info;
    res = auth->authenticate_user(mpvio, &mpvio->auth_info);

    if (unlock_plugin) plugin_unlock(thd, plugin);
  } else {
    // 如果插件无法加载,就会触发 Plugin xxx is not loaded 错误。
    Host_errors errors;
    errors.m_no_auth_plugin = 1;
    inc_host_errors(mpvio->ip, &errors);
    my_error(ER_PLUGIN_IS_NOT_LOADED, MYF(0), auth_plugin_name.str);
    res = CR_ERROR;
  }
  ...
return res;
}

具体到 u2 用户,因为分配的认证插件正好是 mysql_native_password,所以在二次认证阶段,MySQL 会尝试使用该插件进行验证。

但在 MySQL 8.4 中,mysql_native_password 默认是被禁用的,所以就触发了ERROR 1524 (HY000): Plugin 'mysql_native_password' is not loaded错误。

总结

当客户端使用一个不存在的用户名连接 MySQL 时:

  • MySQL 不会直接提示用户不存在
  • 而是为该用户构造一个“假用户”
  • 并随机分配一个认证插件进行认证,以防止用户名枚举攻击

在 MySQL 8.4 中,由于默认禁用了 mysql_native_password,因此,

  • 若随机分配到该插件,就会触发ERROR 1524 (HY000): Plugin 'mysql_native_password' is not loaded错误。
  • 若分配到其他插件,则会走完整认证流程并返回Access denied for user 'xxx'@'xxx'错误。

以上就是 u1 和 u2 报错不同的根本原因。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/974431.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

水题乱做

P11746 设 $R$ 为单色行的数量,$C$ 为单色列的数量。 根据题意,AI 的得分 $S_{AI} = R + C$,你的得分 $S_P = (n - R) + (m - C) = n + m - (R + C) = n + m - S_{AI}$。 获胜条件是 $S_P$ 为奇数且 $S_{AI}$ 为偶数…

第四讲GNN图神经网络

第四讲GNN图神经网络基于空间的卷积(Spatial-based convolution) 基于谱的卷积(Spectral-based convolution)

最短路的板子默写

Dj算法 (好像不太会超时)反正我拿它冲锋了 突然发现自己忘干净了 先梳理一下(和topu不同 topu是找到第一个入度=0,遍历出边 最短路是本次循环找到距离最小点遍历出边 1.建立边 用邻接表e[u]push_back(v) 2.dj函数 …

完整教程:AI超级智能体项目中的多模型集成实践:挑战、架构与代码详解

完整教程:AI超级智能体项目中的多模型集成实践:挑战、架构与代码详解pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: &…

【URP】Unity[相机]渲染类型

URP 相机渲染类型概述 在 Unity Universal Render Pipeline (URP) 中,相机组件提供了多种渲染类型选项,用于控制相机如何参与渲染流程。这些类型决定了相机是否渲染、【从UnityURP开始探索游戏渲染】专栏-直达URP 相…

20251028在荣品RD-RK3588-MID开发板的Android13系统下解决关机的时候最近打开的应用不关的难题

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

实验4 NoSQL和关系数据库的操作比较

实验要求 只给出这四种数据库的JAVA客户端编程的相关代码具体代码 导入依赖: <dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>8.…

构建卓越开发者体验的核心原则

本文深入探讨了构建卓越开发者体验的三个核心优化点:周期时间、专注度和认知负载,并分享了在Google和LinkedIn的实践经验,帮助开发团队提升效率和幸福感。什么造就了卓越的开发者体验? 我在"开发者体验"…

杂题选做-7

#61 CF1927G 题目传送门 观察:每一次操作都可以转化为一次对已覆盖区间的扩展。 因此定义 \(f_{i,j}\) 表示已经考虑了前 \(i\) 个道具的使用情况,并且已经覆盖了 \([1,j]\) 的最小操作次数,第 \(i\) 个道具可以覆盖…

上周热点回顾(11.17

热点随笔: Visual Studio 2026 上手体验,AI 懂你、界面清爽、协作无缝 (小码编匠) 九成九新自用C#入门文档 (假设狐狸有信箱) .net 行不行?在线客服系统成功支持客户双11大促,21客服在线,高…

软件设计实验十七与十八:迭代器模式,解释器模式

[实验任务一]:JAVA和C++常见数据结构迭代器的使用 信1305班共44名同学,每名同学都有姓名,学号和年龄等属性,分别使用JAVA内置迭代器和C++中标准模板库(STL)实现对同学信息的遍历,要求按照学号从小到大和从大到小…

详细介绍:MySQL-8.0.43 免安装版保姆教程

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

【GitHub每日速递 20251124】超神!verl助力大语言模型强化学习,多项特性引领行业新潮流

原文: https://mp.weixin.qq.com/s/PDq5QuTZOtJr_SbnD-29qA 超神!verl助力大语言模型强化学习,多项特性引领行业新潮流 verl 是一个用于大语言模型的强化学习框架的工具库。简单讲,它帮助开发者用强化学习技术优化大…

【STM32工程开源】STM32单片机智能台灯系统

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

Ai元人文构想:从“题海战术”到“理解原理”:AI治理中规则逻辑与价值协议的差异论证与效率抉择

从“题海战术”到“理解原理”:AI治理中规则逻辑与价值协议的差异论证与效率抉择 引语 岐金兰说:"其实我们最大的困惑是,A/B方案,都基于学习迭代过程,二者的差异与优劣,如何论证?" 在人工智能治理的研…

2025年评价高的隧道炉工业级大功率厂家最新推荐权威榜

2025年评价高的隧道炉工业级大功率厂家最新推荐权威榜行业背景与市场趋势随着全球食品工业自动化水平的不断提升,隧道炉作为烘焙、干燥、杀菌等工艺的核心设备,市场需求持续增长。根据《2024-2029年全球工业烤箱市场…

2025年质量好的定制化鸡蛋液产品安全性权威榜

2025年质量好的定制化鸡蛋液产品安全性权威榜行业背景与市场趋势随着食品工业的快速发展和消费者对食品安全要求的不断提高,定制化鸡蛋液产品市场迎来了前所未有的增长机遇。据中国蛋品行业协会最新数据显示,2024年我…

2025年比较好的钢板预处理线优质厂家推荐榜单

2025年钢板预处理线优质厂家推荐榜单:技术与市场的双重考量行业背景与市场趋势钢板预处理作为金属加工制造的关键环节,其质量直接影响后续涂装、焊接等工艺效果及产品使用寿命。根据中国表面工程协会2024年发布的行业…

机器人领域Day One奖学金计划新增14位获得者

某中心机器人部门宣布Day One奖学金计划新增14位获得者,该计划旨在支持来自多元背景的优秀硕士生,涵盖机器人、工程、计算机科学等领域,提供全额奖学金、实习机会和行业导师指导。机器人领域Day One奖学金计划新增1…

Gopeed跨终端下载神器测评:开源免费+远程控制,下载速度跑满带宽的秘诀! - 实践

Gopeed跨终端下载神器测评:开源免费+远程控制,下载速度跑满带宽的秘诀! - 实践pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font…