我们正在使用几张大致如下所示的表:
| ID | DepartmentId | Data |
| 1 | 1 | ... |
| 2 | 1 | ... |
| 3 | 2 | ... |
| 4 | 3 | ... |
| 5 | 2 | ... |
我们大约有200个MySQL用户,每个用户都与一个或多个部门关联(通过一个简单的Username / DepartmentId表)
我们希望将访问(SELECT,UPDATE)限制为仅对每个用户正确的记录子集.
例如,一个
SELECT * FROM DataTable
与部门1和3关联的用户“ Bob”应返回记录1、2和4.
与部门1相关联的用户“ Alice”的同一查询应仅返回记录1和2.
做到这一点的最佳方法是什么?
解决方法:
MySQL没有基于行的权限.最好的办法是构造视图以显示某些记录.一种简单的方法是将一个具有mysql用户名的映射表添加到他们有权访问的部门ID上,并让该映射表上的视图选择与原始视图(仅限于当前发出请求的用户)结合在一起.您可以使用CURRENT_USER()获取当前的mysql用户.
然后将用户限制为视图,而不是原始表.
以下是步骤的细分:
CREATE TABLE `mysqluser_dept` (
`mysqluser` varchar(255) NOT NULL DEFAULT '',
`DepartmentId` int(11) NOT NULL DEFAULT '0',
PRIMARY KEY (`mysqluser`,`DepartmentId`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE VIEW filtered_view AS
SELECT o.* FROM original_table o
JOIN mysqluser_dept m on m.DepartmentId = o.DepartmentId
WHERE m.mysqluser = current_user() GROUP by o.id;
如果您不想显示原始表的所有列,则可以根据需要将视图中的select o.*限制为一组特定的字段.现在,根据需要将mysqlusers的映射表填充到departmet列.当前用户返回确切的用户,因此请使用完整的用户字符串(username @ localhost,username @%等)或更改视图以将主机砍掉进行比较.
现在,用户可以访问filtered_view,并且只能按部门查看他们有权访问的行.奖励:由于这是多对多的,因此您可以根据需要在多个部门中拥有人员-在原始表的主键上进行分组可以避免重复记录.
您可能还希望锁定对映射表mysqluser_department的权限.