MySQL 賬號密碼永不過期為什么不起作用?

背景

客戶反饋MySQL賬號已經(jīng)設(shè)置成密碼永不過期了,但是在登錄后總是提示報(bào)錯(cuò)
ERROR 1862 (HY000): Your password has expired. To log in you must change it using a client that supports expired passwords.

排查方法

首先檢查一下MySQL服務(wù)器設(shè)置的密碼過期時(shí)間,可以看到默認(rèn)密碼60天就會過期

mysql> show variables like '%lifetime%';
+---------------------------+-------+
| Variable_name             | Value |
+---------------------------+-------+
| default_password_lifetime | 60    |
+---------------------------+-------+
1 row in set (0.01 sec)

然后檢查一下mysql.user表,看看用戶說提示報(bào)錯(cuò)的賬號的配置

mysql> select user,host,password_expired,password_last_changed,password_lifetime from mysql.user where user='user';
+------+------+------------------+-----------------------+-------------------+
| user | host | password_expired | password_last_changed | password_lifetime |
+------+------+------------------+-----------------------+-------------------+
| user | %    | N                | 2023-02-06 15:03:41   |                 0 |
+------+------+------------------+-----------------------+-------------------+
1 row in set (0.00 sec)
  • password_expired列為N
    這個(gè)賬號沒有被手動設(shè)置密碼過期
  • password_lifetime列為0
    賬號正常應(yīng)該已經(jīng)設(shè)置成密碼永不過期了
  • password_last_changed列為2023-02-06 15:03:41
    上次密碼修改時(shí)間是2023-02-06

疑點(diǎn)

這個(gè)問題詭異的地方就是password_lifetime列為0。
正常情況下,單個(gè)賬號的策略會覆蓋全局策略。也就是說,如果設(shè)置過單個(gè)賬號密碼永不過期,就不會再參考default_password_lifetime參數(shù)值計(jì)算密碼過期時(shí)間。
這個(gè)賬號如果按照上次密碼修改時(shí)間+默認(rèn)60天過期計(jì)算的話,確認(rèn)是密碼過期該修改密碼了。

分析

排查了半天,后來靈機(jī)一動,想起來一種情況:
這個(gè)賬號是客戶自己設(shè)置成密碼永不過期的,正常我們設(shè)置密碼永不過期都是使用ALTER USER user PASSWORD EXPIRE NEVER語句,但是客戶會不會用了其他方法呢,比如說直接修改mysql.user表?
我們知道,MySQL會在啟動時(shí)將權(quán)限表讀取到內(nèi)存中。而直接更新mysql.user表,不會立即生效,需要再執(zhí)行FLUSH PRIVILEGES重新加載權(quán)限表。

后來追問客戶,客戶果然是在navicat界面中直接點(diǎn)擊mysql.user表,把password_lifetime列改為0,就以為設(shè)置成功了。

處理方案

執(zhí)行FLUSH PRIVILEGES刷新權(quán)限后,果然賬號登錄時(shí)不再報(bào)錯(cuò)。

原因

設(shè)置密碼永不過期的方法錯(cuò)誤,只更新了mysql.user表,沒有刷新權(quán)限
正確方法

ALTER USER user PASSWORD EXPIRE NEVER;
-- 或者
UPDATE mysql.user SET password_lifetime=0 WHERE user='user';
FLUSH PRIVILEGES;

擴(kuò)展知識

MySQL的權(quán)限修改何時(shí)生效

MySQL在啟動時(shí)將權(quán)限表加載到內(nèi)存中,之后使用內(nèi)存中的權(quán)限表進(jìn)行訪問控制

  • 使用賬號管理語句,如ALTER USER/GRANT/REVOKE/SET PASSWORD等,會重新加載權(quán)限表,立即生效。
  • 使用INSERT,UPDATE,DELETE等更改權(quán)限表,不會加載到內(nèi)存中,不會立即生效。要使這些更改生效,可以:
    • 重新加載權(quán)限表 FLUSH PRIVILEGES
    • 重啟數(shù)據(jù)庫

設(shè)置密碼有效期策略

  • 全局有效期更改
SET GLOBAL default_password_lifetime = 60
  • 單個(gè)賬號有效期更改
-- 跟隨全局策略
ALTER USER user PASSWORD EXPIRE DEFAULT
-- 密碼永不過期
ALTER USER user PASSWORD EXPIRE NEVER
-- 密碼N天過期
ALTER USER user PASSWORD EXPIRE INTERVAL N DAY
  • 直接設(shè)置密碼過期
ALTER USER user PASSWORD EXPIRE

密碼立刻過期,在賬號登錄后,必須修改密碼才能進(jìn)行其他操作
使用這種方式設(shè)置密碼過期后,沒有SQL語句直接設(shè)置密碼不過期,但是可以通過更新mysql.userpassword_expired列,然后FLUSH PRIVILEGES刷新權(quán)限,變相允許用戶繼續(xù)使用之前的密碼

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容