You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

MySQL 8.0.18:数据库全权限角色无法让用户创建对应数据库

MySQL角色权限与直接用户权限的差异解析及解决方案

这个行为符合预期吗?

绝对符合,这不是MySQL的bug,而是它8.0版本里角色和直接用户权限的检查机制不一样导致的。

咱们来理清楚差异点:

  • 当你直接给joe授予ALL ON joe_db.*时,哪怕joe_db还没创建,MySQL也会把这条权限写到mysql.db系统表中存着。等你用joe去创建joe_db的时候,权限检查会看到系统表已经有这个用户对该数据库的权限记录,就直接允许创建了。你当时看到的那个1 warning只是提醒你joe_db还不存在,但不影响权限规则的保存。
  • 但用角色joe_role授同样权限的时候,角色的权限不会提前写入mysql.db表——只有当joe_db真的存在了,角色的权限才会生效。所以在数据库没创建的时候,激活角色的joe根本没有创建这个库的权限,自然就报错了。

不授全局ALL权限,怎么让角色能创建指定数据库?

核心是要给角色单独加创建数据库的权限,遵循最小权限原则,别一股脑给全局ALL。具体操作分两步:

正确的授权操作

-- 创建角色
CREATE ROLE 'joe_role';

-- 只给创建数据库的全局权限(仅满足创建需求,不额外授权)
GRANT CREATE ON *.* TO 'joe_role';

-- 再给目标数据库的所有对象权限
GRANT ALL ON `joe_db`.* TO 'joe_role';

-- 把角色分配给用户
GRANT `joe_role` TO `joe`@'localhost';

验证权限

$ mysql -ujoe -p1234 -hlocalhost
mysql> SET ROLE `joe_role`;
Query OK, 0 rows affected (0.00 sec)

mysql> CREATE DATABASE `joe_db`;
Query OK, 1 row affected (0.01 sec)

mysql> DROP DATABASE `joe_db`;
Query OK, 0 rows affected (0.01 sec)

更精细的权限控制(可选)

如果想严格限制joe只能创建joe_db这一个库,MySQL本身没法直接指定“仅允许创建某一个库”的权限,但可以用触发器实现拦截:

  1. 先按上面的步骤给角色全局CREATE权限
  2. 用超级用户创建触发器,拦截非joe_db的创建请求:
DELIMITER //
CREATE TRIGGER restrict_joe_database
BEFORE CREATE ON SCHEMA
FOR EACH STATEMENT
BEGIN
    IF CURRENT_USER() = 'joe@localhost' AND SCHEMA_NAME() != 'joe_db' THEN
        SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = '你只能创建joe_db数据库';
    END IF;
END //
DELIMITER ;

这样既满足了创建指定库的需求,又不会给用户过度授权。


内容的提问来源于stack exchange,提问作者porkbrain

火山引擎 最新活动