允许MySQL用户访问以选择所有视图,但不允许选择表

时间:2015-11-24 23:49:12

标签: mysql view permissions

如何允许用户只选择View,而不是任何基础表?

我知道如何使用

一次一个宏权限

grant select on database.viewName to 'User'

但我试图创建一个用户或配置文件,无论何时创建新视图,都可以访问所有视图而无需逐个运行授权。

在Sequel Pro中,在用户>全局权限和架构权限下,我添加了"显示视图"但这不起作用。

4 个答案:

答案 0 :(得分:1)

我不相信这是可能的。

Mysql GRANT命令采用GRANT permission ON object_type

形式
  

当以下对象是表,存储函数或存储过程时,object_type子句(如果存在)应指定为TABLE,FUNCTION或PROCEDURE。

https://dev.mysql.com/doc/refman/5.7/en/grant.html

我认为没有任何工具只能在视图上授予权限。

请记住,在mysql中,视图只是一个查询,只要您从中进行SELECT,就会执行该查询。它没有自己的数据存储或索引。因此,我希望您必须能够访问基础表才能使视图可用。

答案 1 :(得分:0)

我会展示它,可能需要做一些编辑才能完成。因为我必须在底部附加控制台输出。

模式

create table users
(   userId int auto_increment primary key,
    userName varchar(100) not null
    -- etc
);
insert users(userName) values ('Joe'),('Gertrude');

-- drop table secretdata;
create table SecretData
(   id int auto_increment primary key,
    userId int not null,
    theKey varchar(100) not null,
    theValue varchar(1000) not null,
    key(userId),
    CONSTRAINT fk_sd_users FOREIGN KEY (userId) REFERENCES users(userId)
);
insert secretdata(userId,theKey,theValue) values 
(1,'FB Password','8*&Fjj_anchovieS'),
(1,'Proper response','I love the meal, just like I like it'),
(2,'thing7','goat');

视图

CREATE VIEW userSecrets AS 
    select u.userId,u.userName,s.theKey,s.theValue
    from users u
    join SecretData s
    on s.userId=u.userId;

select * from userSecrets where userId=2; - 目前在这里工作

注意我的数据库名称是so_gibberish

以下是您要查看的授权权利的内容:

GRANT SELECT ON so_gibberish.userSecrets TO 'john'@'host';

↑↑如此配置的用户可以针对视图搜索查询。↑↑

然而,

CREATE USER 'plebian2'@'localhost' IDENTIFIED BY 'mypass';
GRANT SELECT ON so_gibberish.userSecrets TO 'plebian2'@'localhost';

该用户确实有权使用该视图,但 无法直接访问基础表。

控制台输出:

OS Prompt>mysql -u plebian2 -p
Enter password: ******

Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 938
Server version: 5.6.24-log MySQL Community Server (GPL)

mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| so_gibberish       |
+--------------------+
2 rows in set (0.00 sec)

mysql> use so_gibberish;
Database changed

mysql> show tables;
+------------------------+
| Tables_in_so_gibberish |
+------------------------+
| usersecrets            |
+------------------------+
1 row in set (0.00 sec)

mysql> select * from users;
ERROR 1142 (42000): SELECT command denied to user 'plebian2'@'localhost' for table 'users'

mysql> select * from usersecrets;
+--------+----------+-----------------+--------------------------------------+
| userId | userName | theKey          | theValue                             |
+--------+----------+-----------------+--------------------------------------+
|      1 | Joe      | FB Password     | 8*&Fjj_anchovieS                     |
|      1 | Joe      | Proper response | I love the meal, just like I like it |
|      2 | Gertrude | thing7          | goat                                 |
+--------+----------+-----------------+--------------------------------------+
3 rows in set (0.00 sec)

最后,我希望看到名为Access Control for Stored Programs and Views的手册页,看看 Definer 权限如何影响最终州的有效权利。特别是,当定义者具有较少特权而不是使用视图的用户帐户时(一个相当奇怪的条件,但它存在)。

角色

回复你在答案下的评论。

我基本上不满意来自微软世界中存在的mysql中缺少的角色。意思是,有组成角色,用户附加到角色,授权在角色级别(在MSFT世界中)执行。在那里,在MSSQL中,在每个底部创建任何块(存储过程等),将是我在角色级别授予的块。

所以进入mysql,我不得不为用户映射创建该角色。好消息,我只需要做一次。在我运行的块的末尾(如果存在drop / create),它会调用直接操作INFORMATION_SCHEMA.user_privileges之类的东西。但是在非常高的水平上,就像MSFT一样,最终的结果就是我想要的。也就是说,授予权限。

这是一整套蠕虫。但没有它,祝你好运。

grant这样的命令和其他一些命令可以在你自己的引擎下进行。他们几乎没有神圣感。然而,他们在那里保护新手程序员。而那些预示着那些警告标志说小心的人经常会想到,

  

"如何获取数据?我知道它在某处。也许我   不应该在我刚刚做过的事情中做到这一点"

但绝对要修补一些东西,特别是在丢失的数据库(你不关心的)中。更好的是,在你不关心的mysql实例上做。因为我们讨论的是系统范围的影响,而不是在数据库级别。

答案 2 :(得分:0)

此答案已使用 MySQL 8.0.23 验证。

  1. 确保您的视图设置为使用 DEFINER 的凭据运行,这样调用用户就不需要任何 TABLE 权限;不这样做会导致错误。有关 {DEFINER|INVOKER} 参数 see here 的更多详细信息。

  2. 创建您的用户,完全不分配任何权限。

  3. 作为 root 或其他具有足够权限的用户,执行以下命令:

    GRANT SELECT ON <database>.<view_name> TO '<user>'@'<host>';
    

因此,如果我的数据库是 cars 并且视图被称为 service_history,并且我有一个用户 john.doe 需要从任何主机访问它,我将执行以下操作:< /p>

GRANT SELECT ON cars.service_history TO 'john.doe'@'%';

注意 '%' 是如何用来表示任何主机都可以接受的,您可以将其替换为 IP 地址,可能是主机名(但我没有测试过)。

答案 3 :(得分:0)

我通过使用 user() 作为表的过滤器并设置 SQL SECURITY DEFINER,对视图和源表使用单独的架构来实现这一点。

示例代码

CREATE 
    ALGORITHM = UNDEFINED 
    DEFINER = `xxxxxx`@`%` 
    SQL SECURITY DEFINER
VIEW `XX`.`assets` AS
    SELECT 
        `a`.`ID` AS `ID`,
        `a`.`serial_no` AS `serial_no`,
        `a`.`sys_id` AS `sys_id`,
        `a`.`status` AS `status`,
        `a`.`unit_name` AS `unit_name`,
        `a`.`ip` AS `ip`,
        `a`.`tzOffset` AS `tzOffset`
    FROM
        ((`YY`.`Cust_Link_Table` `l`
        JOIN `YY`.`systems` `s` ON ((`l`.`cust_id` = `s`.`cust_id`)))
        JOIN `YY`.`assets` `a` ON ((`s`.`sys_id` = `a`.`sys_id`)))
    WHERE
        (`l`.`db_user` = CONVERT( LEFT(USER(), (LOCATE('@', USER()) - 1)) USING UTF8MB4))