限制对MySQL中行的子集的访问

时间:2012-04-16 05:38:47

标签: mysql security

我是数据库noob :-(如果我有一个像这样设计的简单表:

CREATE TABLE IF NOT EXISTS picture
(
ID INT NOT NULL AUTO_INCREMENT,
userID INT NOT NULL,
name VARCHAR(150),

PRIMARY KEY(ID),
FOREIGN KEY (userID) REFERENCES user(ID)
)ENGINE=InnoDB

并描述,例如,像:

+----+--------+------+
| ID | userID | name |
+----+--------+------+
|  1 |      1 | john |
|  2 |      1 | jack |
|  3 |      2 | amir |
|  4 |      2 | chan |
|  5 |      2 | jose |
|  6 |      3 | jane |
|  7 |      3 | buba |
+----+--------+------+

我如何设计满足以下两个约束条件的数据库:

  1. 用户123可以向pictures表添加新条目。
  2. 用户123可以修改仅包含userID s 1 {{1}的行 }和2,respecitvely
  3. 我知道这可能是非常重要的,所以请随意提出任何其他问题,我会相应地编辑这个问题。

2 个答案:

答案 0 :(得分:2)

汲取this answer我把它放在一起:

delimiter //
CREATE TRIGGER trig_picture BEFORE UPDATE ON picture
FOR EACH ROW
BEGIN
    DECLARE dummy INT;
    IF NOT EXISTS (select ID from users where ID = OLD.userID and name = (SELECT SUBSTRING_INDEX(USER(), '@', 1))) THEN
        SET NEW=(SELECT CONCAT("Access Denied for user ", SUBSTRING_INDEX(USER(), '@', 1), "; uid ", OLD.userID));
    END IF;
END;//
delimiter ;

这假设您有一个users表,其中包含一些条目:

CREATE TABLE IF NOT EXISTS users ( ID INT NOT NULL AUTO_INCREMENT PRIMARY KEY, name VARCHAR(150) );
insert into users values (1, 'adam');
insert into users values (2, 'bob');
insert into users values (3, 'clark');

这假设users表中的名称与SELECT SUBSTRING_INDEX(USER(), '@', 1)返回的数据库用户名相匹配。

另请注意,这只会阻止更新发生。您还必须创建其他插入/删除触发器以防止创建/删除条目。

最后,这并不妨碍某人更改图片表中条目的userID,实际上是将其从进一步编辑中锁定。如果这对您很重要,您可以在触发器中添加额外的检查。

答案 1 :(得分:1)

对于第一项,您只需为用户1,2和3授予对图片表的INSERT权限。

对于第二项,您可以执行以下操作:

一个。创建一个包含userID和数据库登录之间映射的附加表(db_logins)。

+----+--------+--------------+
| ID | userID | db_loginname |
+----+--------+--------------+
|  1 |      1 | dbLogin1     |
|  2 |      2 | dbLogin2     |
|  3 |      3 | dbLogin3     |
+----+--------+--------------+

B中。每当进行更新时,都要将检查db_loginname添加到WHERE子句中。 UPDATE语句看起来像这样(我目前无权访问MySQL实例,因此我无法验证语法):

UPDATE pictures
SET name = 'new name'
FROM pictures
INNER JOIN db_logins 
    ON pictures.userID = db_logins.userID
WHERE name = 'buba' 
   AND db_loginname = user()