Mysql权限拆解

一、权限系统的工作原理

MySQL权限系统通过下面两个阶段进行认证:

1. 对连接的用户进行身份认证,合法的用户通过认证、不合法的用户拒绝连接。

2. 通过认证的合法用户从数据库里查询到对应的权限,用户可以在这些权限范围内对数据库做相应的操作。

权限系统可以从这3个维度来理解:我是谁,从哪里来,到哪里去(前两项验证是否能连接,后一项确定访问对象)  

信息存储在mysql.user 表中,host+user+password 作为整体来判断是否有连接权限。

身份认证通过后,权限按照user,db,tables_priv,columns_priv的顺序进行验证,

权限具有隐式继承关系,权限授于高层时,其他低层隐式继承被授于的权限,当然低层也可改写这些权限。

二、身份验证

对于身份认证,MySQL是通过IP地址(域名)和用户名联合进行确认的,

例如MySQL安装默认创建的用户root@localhost表示用户root只能从本地(localhost)进行连接才可以通过认证,

此用户从其他任何主机对数据库进行的连接都将被拒绝。也就是说,同样的一个用户名,如果来自不同的IP地址,则MySQL将其视为不同的用户。

举例说明,如何创建一个合法的用户

mysql>create user 'test'@'localhost' identified by '123456';                    ==>只能本地登录

mysql>create user 'test'@'192.168.1.%' identified by '123456';                ==>只能192.168.1网段的登录

mysql>create user 'test'@'%' identified by '123456';                              ==>无限制网段的登录

三、权限级别

mysql的权限分为5个级别,分别如下:
全局层级

全局权限:所有权限信息保存在mysql.User 表中,全局权限的所有权限都是针对整个mysqld的,对所有mysql数据库下的所有表及所有字段都有效。
要授予全局权限权限只需要在执行GRANT命令的时候,用*.*来指定范围是全局即可,如果有多个用户,可以使用逗号分隔开,如下:

mysql> grant all privileges on *.* to 'test'@'%' with grant option ;

mysql> grant create on *.* to 'test'@'192.168.1.%';

mysql>select * from mysql.user where user='test' and host='192.168.1.%' \G

User:test

Create_priv:Y

创建权限,只能创建,无法删除、查询、更改(自己创建的也不行)

数据库层级

数据库层级是在全局层级之下,其他三个Level之上的权限级别,其作用域即为所指定数据库中的所有对象,

和全局层级比数据库层级主要少了以下几个权限,

create user,file,process,reload,replication,replication client,replication slave,show databases,shutdown

没有增加任何权限,权限存储在mysql.db表中,要授予数据库层级权限,用如下方式实现:

1、在执行GRANT命令的时候,通过database.* 来指定作用域为整个数据库:

2、先创建一个没有权限的用户再使用过GRANT命令来授权

grant select on mysql.* to 'test'@'localhost'  with grant option;  

create user 'test01'@'%' identified by '123456';

grant select,insert,update,delete on mysql.* to 'test01'@'%';

表层级

表层级权限可以被全局层级和数据库层权限覆盖,表层级权限的作用域是授权所指定的表,所以权限种类也比较小, 只有如下8个权限,alter,create,delete,drop,index,insert,select,update

可以通过如下语句来授权:

grant CREATE,DELETE,INSERT,SELECT,UPDATE on *.* to 'test01'@'%';

列层级

列层级权限的作用域仅限于某个表的某个列,这些权限存储在mysql.columns_priv表中,列层级同样可以被高层同样的权限覆盖掉, 由于列层级权限和子程序层权限作用域没有重合部分所以不会被覆盖

列层级权限仅有select,update,insert三种,通过如下方式赋予权限(需要赋予权限的列名用括号括起来)

grant select(id,name) on test.test01 to test@'%' ;

只能对列操作,不能删除列,删除列属于表层级权限

grant select(id,name) on test.test01 to test@'%' ;

select * from mysql.columns_priv \G

Host:%

User:test01

Db:test

Table_name:test01

Column_name:id,name

Column_priv:Select

子程序层级

create routine,alter routine,execute和grant权限适用于已存储的子程序。这些权限可以被授予为全局层级和数据库层级。 而且,除了create routine外,这些权限可以被授予为子程序层级,并存储在mysql.procs_priv表中。

mysql中程序主要是指:procedure和funcation 两类

与前面授权一样,全局、库、程序对应的表里查询

grant create routine  on test.* to test@'localhost'; (create routine 创建存储过程和函数权限)

select * from user where user like 'test%' \G

具体procedure和funcation 的权限:

select * from mysql.procs_priv \G

四、权限授予、查看、回收、删除

grant create on test.* to test@'%';

show grants for test@'%';

revoke create on test.*  from test@'%'; 回收只能针对普通权限

revoke all privileges, grant option from test@‘%’; 回收所有权限

drop user test@'%';

五、权限生效时间

通过grant、revoke、set password、rename等mysql提供的命令方式修改,立即生效,这些命令直接载入授权表到内存

通过insert、update、delete 手动修改字典表,通过重启mysql,或者flush privileges 刷新字典表到内存,生效。

权限变更过后对已连接的客户端影响:

表、列粒度的权限将在客户端下次执行操作时生效

数据库级别,在切换数据库的时候生效

全局和密码修改,对当前已连接的客户端无效,下次连接生效

猜你喜欢

转载自blog.csdn.net/zll4859291/article/details/129983690