MySQL8安全指南之账号控制与账户管理:权限表

账号控制与账户管理

权限表

mysql数据库中包含了一些权限表,这些表包含了有关用户账户以及其拥有的权限信息。本节将描述这些表。关于系统数据库中其他表的信息,请参见The mysql System Schema

这里的讨论描述了授予表的底层结构,以及服务器在与客户机交互时如何使用它们的内容。但是,通常不直接修改授予表。当您使用帐户管理语句(如CREATE USER、GRANTREVOKE)来设置帐户并控制每个帐户可用的权限时,修改就间接发生了。当您使用这样的语句来执行帐户操作时,服务器将代表您修改授予表。

授予表概述

这些mysql据库包含权限信息:

  • user:用户账号、全局权限和其他非权限列。
  • global_grants:动态全局权限。
  • db:数据库级别的权限。
  • tables_priv:表级别的权限。
  • column_priv:列级别的权限。
  • procs_priv:存储过程和函数权限。
  • proxies_priv:代理用户权限。
  • default_roles:默认用户角色。
  • role_edges
  • password_history:历史更改过的密码。

在 MySQL 8.0 中,授权表使用 InnoDB 存储引擎并且是事务性的。在 MySQL 8.0 之前,授权表使用 MyISAM 存储引擎并且是非事务性的。这种授权表存储引擎的更改允许对帐户管理语句(如CREATE USERgrant)的行为进行相应的更改。以前,命名多个用户的帐户管理语句对于某些用户可能成功,而对于其他用户可能失败。现在,每个语句都是事务性的,要么对所有命名用户成功,要么回滚,如果发生任何错误,则无效。

每个授权表包含范围列和权限列:

  • 范围列确定表中每一行的范围;也就是说,该行适用的上下文。例如,user表中HostUser列值为'h1.example.net''bob',那么该行用于验证指定用户名为bob的客户端从hosth1 .example.net到服务器的连接。类似的,当bob用户从主机h1.example.net连接并访问report数据库的时候,db表中Host、Userdb列值为 'h1.example.net'、'bob'、reports的行将被应用。tables_privcolumns_priv 表包含范围列,指示每行适用的表或表/列组合。procs_priv 范围列指示每行适用的存储例程。

  • 权限列告诉MySQL服务表行授予哪些权限;也就是说,它允许执行哪些操作。服务器将各种授权表中的信息结合起来,形成用户权限的完整描述。 Access Control, Stage 2: Request Verification,描述了这方面的规则。

此外,授权表可能包含用于范围或权限评估以外目的的列。

服务器以下列方式使用授权表:

  • user表中的范围列决定了是否允许或者拒绝进来的连接。对于允许的接,用户表中授予的任何权限都表示用户的静态全局权限。此表中授予的任何权限都适用于服务器上的所有数据库。

    提示:因为任何静态全局特权都被认为是所有数据库的特权,所以任何静态全局特权都允许用户通过SHOW databases查看所有数据库名称,或者通过检查INFORMATION_SCHEMASCHEMATA表查看所有数据库名称

  • global_grants 表列出了当前分配给用户帐户的动态全局权限。对于该表中的每一行,范围列确定哪个用户拥有权限列中指定的权限。

  • db表的范围列决定了那些用户可以从哪些主机上访问哪些数据库。权限列决定了被允许的操作。在数据库级别授予的权限适用于数据库和数据库中的所有对象,例如表和存储的程序。

  • tables_privcolumns_privdb类似。但是粒度更细:他们应用于表级别或者列级别而不是数据库级别。在表级别授予的权限适用于该表及其所有列。在列级别授予的权限仅适用于特定列。

  • procs_priv 表适用于存储例程(存储过程和函数)。在例程级别授予的特权限仅适用于单个过程或函数。

  • proxies_priv 表指示哪些用户可以充当其他用户的代理以及用户是否可以将 PROXY 权限授予其他用户。

  • default_rolesrole_edges 表包含有关角色关系的信息。

  • password_history表保留以前用过的密码,以启用对密码重用的限制。

服务器在启动时将授权表的内容读入内存。您可以通过发出 FLUSH PRIVILEGES 语句或执行 mysqladmin flush-privileges 或 mysqladmin reload 命令来告诉它重新加载表。对权限表的更改将按照When Privilege Changes Take Effect中的说明使其生效。

当您修改帐户时,最好验证您的更改是否具有预期效果。要检查给定帐户的权限,请使用 SHOW GRANTS 语句。例如,要确定授予用户名和主机名值为 bobpc84.example.com 的帐户的权限,请使用以下语句:

SHOW GRANTS FOR 'bob'@'pc84.example.com';

要显示帐户的非特权属性,请使用 SHOW CREATE USER

SHOW CREATE USER 'bob'@'pc84.example.com';

用户和数据库授权表

服务器在访问控制的第一阶段和第二阶段都使用 mysql 数据库中的 userdb 表(请参阅Access Control and Account Management)。此处显示了 userdb 表中的列。

Table Nameuserdb
Scope columnsHostHost
UserDb
User
Privilege columnsSelect_privSelect_priv
Insert_privInsert_priv
Update_privUpdate_priv
Delete_privDelete_priv
Index_privIndex_priv
Alter_privAlter_priv
Create_privCreate_priv
Drop_privDrop_priv
Grant_privGrant_priv
Create_view_privCreate_view_priv
Show_view_privShow_view_priv
Create_routine_privCreate_routine_priv
Alter_routine_privAlter_routine_priv
Execute_privExecute_priv
Trigger_privTrigger_priv
Event_privEvent_priv
Create_tmp_table_privCreate_tmp_table_priv
Lock_tables_privLock_tables_priv
References_privReferences_priv
Reload_priv
Shutdown_priv
Process_priv
File_priv
Show_db_priv
Super_priv
Repl_slave_priv
Repl_client_priv
Create_user_priv
Create_tablespace_priv
Create_role_priv
Drop_role_priv
Security columnsssl_type
ssl_cipher
x509_issuer
x509_subject
plugin
authentication_string
password_expired
password_last_changed
password_lifetime
account_locked
Password_reuse_history
Password_reuse_time
Password_require_current
User_attributes
Resource control columnsmax_questions
max_updates
max_connections
max_user_connections

user表的pluginauthentication_string 列存储身份验证插件和凭据信息。

服务器使用帐户行中plugin列中指定的插件来验证帐户的连接尝试。

插件列必须不能为空。插件列必须为非空。在启动时和运行时执行 FLUSH PRIVILEGES 时,服务器检查user表行。对于plugin列为空的任何行,服务器将警告写入错误日志:

[Warning] User entry 'user_name'@'host_name' has an empty plugin
value. The user will be ignored and no one can login with this user
anymore.

要将插件分配给缺少插件的帐户,请使用 ALTER USER 语句。

password_expired列允许dba将帐户密码过期,并要求用户重置密码。默认的 password_expired 值为N,但可以使用 ALTER USER 语句设置为Y。帐户密码过期后,该帐户在与服务器的后续连接中执行的所有操作都会导致错误,直到用户发出 ALTER USER 语句来建立新的帐户密码。

password_last_changed 是一个 TIMESTAMP 列,指示上次更改密码的时间。对于使用 MySQL 内置身份验证插件(mysql_native_password、sha256_passwordcaching_sha2_password)的帐户,该值是非 NULL。对于其他帐户使用外部身份验证系统进行身份验证的帐户,该值为 NULL。

password_last_changedCREATE USER、ALTER USERSET PASSWORD 语句以及创建帐户或更改帐户密码的 GRANT 语句来更新。

password_lifetime 表示账户密码的生命周期,以天为单位。如果密码已过其生命周期(使用 password_last_changed 列进行评估),则当客户端使用该帐户进行连接时,服务器会认为密码已过期。N大于零意味着必须没隔 N 天更改一次密码。0表示 禁用自动密码过期。如果值为 NULL(默认值),则应用全局过期策略,通过default_password_lifetime 系统变量所定义。

account_locked 表明帐户是否被锁定(请参阅Account Locking)。

Password_reuse_history是帐户的Password history选项的值,默认历史为NULL。

Password_reuse_time 是帐户的 PASSWORD REUSE INTERVAL 选项的值,默认间隔为 NULL。

Password_require_current(MySQL 8.0.13新增)对应账户的PASSWORD REQUIRE选项的值,如下表所示。

Password_require_current ValueCorresponding PASSWORD REQUIRE Option
'Y'PASSWORD REQUIRE CURRENT
'N'PASSWORD REQUIRE CURRENT OPTIONAL
NULLPASSWORD REQUIRE CURRENT DEFAULT

User_attributes(在 MySQL 8.0.14 中添加)是一个 JSON 格式的列,用于存储未存储在其他列中的帐户属性:

  • additional_password:二级密码,如果有的话。请参阅 Dual Password Support
  • Restrictions:限制列表。限制是通过部分撤销操作添加的。属性值是一个元素数组,每个元素都有DatabaseRestrictions键,指示受限制数据库的名称及其适用的限制。请参阅 Privilege Restriction Using Partial Revokes
  • Password_locking:登录失败跟踪和临时帐户锁定的条件。Password_locking属性根据CREATE USER和ALTER USER语句的FAILED_LOGIN_ATTEMPTSPASSWORD_LOCK_TIME选项进行更新。failed_login_attemptspassword_lock_time_days键属性值是一个散列。如果缺少键,则其值隐式为0。如果键值隐式或显式为0,则禁用相应的功能。这个属性是在MySQL 8.0.19中添加的。

示例:有二级密码和部分被撤销的数据库权限的帐户在列值中有additional_passwordRestrictions属性:

mysql> SELECT User_attributes FROM mysql.User WHERE User = 'u'\G
*************************** 1. row ***************************
User_attributes: {"Restrictions":[{"Database": "mysql", "Privileges": ["SELECT"]}],"additional_password": "hashed_credentials"}

要确定存在哪些属性,请使用 JSON_KEYS() 函数:

SELECT User, Host, JSON_KEYS(User_attributes) FROM mysql.user WHERE User_attributes IS NOT NULL;

要提取特定属性,例如Restrictions,请执行以下操作:

SELECT User, Host, User_attributes->>'$.Restrictions' FROM mysql.user WHERE User_attributes->>'$.Restrictions' <> '';

table_priv 和 columns_priv 授权表

在访问控制的第二阶段,服务器执行请求验证以确保每个客户端对其发出的每个请求都有足够的权限。除了userdb授权表之外,服务器还可以查询tables_privcolumns_priv表,以获取涉及到表的请求。后两个表在表和列级别提供更精细的权限控制。他们有如下表所示的列。

Table 6.6 tables_priv and columns_priv Table Columns

Table Nametables_privcolumns_priv
Scope columnsHostHost
DbDb
UserUser
Table_nameTable_name
Column_name
Privilege columnsTable_privColumn_priv
Column_priv
Other columnsTimestampTimestamp
Grantor

TimestampGrantor 列分别设置为当前时间戳和 CURRENT_USER 值,但在其他方面未使用。

procs_priv 授权表

对于涉及存储例程的请求的验证,服务器可以查阅 procs_priv 表,该表具有下表所示的列。

Table Nameprocs_priv
Scope columnsHost
Db
User
Routine_name
Routine_type
Privilege columnsProc_priv
Other columnsTimestamp
Grantor

Routine_type 列是一个 ENUM 列,其值为 'FUNCTION''PROCEDURE’ 以表明该行引用的例程类型。此列允许为具有相同名称的函数和过程分别授予特权。

TimestampGrantor 列未使用。

proxies_priv 授权表

proxies_priv 表记录有关代理帐户的信息。它有这些列:

  • Host、User:代理账号;即具有帐代理权限的帐户。
  • Proxied_host、Proxied_user:代理账户。
  • Grantor,Timestamp:未使用。
  • with_grant:代理账户是否可以将代理权限授予其他账户。

global_grants 授权表

global_grants 表列出了当前分配给用户帐户的动态全局权限。该表具有以下列:

  • USER、HOST:授予权限的帐户的用户名和主机名。

  • PRIV:权限名称。

  • WITH_GRANT_OPTION:该账户是否可以将权限授予其他账户。

default_roles 授权表

default_roles 表列出了默认用户角色。它有这些列:

  • HOST、USER:默认角色适用的帐户或角色。

  • DEFAULT_ROLE_HOST、DEFAULT_ROLE_USER:默认角色。

password_history 授权表

password_history 表包含有关密码更改的信息。它有这些列:

  • Host, User:发生密码更改的帐户。
  • Password_timestamp:发生密码更改的时间。
  • Password:新的密码哈希值。

password_history表会为每个帐户积累足够数量的非空密码,以使MySQL能够对帐户密码历史长度和重用间隔进行检查。当尝试更改密码时,会自动删除这两个限制之外的条目。

如果一个帐户被重命名,它的条目将被重命名。如果帐户被删除或其身份验证插件被更改,则其条目将被删除。

授权表范围列属性

授权表中的范围列包含字符串。每个列的默认值是空字符串。下表显示了每列中允许的字符数。

Column NameMaximum Permitted Characters
Host, Proxied_host255 (60 prior to MySQL 8.0.17)
User, Proxied_user32
Db64
Table_name64
Column_name64
Routine_name64

HostProxied_host 值在存储到授权表中之前被转换为小写。

出于访问检查目的,User、Proxied_user、authentication_string、DbTable_name 值的比较区分大小写。 Host、Proxied_host、Column_nameRoutine_name 值的比较不区分大小写。

授权表权限列属性

userdb表在单独的列中列出每个权限,声明为ENUM('N','Y') DEFAULT 'N'。换句话说,每个权限都可以禁用或启用,默认是禁用的。

tables_priv, columns_priv, 和procs_priv表将权限列声明为Set列。这些列中的值可以控制的任何权限组合。只会启用列值中列出的那些权限。

Table NameColumn NamePossible Set Elements
tables_privTable_priv'Select', 'Insert', 'Update', 'Delete', 'Create', 'Drop', 'Grant', 'References', 'Index', 'Alter', 'Create View', 'Show view', 'Trigger'
tables_privColumn_priv'Select', 'Insert', 'Update', 'References'
columns_privColumn_priv'Select', 'Insert', 'Update', 'References'
procs_privProc_priv'Execute', 'Alter Routine', 'Grant'

只有 userglobal_grants 表指定了管理权限,例如 RELOAD、SHUTDOWNSYSTEM_VARIABLES_ADMIN。管理操作是针对服务器本身的操作,不是特定于数据库的,因此没有理由在其他授予表中列出这些权限。因此,服务器只需要参考userglobal_grants表来确定用户是否可以执行管理操作。

FILE特权也只在user表中指定。它本身并不是一种管理权限,但用户读写服务器主机上的文件的能力与所访问的数据库无关。

授予表并发

MySQL 8.0.22开始,为了允许在MySQL 授权表上并发DMLDDL操作,之前在MySQL 授权表上获得行锁的读操作被执行为非锁读。在MySQL授权表上执行的非锁定读操作包括:

  • SELECT语句和其他只读语句通过联接列表和子查询从授权表中读取数据。包括 SELECT ... FOR SHARE 语句,使用任何事务隔离级别。
  • 使用任何事务隔离级别从授权表读取数据(通过连接列表或子查询)但不修改它们的 DML 操作。

使用 -binlog_format=mixed 时,从授权表读取数据的 DML 操作将作为行事件写入二进制日志,以使混合模式复制的操作安全。

指定账户名称

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值