赞
踩
MySQL实现了一个复杂的访问控制和权限系统,允许您创建全面的访问规则来处理客户端操作并有效防止未经授权的客户端访问数据库系统。
当客户端连接到服务器时,MySQL访问控制有两个阶段:
有一个名为MySQL安装程序自动创建的数据库mysql。mysql数据库包含五个主要授权表。您经常通过GRANT 和 REVOKE等语句间接操作这些表 。
3. user
:包含用户帐户和全局权限列。MySQL使用user表来接受或拒绝来自主机的连接。user表中授予的权限 对MySQL服务器上的所有数据库都有效。
4. db
:包含数据库级别权限。MySQL使用db表来确定用户可以访问哪个数据库以及从哪个主机访问。在db表中的数据库级别授予的权限适用于数据库,并且所有对象都属于数据库,例如表,触发器,视图,存储过程等。
5. table_priv
和columns_priv
:包含表级和列级权限。table_priv表中授予的权限适用于表及其列,而columns_priv 表中授予的权限仅适用于 表的特定列。
6. procs_priv
:包含存储的函数和存储过程权限
在MySQL中,您不仅可以指定谁可以连接到数据库服务器,还可以指定用户连接的主机。因此,MySQL中的用户帐户包含用户名和由@字符分隔的主机名。
例如,如果admin 用户连接到MySQL数据库服务器localhost,则用户帐户为 admin@localhost
admin用户只能从连接到MySQL数据库服务器localhost,而不是从远程主机如begtut.com。这使得MySQL数据库服务器更加安全。
此外,通过组合用户名和主机,可以设置多个具有相同名称的帐户,但可以使用不同的权限从不同的主机进行连接。
MySQL将用户帐户存储在mysql数据库的user授权表中。
MySQL提供了CREATE USER 允许您创建新用户帐户的语句。CREATE USER语句的语法如下:
CREATE USER user_account IDENTIFIED BY password;
user_account格式’username’@‘hostname’ 之后的CREATE USER语句。
密码在IDENTIFIED BY子句中指定。密码必须是明文。在将用户帐户保存到user表中之前,MySQL将加密密码。
例如,要创建一个使用 密码dbadmin连接到MySQL数据库服务器 的新用户,请使用以下 语句:localhostsecretCREATE USER
CREATE USER dbadmin@localhost
IDENTIFIED BY 'secret';
要查看用户帐户的权限,请使用以下SHOW GRANTS语句:
SHOW GRANTS FOR dbadmin@localhost;
结果中的*.*表示用户帐户dbadmin只能登录数据库服务器,没有其他权限。
请注意,点(.)前面的部分代表数据库,点(.)后面的部分代表表格,例如, database.table
要允许用户帐户从任何主机进行连接,请使用百分比(%) 通配符,如以下示例所示:
CREATE USER superadmin@'%'
IDENTIFIED BY 'secret';
百分比通配符% 与在LIKE运算符中使用的效果相同,例如,要允许mysqladmin用户帐户从begtut.com 主机的任何子域连接到数据库服务器 ,请使用百分比通配符% ,如下所示:
CREATE USER mysqladmin@'%.begtut.com'
IDENTIFIED by 'secret';
请注意,您还可以在CREATE USER 语句中使用下划线通配符_ 。
如果省略hostname 用户帐户的一部分,MySQL将接受它并允许用户从任何主机连接。例如,以下语句创建一个名为remote 可以从任何主机连接到数据库服务器的新用户帐户:
CREATE USER remote;
您可以看到授予remote用户帐户的权限,如下所示:
SHOW GRANTS FOR remote;
更改密码的第一种方法是使用UPDATE 语句来更新mysql数据库user表。
执行UPDATE语句后,还需要执行FLUSH PRIVILEGES 语句以从mysql数据库中的grant表重新加载权限。
假设你想为dbadmin更改密码,则需要执行以下语句:
USE mysql;
UPDATE user
SET password = PASSWORD('dolphin')
WHERE user = 'dbadmin' AND
host = 'localhost';
FLUSH PRIVILEGES;
请注意,从MySQL 5.7.6开始,用户表authentication_string仅使用列来存储密码。此外,它删除了password列。
因此,如果您使用MySQL 5.7.6+,则必须使用UPDATE语句中的authentication_string列:
USE mysql;
UPDATE user
SET authentication_string = PASSWORD('dolphin')
WHERE user = 'dbadmin' AND
host = 'localhost';
FLUSH PRIVILEGES;
更改密码的第二种方法是使用SET PASSWORD 语句。
您使用user@host 格式的用户帐户来更新密码。如果您需要更改其他帐户的密码,您的帐户至少需要拥有UPDATE权限。
通过使用SET PASSOWORD语句,您无需执行FLUSH PRIVILEGES 语句即可从授权表重新加载权限。
以下语句dbadmin 使用SET PASSWORD 语句更改用户帐户的密码 。
SET PASSWORD FOR 'dbadmin'@'localhost' = PASSWORD('bigshark');
请注意,从版本5.7.6开始,MySQL对此语法进行了折旧,并可能在将来的版本中将其删除。相反,它使用明文密码如下:
SET PASSWORD FOR 'dbadmin'@'localhost' = 'bigshark';
更改用户帐户密码的第三种方法是使用ALTER USER 带有IDENTIFIED BY 子句的语句 。
以下ALTER USER 语句将dbadmin 用户的密码更改 为littlewhale:
ALTER USER dbadmin@localhost IDENTIFIED BY 'littlewhale';
之后创建一个新的用户帐户,用户没有任何特权。要授予用户帐户权限,请使用GRANT语句。
以下说明了GRANT语句的语法:
GRANT privilege,[privilege],.. ON privilege_level
TO user [IDENTIFIED BY password]
[REQUIRE tsl_option]
[WITH [GRANT_OPTION | resource_option]];
请注意,要使用GRANT语句,您必须具有GRANT OPTION您授予的权限和权限。如果read_only 启用了系统变量,则需要具有SUPER执行GRANT语句的权限。
通常,我们首先使用CREATE USER语句创建新用户帐户,然后使用GRANT语句向用户授予权限。
例如,以下CREATE USER语句创建一个新的超级用户帐户。
CREATE USER super@localhost IDENTIFIED BY 'dolphin';
要显示分配给super @ localhost用户的特权,请使用SHOW GRANTSstatement。
SHOW GRANTS FOR super@localhost;
要授予super @ localhost用户帐户的所有权限,请使用以下语句。
GRANT ALL ON *.* TO 'super'@'localhost' WITH GRANT OPTION;
ON *.*子句表示数据库中的所有数据库和所有对象。在WITH GRANT OPTION允许super@localhost授予权限给其他用户。
现在,如果SHOW GRANTS再次使用语句,您将看到super @ localhost的权限已更新。
SHOW GRANTS FOR super@localhost;
要创建在mysqldemo 示例数据库中具有所有权限的用户,请使用以下语句:
CREATE USER auditor@localhost IDENTIFIED BY 'whale';
GRANT ALL ON mysqldemo.* TO auditor@localhost;
您可以在单个GRANT 语句中授予多个权限。例如,您可以 使用以下语句创建一个可以对mysqldemo数据库执行SELECT,INSERT和UPDATE语句的用户 :
CREATE USER rfc IDENTIFIED BY 'shark';
GRANT SELECT, UPDATE, DELETE ON mysqldemo.* TO rfc;
特权 | 说明 | 全局 | 数据库 | 表 | 列 | 程序 | 代理 |
---|---|---|---|---|---|---|---|
ALL [PRIVILEGES] | 授予除GRANT OPTION之外的指定访问级别的所有权限 | ||||||
ALTER | 允许用户使用ALTER TABLE语句 | X | X | X | |||
ALTER ROUTINE | 允许用户更改或删除存储的例程 | X | X | X | |||
CREATE | 允许用户创建数据库和表 | X | X | X | |||
CREATE ROUTINE | 允许用户创建存储的例程 | X | X | ||||
CREATE TABLESPACE | 允许用户创建,更改或删除表空间和日志文件组 | X | |||||
CREATE TEMPORARY TABLES | 允许用户使用CREATE TEMPORARY TABLE创建临时表 | X | X | ||||
CREATE USER | 允许用户使用CREATE USER,DROP USER,RENAME USER和REVOKE ALL PRIVILEGES语句。 | X | |||||
CREATE VIEW | 允许用户创建或修改视图。 | X | X | X | |||
DELETE | 允许用户使用DELETE | X | X | X | |||
DROP | 允许用户删除数据库,表和视图 | X | X | X | |||
EVENT | 启用事件计划程序的事件使用。 | X | X | ||||
EXECUTE | 允许用户执行存储的例程 | X | X | X | |||
FILE | 允许用户读取数据库目录中的任何文件。 | X | |||||
GRANT OPTION | 允许用户拥有授予或撤消其他帐户权限的权限。 | X | X | X | X | X | |
INDEX | 允许用户创建或删除索引。 | X | X | X | |||
INSERT | 允许用户使用INSERT语句 | X | X | X | X | ||
LOCK TABLES | 允许用户对具有SELECT权限的表使用LOCK TABLES | X | X | ||||
PROCESS | 允许用户使用SHOW PROCESSLIST语句查看所有进程。 | X | |||||
PROXY | 启用用户代理。 | ||||||
REFERENCES | 允许用户创建外键 | X | X | X | X | ||
RELOAD | 允许用户使用FLUSH操作 | X | |||||
REPLICATION CLIENT | 允许用户查询以查看主服务器或从属服务器的位置 | X | |||||
REPLICATION SLAVE | 允许用户使用复制从属从主服务器读取二进制日志事件。 | X | |||||
SELECT | 允许用户使用SELECT语句 | X | X | X | X | ||
SHOW DATABASES | 允许用户显示所有数据库 | X | |||||
SHOW VIEW | 允许用户使用SHOW CREATE VIEW语句 | X | X | X | |||
SHUTDOWN | 允许用户使用mysqladmin shutdown命令 | X | |||||
SUPER | 允许用户使用其他管理操作,例如CHANGE MASTER TO,KILL,PURGE BINARY LOGS,SET GLOBAL和mysqladmin命令 | X | |||||
TRIGGER | 允许用户使用TRIGGER操作。 | X | X | X | |||
UPDATE | 允许用户使用UPDATE语句 | X | X | X | X | ||
USAGE | 相当于“没有特权” |
要从用户帐户撤消权限,请使用MySQL REVOKE语句。MySQL允许您撤消用户的一项或多项权限或所有权限。
以下说明了从用户撤消特定权限的语法:
REVOKE privilege_type [(column_list)]
[, priv_type [(column_list)]]...
ON [object_type] privilege_level
FROM user [, user]...
请注意,要撤消用户帐户的权限,您必须具有 GRANT OPTION权限以及要撤消的权限。
要撤消用户的所有权限,请使用以下形式的REVOKE语句:
REVOKE ALL PRIVILEGES, GRANT OPTION FROM user [, user]…
要执行REVOKE ALL语句,您必须具有mysql数据库的全局CREATE USER特权或UPDATE特权。
要撤消代理用户,请使用以下REVOKE PROXY命令:
REVOKE PROXY ON user FROM user [, user]...
代理用户是MySQL中可以模仿其他用户的有效用户,因此,代理用户具有其模拟的用户的所有权限。
在撤消用户权限之前,最好使用以下SHOW GRANTS语句检查用户是否具有权限:
SHOW GRANTS FOR user;
假设rfc用户对示例数据库具有SELECT,UPDATE和DELETE权限。如果你想撤销和来自特权用户,你可以按照如下操作步骤:mysqldemo UPDATEDELETErfc
首先,检查用户使用SHOW GRANTS语句的权限:
SHOW GRANTS FOR rfc;
GRANT SELECT, UPDATE, DELETE ON 'mysqldemo'.* TO 'rfc'@'%';
请注意,并按照 授予的特权用户 的教程,你可以创建RFC帐户,并授予SELECT,UPDATE以及DELETE权限的,如下所示:
CREATE USER IF EXISTS rfc IDENTIFIED BY 'dolphin';
GRANT SELECT, UPDATE, DELETE ON mysqldemo.* TO rfc;
其次,你可以撤销UPDATE,并DELETE从特权 rfc 用户:
REVOKE UPDATE, DELETE ON mysqldemo.* FROM rfc;
第三,您可以rfc使用SHOW GRANTS命令再次检查用户的权限。
SHOW GRANTS FOR 'rfc'@'localhost';
GRANT SELECT ON 'mysqldemo'.* TO 'rfc'@'%';
如果要撤消rfc用户的所有权限,请执行以下命令:
REVOKE ALL PRIVILEGES, GRANT OPTION FROM rfc;
如果rfc 再次检查用户的权限,您将看到 rfc 用户没有权限。
SHOW GRANTS FOR rfc;
GRANT USAGE ON *.* TO 'rfc'@'%';
注意:USAGE权限意味着MySQL中没有权限。
MySQL REVOKE语句的效果取决于权限级别,如下所示:
通常,您有许多具有相同权限集的用户。以前,授予和撤销多个用户权限的唯一方法是单独更改每个用户的权限,这非常耗时。
为了简化,MySQL提供了一个名为role的新对象,它是一个命名的特权集合。
如果要为多个用户授予相同的权限集,则应按如下方式执行:
如果要更改用户的权限,则只需更改已授予角色的权限。更改将对角色授予的所有用户生效。
首先,创建一个名为CRM 的新数据库,代表客户关系管理。
CREATE DATABASE crm;
接下来,切换到crm数据库:
USE crm;
然后,在CRM数据库中创建customer表。
CREATE TABLE customer(
id INT PRIMARY KEY AUTO_INCREMENT,
first_name varchar(255) NOT NULL,
last_name VARCHAR(255) NOT NULL,
phone VARCHAR(15) NOT NULL,
email VARCHAR(255)
);
之后,将数据插入customer表中。
INSERT INTO customer(first_name,last_name,phone,email)
VALUES('John','Doe','(408)-987-7654','john.doe@begtut.com'),
('Lily','Bush','(408)-987-7985','lily.bush@begtut.com');
最后,使用以下SELECT语句验证插入:
假设您开发了一个使用CRM数据库的应用程序。要与CRM数据库交互,您需要为需要完全访问数据库的开发人员创建帐户。此外,您需要为仅需要读取权限的用户和需要同时具有读/写访问权限的其他用户创建帐户。
为避免单独授予每个用户帐户的权限,您需要创建一组角色并为每个用户帐户授予相应的角色。
要创建新角色,请使用CREATE ROLE语句:
CREATE ROLE crm_dev, crm_read, crm_write;
角色名称类似于由用户和主机部分组成的用户帐户:role_name@host_name。
如果省略主机部分,则默认为’%'表示任何主机。
要为角色授予权限,请使用GRANT语句。以下语句授予crm_dev角色所有权限:
GRANT ALL ON crm.* TO crm_dev;
以下语句授予角色SELECT权限crm_read:
GRANT SELECT ON crm.* TO crm_read;
下面的语句补助INSERT,UPDATE以及DELETE权限的crm_write角色:
GRANT INSERT, UPDATE, DELETE ON crm.* TO crm_write;
假设您需要一个用户帐户作为开发人员,一个可以具有只读访问权限的用户帐户和两个可以具有读/写访问权限的用户帐户。
要创建新用户,请使用以下CREATE USER语句:
-- developer user
CREATE USER crm_dev1@localhost IDENTIFIED BY 'Secure$1782';
-- read access user
CREATE USER crm_read1@localhost IDENTIFIED BY 'Secure$5432';
-- read/write users
CREATE USER crm_write1@localhost IDENTIFIED BY 'Secure$9075';
CREATE USER crm_write2@localhost IDENTIFIED BY 'Secure$3452';
要为用户分配角色,请使用以下GRANT语句:
GRANT crm_dev TO crm_dev1@localhost;
GRANT crm_read TO crm_read1@localhost;
GRANT crm_read, crm_write TO crm_write1@localhost, crm_write2@localhost;
请注意,crm_write1 @ localhost和crm_write2 @ localhost帐户的GRANT语句同时授予crm_read和crm_write角色。
要验证角色分配,请使用以下SHOW GRANTS语句作为以下示例:
SHOW GRANTS FOR crm_dev1@localhost;
现在,如果您使用crm_read1用户帐户连接到MySQL 并尝试访问CRM数据库:
>mysql -u crm_read1 -p
Enter password: ***********
mysql>USE crm;
声明发出以下错误消息:
ERROR 1044 (42000): Access denied for user 'crm_read1'@'localhost' to database 'crm'
这是因为当您向用户帐户授予角色时,当用户帐户连接到数据库服务器时,它不会自动使角色变为活动状态。
如果您调用CURRENT_ROLE()函数:
mysql> SELECT current_role();
+----------------+
| current_role() |
+----------------+
| NONE |
+----------------+
1 row in set (0.02 sec)
它返回了NONE,意味着没有活跃的角色。
要在每次用户帐户连接到数据库服务器时指定应激活哪些角色,请使用SET DEFAULT ROLE语句。
以下语句为crm_read1@localhost帐户的所有已分配角色设置默认值。
SET DEFAULT ROLE ALL TO crm_read1@localhost;
现在,如果使用crm_read1用户帐户连接到MySQL数据库服务器并调用CURRENT_ROLE()函数:
>mysql -u crm_read1 -p
Enter password: ***********
>SELECT CURRENT_ROLE();
您将看到crm_read1用户帐户的默认角色。
+----------------+
| current_role() |
+----------------+
| `crm_read`@`%` |
+----------------+
1 row in set (0.00 sec)
您可以crm_read通过将当前数据库切换为CRM,执行SELECT语句和DELETE语句来测试帐户的权限,如下所示:
mysql> use crm;
Database changed
mysql> SELECT COUNT(*) FROM customer;
+----------+
| COUNT(*) |
+----------+
| 2 |
+----------+
1 row in set (0.00 sec)
mysql> DELETE FROM customer;
ERROR 1142 (42000): DELETE command denied to user 'crm_read1'@'localhost' for table 'customer'
它按预期工作。当我们发布DELETE语句时,我们收到错误,因为crm_read1用户帐户只有读访问权限。
用户帐户可以通过指定哪个已授予的角色处于活动状态来修改当前会话中当前用户的有效权限。
以下语句将活动角色设置为NONE,表示没有活动角色。
SET ROLE NONE;
要将活动角色设置为所有已授予角色,请使用:
SET ROLE ALL;
要将活动角色设置为由SET DEFAULT ROLE语句设置的默认角色,请使用:
SET ROLE DEFAULT;
要设置活动的命名角色,请使用:
SET ROLE granted_role_1, granted_role_2, ...
要撤消特定角色的权限,请使用REVOKE语句。REVOKE声明不仅影响角色,还影响授予角色的任何帐户。
例如,要临时使所有读/写用户只读,您可以crm_write按如下方式更改角色:
REVOKE INSERT, UPDATE, DELETE ON crm.* FROM crm_write;
要恢复权限,您需要按如下方式重新授予权限:
GRANT INSERT, UPDATE, DELETE ON crm.* FOR crm_write;
要删除一个或多个角色,请使用DROP ROLE语句,如下所示:
DROP ROLE role_name, role_name, ...;
与REVOKE语句一样,DROP ROLE语句撤销了授予它的每个用户帐户的角色。
例如,要删除crm_read,crm_write角色,可以使用如下语句:
DROP ROLE crm_read, crm_write;
MySQL将用户帐户视为角色,因此,您可以将用户帐户授予其他用户帐户,例如向用户帐户授予角色。这允许您将用户的权限复制到另一个用户。
假设您需要另一个CRM数据库开发者帐户:
首先,创建新的用户帐户:
CREATE USER crm_dev2@localhost IDENTIFIED BY 'Secure$6275';
其次,将crm_dev1用户帐户的权限复制到crm_dev2用户帐户,如下所示:
GRANT crm_dev1@localhost TO crm_dev2@localhost;
要删除一个或多个用户帐户,请使用以下DROP USER语句:
DROP USER user, [user],...;
要删除用户,请在DROP USER子句后面的格式中指定帐户名称’user_name’@‘host_name’。如果要一次删除多个用户,请使用逗号分隔用户列表。
如果删除不存在的用户帐户,MySQL将发出错误。从MySQL 5.7.8开始,您可以使用IF EXISTS子句指示语句为每个不存在的用户帐户发出警告,而不是发出错误。
DROP USER [IF EXISTS] user, [user],...;
除了删除用户帐户外,DROP USER语句还会删除所有授权表中的所有权限。
要查看MySQL数据库服务器中的所有用户,请使用以下SELECT语句:
SELECT user, host FROM mysql.user;
这是我们的数据库服务器中的用户帐户列表:
+------------------+-----------+ | user | host | +------------------+-----------+ | api@localhost | % | | crm_dev | % | | crm_read | % | | crm_write | % | | remote | % | | rfc | % | | root | % | | superadmin | % | | auditor | localhost | | crm_dev1 | localhost | | crm_read1 | localhost | | crm_write1 | localhost | | crm_write2 | localhost | | dbadmin | localhost | | mysql.infoschema | localhost | | mysql.session | localhost | | mysql.sys | localhost | | super | localhost | +------------------+-----------+ 18 rows in set (0.07 sec)
假设您要删除用户帐户dbadmin@localhost,请使用以下语句:
DROP USER dbadmin@localhost;
mysql.user再次从表中查询数据,您将看到dbadmin@localhost已删除的数据。
SELECT user, host FROM mysql.user;
用户帐户dbadmin@localhost已被删除,如以下结果集所示:
+------------------+-----------+ | user | host | +------------------+-----------+ | api@localhost | % | | crm_dev | % | | crm_read | % | | crm_write | % | | remote | % | | rfc | % | | root | % | | superadmin | % | | auditor | localhost | | crm_dev1 | localhost | | crm_read1 | localhost | | crm_write1 | localhost | | crm_write2 | localhost | | mysql.infoschema | localhost | | mysql.session | localhost | | mysql.sys | localhost | | super | localhost | +------------------+-----------+ 17 rows in set (0.06 sec)
要在单个语句中删除用户’api@localhost’@%和remote用户帐户DROP USER,请使用以下语句:
DROP USER 'api@localhost', remote;
让我们验证删除操作。
SELECT user, host FROM mysql.user;
我们还剩下四个帐户,这两个帐户已被删除。
+------------------+-----------+ | user | host | +------------------+-----------+ | crm_dev | % | | crm_read | % | | crm_write | % | | rfc | % | | root | % | | superadmin | % | | auditor | localhost | | crm_dev1 | localhost | | crm_read1 | localhost | | crm_write1 | localhost | | crm_write2 | localhost | | mysql.infoschema | localhost | | mysql.session | localhost | | mysql.sys | localhost | | super | localhost | +------------------+-----------+ 15 rows in set (0.01 sec)
假设用户帐户已登录并且活动会话正在运行。如果删除用户帐户,则不会停止打开的会话。活动会话将继续,直到用户退出。通常,在这种情况下,您应在执行DROP USER语句之前立即关闭用户的会话。
首先,您需要使用SHOW PROCESSLIST语句来标识用户的进程ID 。
mysql> show processlist;
+----+-----------------+----------------------+-------+---------+---------+------------------------+------------------+
| Id | User | Host | db | Command | Time | State | Info |
+----+-----------------+----------------------+-------+---------+---------+------------------------+------------------+
| 66 | root | localhost:55402 | mysql | Query | 0 | starting | show processlist |
| 78 | dbadmin | localhost:63139 | NULL | Sleep | 115 | | NULL |
+----+-----------------+----------------------+-------+---------+---------+------------------------+------------------+
9 rows in set (0.01 sec)
如您所见,dbadmin@localhost用户帐户具有进程ID 78。
其次,你通过使用来杀死这个过程
KILL 78;
用户帐户dbadmin@localhost收到错误消息:
ERROR 2013 (HY000): Lost connection to MySQL server during query
第三,执行DROP USER语句删除用户帐户dbadmin@localhost:
DROP USER dbadmin@localhost;
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。