MySQL授予数据库除一张表之外的所有权限

发布于 2024-11-14 18:18:31 字数 534 浏览 8 评论 0原文

我一直无法找到合理的解决方案来实现以下目标:

我希望拥有一个对数据库(或具有相同架构的一系列数据库)拥有所有权限的用户,除了一个表,他们只有 SELECT 权限。

本质上,我希望用户可以自由控制数据库,但不能更新特定的表。

到目前为止,我已经尝试过,但没有成功:

  • 授予该数据库(db_name.*)的所有权限,然后专门授予对该所需表的选择权限(希望它会覆盖“全部”,我知道很愚蠢)。 授予该数据库(db_name.*)的所有权限

  • 授予该数据库 (db_name.*) 的所有权限,然后撤销插入、更新和删除。但这会产生一个错误,指出 db_name.table_name 没有授予规则。

根据我收集到的信息,我必须单独授予数据库每个表的所有权限(只读表除外)。

请有人告诉我有一个更简单的方法

注意:我正在运行 MySQL 5.1。 Ubuntu 10.04 上提供了最新版本。

I've been unable to find a reasonable solution to achieve the following:

I wish to have a user that has ALL privileges on a database (or series of databases with the same schema), except for one table, to which they will only have SELECT privileges.

Essentially I want the user to have free reign over a database but not to be able to update a specific table.

So far I have tried, to no avail:

  • Granting all privileges on that database (db_name.*) and then specifically granting only select privileges on that desired table (hoping it would overwrite the "all", stupid I know).

  • Granting all privileges on that database (db_name.*) then revoking insert, update, and delete. But this produced an error saying there was no grant rule for db_name.table_name.

From what I've been able to gather I'll have to individually grant all privileges on each table of the database except the read only table.

Please someone tell me there is a easier way

Note: I'm running MySQL 5.1. The latest available on Ubuntu 10.04.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

夕嗳→ 2024-11-21 18:18:31

我知道这是一篇旧帖子,但我想我应该添加到 @tdammers 问题以供其他人查看。您还可以对 information_schema.tables 执行 SELECT CONCAT 来创建授予命令,而不必编写单独的脚本。

首先撤销该数据库的所有权限:

REVOKE ALL PRIVILEGES ON db.* FROM user@localhost;  

然后创建 GRANT 语句:

SELECT CONCAT("GRANT UPDATE ON db.", table_name, " TO user@localhost;")
FROM information_schema.TABLES
WHERE table_schema = "YourDB" AND table_name <> "table_to_skip";

将结果复制并粘贴到 MySQL 客户端并全部运行。

I know this is an old post, but I thought I'd add on to @tdammers question for others to see. You can also perform a SELECT CONCAT on information_schema.tables to create your grant commands, and not have to write a separate script.

First revoke all privileges from that db:

REVOKE ALL PRIVILEGES ON db.* FROM user@localhost;  

Then create your GRANT statements:

SELECT CONCAT("GRANT UPDATE ON db.", table_name, " TO user@localhost;")
FROM information_schema.TABLES
WHERE table_schema = "YourDB" AND table_name <> "table_to_skip";

Copy and paste the results into your MySQL client and run them all.

梦冥 2024-11-21 18:18:31

AFAIK,是的,您需要为每个表单独授予。但是嘿,你那里有一台电脑。计算机非常擅长为您自动执行重复性任务,所以为什么不编写一个脚本来执行以下操作:

  1. 获取数据库中所有表的列表 (SHOW TABLES;)
  2. 对于数据库中的每个项目列表,授予所有权限
  3. 撤销对特殊表的权限

或者,或者:
2. 对于列表中的每一项,检查是否是特殊表;如果不是,则授予所有权限

我不提供代码的原因是它可以用任何具有 MySQL 功能的脚本语言(甚至是 shell 脚本)来完成;使用您最舒服的方式。

AFAIK, yes, you need to grant individually per table. But hey, you have a computer there. Computers are great at automating repetitive tasks for you, so why don't you make a script that does the following:

  1. Get a list of all tables in the database (SHOW TABLES;)
  2. For each item on the list, grant all permissions
  3. Revoke permissions on the special table

Or, alternatively:
2. For each item on the list, check if it is the special table; if it's not, grant all permissions

The reason I'm not giving code is that it can be done in any scripting language with MySQL facilities, even shell script; use what you're most comfortable using.

倚栏听风 2024-11-21 18:18:31

这是我用来在 MariaDB 中授予角色的草稿。
也许设置一个事件会让事情变得更酷:-)

DELIMITER $

DROP PROCEDURE IF EXISTS refreshRoles $
CREATE PROCEDURE refreshRoles ()
  COMMENT 'Grant SELECT on new databases/tables, revoke on deleted'
BEGIN
  DECLARE done BOOL;
  DECLARE db VARCHAR(128);
  DECLARE tb VARCHAR(128);
  DECLARE rl VARCHAR(128);
  DECLARE tables CURSOR FOR
    SELECT table_schema, table_name, '_bob_live_sg' FROM information_schema.tables
    WHERE table_schema LIKE '%bob\_live\_sg' AND
      (  false
      OR table_name LIKE 'bundle%'
      OR table_name LIKE 'cart%'
      OR table_name LIKE 'catalog%'
      OR table_name LIKE 'url%'
      );

  DECLARE CONTINUE HANDLER FOR SQLSTATE '02000' SET done=true;

  CREATE ROLE IF NOT EXISTS '_bob_live_sg';
  REVOKE ALL, GRANT OPTION FROM '_bob_live_sg';

  OPEN tables;
  SET done = false;
  grant_loop: LOOP
    FETCH tables INTO db, tb, rl;
    IF done THEN
      LEAVE grant_loop;
    END IF;
    SET @g = CONCAT('GRANT SELECT ON `', db, '`.`', tb, '` TO ', rl);
    PREPARE g FROM @g;
    EXECUTE g;
    DEALLOCATE PREPARE g;
  END LOOP;
  CLOSE tables;
END $

DELIMITER ;

CALL refreshRoles;

Here is a draft of what I use to grant roles in MariaDB.
Maybe setting an EVENT would make it more cool :-)

DELIMITER $

DROP PROCEDURE IF EXISTS refreshRoles $
CREATE PROCEDURE refreshRoles ()
  COMMENT 'Grant SELECT on new databases/tables, revoke on deleted'
BEGIN
  DECLARE done BOOL;
  DECLARE db VARCHAR(128);
  DECLARE tb VARCHAR(128);
  DECLARE rl VARCHAR(128);
  DECLARE tables CURSOR FOR
    SELECT table_schema, table_name, '_bob_live_sg' FROM information_schema.tables
    WHERE table_schema LIKE '%bob\_live\_sg' AND
      (  false
      OR table_name LIKE 'bundle%'
      OR table_name LIKE 'cart%'
      OR table_name LIKE 'catalog%'
      OR table_name LIKE 'url%'
      );

  DECLARE CONTINUE HANDLER FOR SQLSTATE '02000' SET done=true;

  CREATE ROLE IF NOT EXISTS '_bob_live_sg';
  REVOKE ALL, GRANT OPTION FROM '_bob_live_sg';

  OPEN tables;
  SET done = false;
  grant_loop: LOOP
    FETCH tables INTO db, tb, rl;
    IF done THEN
      LEAVE grant_loop;
    END IF;
    SET @g = CONCAT('GRANT SELECT ON `', db, '`.`', tb, '` TO ', rl);
    PREPARE g FROM @g;
    EXECUTE g;
    DEALLOCATE PREPARE g;
  END LOOP;
  CLOSE tables;
END $

DELIMITER ;

CALL refreshRoles;
冬天的雪花 2024-11-21 18:18:31

不幸的是,MySQL 中有内置的自然方法来执行选择性/特殊任务。

您可以使用下面的脚本(Linux 控制台 bash 脚本)

#!/bin/bash

# Define the database and root authorization details
db_host='localhost'
db_name='adhoctuts'
db_user='root'
db_pass='Adhoctuts2018#'

# Define the query to get the needed tables
table_list=$(mysql -h $db_host -u $db_user -p"$db_pass" -se "select concat(table_schema,'.',table_name) from information_schema.tables where table_schema='$db_name' and table_name not like 'tbl1' AND table_name not like '\_\_%';" $db_name | cut -f1)

# Convert the query result into the array
table_arr=(${table_list//,/ })

# Declare the associative array of the users as username=>password pair
# e.g: declare -A user_list=(["'user1'"]="pass1" ["'user2'"]="pass2")
# In our case there is a single user
declare -A user_list=(["'aht_r'@'localhost'"]="Adhoctuts2018#")
for user in "${!user_list[@]}"
do
    pass=${user_list[$user]}
    # Recreate user
    mysql -h $db_host -u $db_user -p"$db_pass" -se "drop user if exists $user; create user $user identified by '$pass';"

    # Provide SELECT privilege
    mysql -h $db_host -u $db_user -p"$db_pass" -se "revoke all privileges, grant option from $user;" $db_name
    mysql -h $db_host -u $db_user -p"$db_pass" -se "grant usage on $db_name.* TO $user;" $db_name
    for tbl in "${table_arr[@]}"; do
        echo "grant select on $tbl TO $user"
        mysql -h $db_host -u $db_user -p"$db_pass" -se "grant select on $tbl TO $user;" $db_name    
    done
done

如果您有 Windows 控制台,您可以使用以下 .bat 文件:

@ECHO OFF
%= Define the database and root authorization details =% 
set db_host=192.168.70.138
set db_name=adhoctuts
set db_user=adhoctuts
set db_pass=Adhoctuts2018#

mysql -h %db_host% -u %db_user% -p"%db_pass%" -se "select concat(table_schema,'.',table_name) from information_schema.tables where table_schema='%db_name%' and table_name not like 'tbl1' AND table_name not like '\_\_%%';" %db_name% > tbls

setlocal EnableDelayedExpansion
set user_cnt=2
set user[1]='Adhoctuts1'@'192.168.%%.%%'
set pass[1]=Adhoctuts1_2018#
set user[2]='Adhoctuts2'@'192.168.%%.%%'
set pass[2]=Adhoctuts2_2018#

set i=1
:loop
    set user=!user[%i%]!
    set pass=!pass[%i%]!
    mysql -h %db_host% -u %db_user% -p"%db_pass%" -se "drop user if exists %user% ; create user %user%  identified by '%pass%';"
    mysql -h %db_host% -u %db_user% -p"%db_pass%" -se "revoke all privileges, grant option from %user%;" %db_name%      
    for /F "usebackq delims=" %%a in ("tbls") do (
        mysql -h %db_host% -u %db_user% -p"%db_pass%" -se "grant select on %%a TO %user%;" %db_name%
    )
    if %i% equ %user_cnt% goto :end_loop
    set /a i=%i%+1
goto loop

:end_loop
del /f tbls

首先编写查询以获取所需表的列表,接下来定义您想要的用户列表授予访问权限。每次数据库结构发生变化时,您都需要执行该脚本。我为 MySQL 选择性/特殊任务创建了单独的简短教程。

https://adhoctuts.com/mysql-selective-exceptional-permissions -and-backup-restore/

https://youtu.be/8fWQbtIISdc

Unfortunately, there is built-in natural ways in MySQL to perform selective/exceptional tasks.

You could use below script(linux console bash script)

#!/bin/bash

# Define the database and root authorization details
db_host='localhost'
db_name='adhoctuts'
db_user='root'
db_pass='Adhoctuts2018#'

# Define the query to get the needed tables
table_list=$(mysql -h $db_host -u $db_user -p"$db_pass" -se "select concat(table_schema,'.',table_name) from information_schema.tables where table_schema='$db_name' and table_name not like 'tbl1' AND table_name not like '\_\_%';" $db_name | cut -f1)

# Convert the query result into the array
table_arr=(${table_list//,/ })

# Declare the associative array of the users as username=>password pair
# e.g: declare -A user_list=(["'user1'"]="pass1" ["'user2'"]="pass2")
# In our case there is a single user
declare -A user_list=(["'aht_r'@'localhost'"]="Adhoctuts2018#")
for user in "${!user_list[@]}"
do
    pass=${user_list[$user]}
    # Recreate user
    mysql -h $db_host -u $db_user -p"$db_pass" -se "drop user if exists $user; create user $user identified by '$pass';"

    # Provide SELECT privilege
    mysql -h $db_host -u $db_user -p"$db_pass" -se "revoke all privileges, grant option from $user;" $db_name
    mysql -h $db_host -u $db_user -p"$db_pass" -se "grant usage on $db_name.* TO $user;" $db_name
    for tbl in "${table_arr[@]}"; do
        echo "grant select on $tbl TO $user"
        mysql -h $db_host -u $db_user -p"$db_pass" -se "grant select on $tbl TO $user;" $db_name    
    done
done

If you have a windows console you could use the following .bat file:

@ECHO OFF
%= Define the database and root authorization details =% 
set db_host=192.168.70.138
set db_name=adhoctuts
set db_user=adhoctuts
set db_pass=Adhoctuts2018#

mysql -h %db_host% -u %db_user% -p"%db_pass%" -se "select concat(table_schema,'.',table_name) from information_schema.tables where table_schema='%db_name%' and table_name not like 'tbl1' AND table_name not like '\_\_%%';" %db_name% > tbls

setlocal EnableDelayedExpansion
set user_cnt=2
set user[1]='Adhoctuts1'@'192.168.%%.%%'
set pass[1]=Adhoctuts1_2018#
set user[2]='Adhoctuts2'@'192.168.%%.%%'
set pass[2]=Adhoctuts2_2018#

set i=1
:loop
    set user=!user[%i%]!
    set pass=!pass[%i%]!
    mysql -h %db_host% -u %db_user% -p"%db_pass%" -se "drop user if exists %user% ; create user %user%  identified by '%pass%';"
    mysql -h %db_host% -u %db_user% -p"%db_pass%" -se "revoke all privileges, grant option from %user%;" %db_name%      
    for /F "usebackq delims=" %%a in ("tbls") do (
        mysql -h %db_host% -u %db_user% -p"%db_pass%" -se "grant select on %%a TO %user%;" %db_name%
    )
    if %i% equ %user_cnt% goto :end_loop
    set /a i=%i%+1
goto loop

:end_loop
del /f tbls

First you write the query to get the list of the needed tables, next you define the list of users you want to grant access for. You need to execute the script every time the database structure changes. I have created separate short tutorial for MySQL selective/exceptional tasks.

https://adhoctuts.com/mysql-selective-exceptional-permissions-and-backup-restore/

https://youtu.be/8fWQbtIISdc

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文