Mysql 访问视图却报ERROR 1356 (HY000)错误

1.适用范围

MYSQL 8.0

2.问题概述

普通业务用户,在自己用户下创建了表和视图,表可以正常访问,而访问视图却报ERROR 1356 (HY000)错误,测试如下:

mysql> desc asher_test ;
+-----------+-------------+------+-----+---------+-------+
| Field     | Type        | Null | Key | Default | Extra |
+-----------+-------------+------+-----+---------+-------+
| name      | varchar(50) | YES  |     | NULL    |       |
| purchased | date        | YES  |     | NULL    |       |
+-----------+-------------+------+-----+---------+-------+
2 rows in set (0.00 sec)

mysql> select * from asher_test;
+-------------+------------+
| name        | purchased  |
+-------------+------------+
| fullbackup  | 2022-11-27 |
+-------------+------------+
1 row in set (0.00 sec)

mysql> select * from ray ;
ERROR 1356 (HY000): View 'drm.ray' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them



3.问题原因

3.1.通过root 用户查询问题仍然存在,且所有视图问题都是相同的。

mysql> select * from ray ;
ERROR 1356 (HY000): View 'drm.ray' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them

3.2.root 自己的创建的视图可以正常访问


CREATE VIEW asher_v2   
     (v_name,v_purchased )
     AS SELECT name, purchased
     FROM asher_test;

mysql> select * from asher_v2   ;
+-------------+-------------+
| v_name      | v_purchased |
+-------------+-------------+
| fullbackup  | 2022-11-27  |
+-------------+-------------+
1 row in set (0.00 sec)

drop VIEW asher_v2   ;

3.3.查看用户权限

mysql> show grants for `drm_admin`@`%` ;
+------------------------------------------------------------------------------------+
| Grants for drm_admin@%                                                             |
+------------------------------------------------------------------------------------+
| GRANT USAGE ON *.* TO `drm_admin`@`%`                                              |
| GRANT SELECT ON `performance_schema`.`user_variables_by_thread` TO `drm_admin`@`%` |
| GRANT `drm_admin_role`@`%` TO `drm_admin`@`%`                                      |
+------------------------------------------------------------------------------------+
3 rows in set (0.00 sec)

mysql> show grants for drm_admin_role ;
+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Grants for drm_admin_role@%                                                                                                                                                                                                         |
+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| GRANT PROCESS, CREATE USER ON *.* TO `drm_admin_role`@`%`                                                                                                                                                                           |
| GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, REFERENCES, INDEX, ALTER, CREATE TEMPORARY TABLES, EXECUTE, 
CREATE VIEW, SHOW VIEW, CREATE ROUTINE, ALTER ROUTINE, TRIGGER ON `drm`.* TO `drm_admin_role`@`%` WITH GRANT OPTION |
|                                                                                                                                                         |
+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
3 rows in set (0.00 sec)

3.4.以为是权限问题,重新授权问题仍然存在

grant all privileges on drm.* to drm_admin_role ;

CREATE VIEW asher_v3  
     (v_name,v_purchased )
     AS SELECT name, purchased
     FROM asher_test;

mysql> select * from asher_v3   ;
ERROR 1356 (HY000): View 'drm.asher_v3' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them

3.5.创建普通用户直接授权,可以正常查询

create user test@'%' identified by 'xxxxxx';
Query OK, 0 rows affected (0.00 sec)

GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, REFERENCES, INDEX, ALTER, CREATE TEMPORARY TABLES, EXECUTE, CREATE VIEW, SHOW VIEW, CREATE ROUTINE, ALTER ROUTINE, TRIGGER ON `drm`.* TO test@'%' WITH GRANT OPTION ;


CREATE VIEW asher_v4
     AS SELECT name, purchased
     FROM asher_test;

select * from asher_v4 ;
mysql> select * from asher_v4 ;
+-------------+------------+
| name        | purchased  |
+-------------+------------+
| fullbackup  | 2022-11-27 |
+-------------+------------+
1 row in set (0.00 sec)

3.6.通过角色授权,问题存在


mysql> show grants for  test@'%' ;
+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Grants for test@%                                                                                                                                                                                                         |
+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| GRANT USAGE ON *.* TO `test`@`%`                                                                                                                                                                                          |
| GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, REFERENCES, INDEX, ALTER, CREATE TEMPORARY TABLES, EXECUTE, CREATE VIEW, SHOW VIEW, CREATE ROUTINE, ALTER ROUTINE, TRIGGER ON `drm`.* TO `test`@`%` WITH GRANT OPTION |
+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
2 rows in set (0.00 sec)

revoke   SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, REFERENCES, INDEX, ALTER, CREATE TEMPORARY TABLES, EXECUTE, CREATE VIEW, SHOW VIEW, CREATE ROUTINE, ALTER ROUTINE, TRIGGER ON `drm`.* from `test`@`%` ;


mysql> show grants for  test@'%' ;
+--------------------------------------------------------+
| Grants for test@%                                      |
+--------------------------------------------------------+
| GRANT USAGE ON *.* TO `test`@`%`                       |
| GRANT USAGE ON `drm`.* TO `test`@`%` WITH GRANT OPTION |
+--------------------------------------------------------+
2 rows in set (0.01 sec)

GRANT  `drm_admin_role`@`%` TO test@'%'   ;

  show grants for  test@'%' ;
+--------------------------------------------------------+
| Grants for test@%                                      |
+--------------------------------------------------------+
| GRANT USAGE ON *.* TO `test`@`%`                       |
| GRANT USAGE ON `drm`.* TO `test`@`%` WITH GRANT OPTION |
| GRANT `drm_admin_role`@`%` TO `test`@`%`               |
+--------------------------------------------------------+
3 rows in set (0.00 sec)


drop VIEW asher_v5 ; 
  CREATE VIEW asher_v5
        AS SELECT name, purchased
        FROM asher_test;
 

mysql> select * from asher_v5 ;
ERROR 1356 (HY000): View 'drm.asher_v5' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them
同样的权限给角色 不能解决问题 

3.7.重建角色问题仍然存在

revoke `drm_admin_role`@`%` from  `test`@`%` ; 
create role test_role ; 

GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, REFERENCES, INDEX, ALTER, CREATE TEMPORARY TABLES, EXECUTE, CREATE VIEW, SHOW VIEW, CREATE ROUTINE, ALTER ROUTINE, TRIGGER ON `drm`.* TO test_role  WITH GRANT OPTION ;

mysql> show grants for test_role ;
+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Grants for test_role@%                                                                                                                                                                                                         |
+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| GRANT USAGE ON *.* TO `test_role`@`%`                                                                                                                                                                                          |
| GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, REFERENCES, INDEX, ALTER, CREATE TEMPORARY TABLES, EXECUTE, CREATE VIEW, SHOW VIEW, CREATE ROUTINE, ALTER ROUTINE, TRIGGER ON `drm`.* TO `test_role`@`%` WITH GRANT OPTION |
+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
2 rows in set (0.00 sec)

mysql> show grants for drm_admin_role ;
+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Grants for drm_admin_role@%                                                                                                                                                                                                         |
+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| GRANT PROCESS, CREATE USER ON *.* TO `drm_admin_role`@`%`                                                                                                                                                                           |
| GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, REFERENCES, INDEX, ALTER, CREATE TEMPORARY TABLES, EXECUTE, CREATE VIEW, SHOW VIEW, CREATE ROUTINE, ALTER ROUTINE, TRIGGER ON `drm`.* TO `drm_admin_role`@`%` WITH GRANT OPTION |
+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
2 rows in set (0.00 sec)

mysql> 

grant test_role  to  `test`@`%` ;
show grants for  `test`@`%` ;
+--------------------------------------------------------+
| Grants for test@%                                      |
+--------------------------------------------------------+
| GRANT USAGE ON *.* TO `test`@`%`                       |
| GRANT USAGE ON `drm`.* TO `test`@`%` WITH GRANT OPTION |
| GRANT `test_role`@`%` TO `test`@`%`                    |
+--------------------------------------------------------+
3 rows in set (0.00 sec)

drop VIEW asher_v6 ; 
  CREATE VIEW asher_v6
        AS SELECT name, purchased
        FROM asher_test;

3.8.将视图 definer改成invoker的

# 把视图 definer改成invoker的 试试
mysql> show create view  asher_v6;
+--------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------+----------------------+
| View   | Create View                                                                                                                                                                  | character_set_client | collation_connection |
+--------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------+----------------------+
| asher_v6 | CREATE ALGORITHM=UNDEFINED DEFINER=`test`@`%` SQL SECURITY DEFINER VIEW `asher_v6` AS select `asher_test`.`name` AS `name`,`asher_test`.`purchased` AS `purchased` from `asher_test` | utf8mb4              | utf8mb4_0900_ai_ci   |
+--------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------+----------------------+
1 row in set (0.00 sec)


CREATE ALGORITHM=UNDEFINED DEFINER=`test`@`%` SQL SECURITY INVOKER VIEW `asher_v7` AS select `asher_test`.`name` AS `name`,`asher_test`.`purchased` AS `purchased` from `asher_test`

mysql> select * from asher_v7 ;
+-------------+------------+
| name        | purchased  |
+-------------+------------+
| fullbackup  | 2022-11-27 |
+-------------+------------+
1 row in set (0.00 sec)


# 更改现有视图,将视图 definer改成invoker

ALTER
ALGORITHM=UNDEFINED
DEFINER=`test`@`%`
SQL SECURITY INVOKER VIEW `asher_v6` AS select `asher_test`.`name` AS `name`,`asher_test`.`purchased` AS `purchased` from `asher_test` ;
 

 select * from asher_v6 ;
+-------------+------------+
| name        | purchased  |
+-------------+------------+
| fullbackup  | 2022-11-27 |
+-------------+------------+
1 row in set (0.00 sec)

4.解决方案

通过以肯方案测试,得知在创建视图或者是存储过程的时候,是需要定义安全验证方式的(也就是安全性SQL SECURITY),其值可以为definer或invoker,表示在执行过程中,使用谁的权限来执行。
definer:由definer(定义者)指定的用户的权限来执行
invoker:由调用这个视图(存储过程)的用户的权限来执行
但是我们这里是用了角色,所以第如果是用的默认definer,就不能用角色,而是直接授权。如果要用角色,就需要将definer改为角色的名字,而不是用户的名字。

4.1 方案一,更definer改成invoker

这里我们可以直接将视图 definer改成invoker ,更改方案如下:

4.1.1直接更改现有视图,将视图 definer改成invoker

ALTER
ALGORITHM=UNDEFINED
DEFINER=`test`@`%`
SQL SECURITY INVOKER VIEW `asher_v6` AS select `asher_test`.`name` AS `name`,`asher_test`.`purchased` AS `purchased` from `asher_test` ;
 

4.1.2 创建视图的时候,将视图 definer改成invoker

CREATE ALGORITHM=UNDEFINED DEFINER=`test`@`%` SQL SECURITY INVOKER VIEW `asher_v7` AS select `asher_test`.`name` AS `name`,`asher_test`.`purchased` AS `purchased` from `asher_test`

4.2 方案二,更改DEFINER为角色名

视图默认为definer情况下,指定definer改为角色的名字
直接授权在上面的2.5测试中,是可以执行的,所以这里我们将definer改为角色的名字

mysql> select * from asher_v5 ;
ERROR 1356 (HY000): View 'drm.asher_v5' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them
mysql> show create view asher_v5 ;
+--------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------+----------------------+
| View   | Create View                                                                                                                                                                  | character_set_client | collation_connection |
+--------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------+----------------------+
| asher_v5 | CREATE ALGORITHM=UNDEFINED DEFINER=`test`@`%` SQL SECURITY DEFINER VIEW `asher_v5` AS select `asher_test`.`name` AS `name`,`asher_test`.`purchased` AS `purchased` from `asher_test` | utf8mb4              | utf8mb4_0900_ai_ci   |
+--------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------+----------------------+
1 row in set (0.00 sec)




ALTER
ALGORITHM=UNDEFINED
DEFINER=`test_role`@`%`
SQL SECURITY DEFINER VIEW `asher_v5` AS select `asher_test`.`name` AS `name`,`asher_test`.`purchased` AS `purchased` from `asher_test` ;
 
mysql> show create view asher_v5 ;
+--------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------+----------------------+
| View   | Create View                                                                                                                                                                       | character_set_client | collation_connection |
+--------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------+----------------------+
| asher_v5 | CREATE ALGORITHM=UNDEFINED DEFINER=`test_role`@`%` SQL SECURITY DEFINER VIEW `asher_v5` AS select `asher_test`.`name` AS `name`,`asher_test`.`purchased` AS `purchased` from `asher_test` | utf8mb4              | utf8mb4_0900_ai_ci   |
+--------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------+----------------------+
1 row in set (0.00 sec)

mysql> select * from asher_v5 ;
+-------------+------------+
| name        | purchased  |
+-------------+------------+
| fullbackup  | 2022-11-27 |
+-------------+------------+
1 row in set (0.00 sec)


5.参考文档

https://dev.mysql.com/doc/refman/8.0/en/create-view.html
https://dev.mysql.com/doc/refman/8.0/en/stored-objects-security.html

posted @ 2023-01-03 23:13  www.cqdba.cn  阅读(2082)  评论(0编辑  收藏  举报