作者:杨涛涛 资深数据库专家,专研MySQL十余年。擅长MySQL、PostgreSQL、MongoDB等开源数据库相关的备份恢复、SQL调优、监控运维、高可用架构设计等。目前任职于爱可生,为各大运营商及银行金融企业提供MySQL相关技术支持、MySQL相关课程培训等工作。 本文来源:原创投稿 爱可生开源社区出品,原创内容未经授权不得随意使用,转载请联系小编并注明来源。 引言引言 这里来介绍下MySQL8。0版本自带的新密码验证策略。正文 我们非常熟悉这样的模式:用户想更改自己密码,需要提供原来密码或者追加手机验证码才可以,这种模式在MySQL数据库里一直不存在。在MySQL8。0之前的版本,普通用户可以直接更改自己密码,不需要旧密码验证,也不需要知会管理员,比如用户yttadmin需要更改密码,在MySQL5。7下直接敲alteruser命令即可:rootyttubuntu:mysqluyttadminproot1234P5734hyttubuntuealteruseryttadminidentifiedbyrootmysql:〔Warning〕Usingapasswordonthecommandlineinterfacecanbeinsecure。这样的密码更改行为其实不是很安全,假设有下面的场景出现:用户yttadmin登录到MySQL服务后,做了些日常操作,完成后忘记退出;此时刚好有一个别有用心的用户yttfake进入yttadmin的登录环境,直接敲命令alteruser即可更改用户yttadmin的密码,并且退出当前登录环境,用户yttadmin本尊再次登录MySQL,就会提示密码错误,不允许登录,此时用户yttadmin大脑肯定是懵的。为了防止这类不安全事件的发生,MySQL8。0发布了一系列密码验证策略。这里介绍第一项:当前密码验证策略设置!当前密码验证策略有两种方法来给到具体用户。第一种,从管理员侧来设置单个用户的当前密码验证策略。 创建用户或者更改用户设置时使用子句:passwordrequirecurrent(表示强制此用户满足当前密码验证策略)。mysql:(none)createuseryttadminidentifiedbyroot123passwordrequirecurrent;QueryOK,0rowsaffected(0。11sec) 之后以用户yttadmin登录MySQL并且更改密码,提示需要提供旧密码才行。rootyttubuntu:homeyttmysqlhyttubuntuuyttadminproot123mysql:〔Warning〕Usingapasswordonthecommandlineinterfacecanbeinsecure。WelcometotheMySQLmonitor。Commandsendwith;org。YourMySQLconnectionidis33Serverversion:8。0。27MySQLCommunityServerGPLmysql:(none)alteruseryttadminidentifiedbyroot;ERROR3892(HY000):CurrentpasswordneedstobespecifiedintheREPLACEclauseinordertochangeit。 接下来,alteruser跟上子句replace来让用户yttadmin输入旧密码,成功更改新密码。mysql:(none)alteruseryttadminidentifiedbyrootreplaceroot123;QueryOK,0rowsaffected(0。00sec) 如果有的场景下需要保持MySQL旧版本的密码更改行为,管理员侧可以用子句:passwordrequirecurrentoptional关闭新特性。(optional关键词可用default替代,参考全局密码验证参数设置)mysql:(none)alteruseryttadminpasswordrequirecurrentoptional;QueryOK,0rowsaffected(0。04sec) 来再次验证下用户yttadmin更改密码的行为:又变更为不安全的MySQL旧版本安全行为。mysql:(none)alteruseryttadminidentifiedbyroot;QueryOK,0rowsaffected(0。01sec)第二种,设置全局参数,来强制所有用户使用当前密码验证策略。 MySQL8。0新版本内置的参数passwordrequirecurrent定义一个全局密码策略,默认关闭。开启这个选项时,要求用户更改密码时必须提供旧密码。 开启全局参数:mysql:(none)setpersistpasswordrequirecurrenton;QueryOK,0rowsaffected(0。00sec) 创建另外一个新用户yttusage:mysql:(none)createuseryttusageidentifiedbyroot123;QueryOK,0rowsaffected(0。00sec) 以用户yttusage登录MySQL更改自己密码:直接拒绝更改,需要提供旧密码。rootyttubuntu:mysqluyttusageproot123hyttubuntumysql:〔Warning〕Usingapasswordonthecommandlineinterfacecanbeinsecure。WelcometotheMySQLmonitor。Commandsendwith;org。YourMySQLconnectionidis37Serverversion:8。0。27MySQLCommunityServerGPL。。。mysql:(none)alteruseryttusageidentifiedbyroot;ERROR3892(HY000):CurrentpasswordneedstobespecifiedintheREPLACEclauseinordertochangeit。mysql:(none) replace子句提供旧密码再次成功更改新密码:mysql:(none)alteruseryttusageidentifiedbyrootreplaceroot123;QueryOK,0rowsaffected(0。02sec) 这里有一个需要注意的点:虽然全局参数开启,但是alteruser命令优先级更高,可以直接覆盖全局参数设置。下面是全局参数开启的环境下,用alteruser命令来关闭用户yttusage的当前密码验证策略。mysql:(none)alteruseryttusagepasswordrequirecurrentoptional;QueryOK,0rowsaffected(0。11sec) 接下来用户yttusage又恢复为MySQL旧版本的安全行为:mysql:(none)alteruseryttusageidentifiedbyrootnew;QueryOK,0rowsaffected(0。11sec) 还有另外一个子句:passwordrequirecurrentdefault,具体行为由全局参数passwordrequirecurrent的设置决定,全局参数关闭,这个子句恢复MySQL旧版本安全行为;全局参数开启,这个子句使用MySQL新版本安全行为。mysql:(none)alteruseryttusagepasswordrequirecurrentdefault;QueryOK,0rowsaffected(0。09sec)总结: 本文介绍的当前密码验证策略,使得MySQL朝着更加安全的方向努力。