我正在使用用户“feedbackdev”连接到 MySQL,但查询是使用“feedback”执行的,它是同一服务器上的另一个用户。
root@board:~# mysql -u feedbackdev -p feedbackdev
Enter password:
mysql> select user();
+-----------------------+
| user() |
+-----------------------+
| feedbackdev@localhost |
+-----------------------+
mysql> select rating, COUNT(*) AS rating_count from order_feedback_view where feedback_created_at >= '2024-10-26 09:01:29' group by rating;
ERROR 1143 (42000): SELECT command denied to user 'feedback'@'localhost' for column 'source_id' in table 'orders'
以下是用户可获得的赠款
mysql> show grants for 'feedbackdev'@'localhost';
+----------------------------------------------------------------------+
| Grants for feedbackdev@localhost |
+----------------------------------------------------------------------+
| GRANT PROCESS, SUPER ON *.* TO `feedbackdev`@`localhost` |
| GRANT SET_USER_ID ON *.* TO `feedbackdev`@`localhost` |
| GRANT ALL PRIVILEGES ON `feedbackdev`.* TO `feedbackdev`@`localhost` |
+----------------------------------------------------------------------+
3 rows in set (0.00 sec)
mysql> show grants for 'feedback'@'localhost';
+---------------------------------------------------------------------------+
| Grants for feedback@localhost |
+---------------------------------------------------------------------------+
| GRANT PROCESS, SUPER, REPLICATION CLIENT ON *.* TO `feedback`@`localhost` |
| GRANT FLUSH_TABLES ON *.* TO `feedback`@`localhost` |
| GRANT ALL PRIVILEGES ON `feedback`.* TO `feedback`@`localhost` |
+---------------------------------------------------------------------------+
3 rows in set (0.00 sec)
MySQL 版本 8.0.40
MySQL(以及其他 RDBMS)中的视图可用于对数据进行有限的访问,否则访问视图的用户将无法访问这些数据。为此,定义
SQL SECURITY
中有一个子句,可以将其设置为并将其设置为除打算从视图中选择的用户之外的某个用户。然后,必须仔细构建视图查询,以免泄露任何敏感信息,然后对其返回的数据的访问由视图本身上设置的权限控制。(它与存储过程和函数的工作方式相同,用于类似的目的。)DEFINER
当您通过 导出 VIEW 时,有一个注意事项
mysqldump
:它会导出定义中存储的实际DEFINER
值,并在重新加载时恢复该值,即使它是作为另一个用户加载的,或加载到属于另一个用户的数据库中。这就是您的情况,旧的定义者无权访问属于新用户的数据,因此当您尝试调用视图时,其访问被拒绝。有两种方法可以解决这个问题。第一种方法是不使用 转储定义器
mysqldump
,而是使用选项。然而,在重新加载转储期间,定义--skip-definer
器将被重新设置给重新加载它的用户。第二种方法是使用 重新定义视图
SQL SECURITY INVOKER
,在这种情况下,视图的查询将始终以调用视图本身的用户的权限执行。对于这种情况,这将是更干净的解决方案,因为从逻辑上讲,这个视图似乎不应该用于提供对受保护信息的有限访问,它一开始就不应该用定义者安全性来定义。