2014-03-21 2 views
3

Мы используем несколько таблиц, которые выглядят примерно так:MySQL: Ограничение доступа к подмножеству записей для каждого пользователя

| ID | DepartmentId | Data | 
| 1 | 1   | ... | 
| 2 | 1   | ... | 
| 3 | 2   | ... | 
| 4 | 3   | ... | 
| 5 | 2   | ... | 

У нас есть около 200 пользователей MySQL, каждый из которых связан с одним или несколькими отделами (через простую таблицу Username/DepartmentId) Мы хотели бы ограничить доступ (SELECT, UPDATE) только правильным подмножеством записей для каждого пользователя.

Например,

SELECT * FROM DataTable 

пользователя «Боб», который связан с отделами 1 и 3 должны возвращать записи 1, 2 и 4. тот же запрос для пользователя «Алиса», связанного с отделом 1, должны возвращать только записи 1 и 2.

Каков наилучший способ для этого?

+0

Вы должны сделать это со стороны приложения. На самом деле это довольно просто. – Alexander

+1

Когда вы говорите пользователям Mysql, вы говорите, что пользователи MySQL, перечисленные в таблице mysql.user, вы подключаетесь к БД с или «пользователями» в таблице, называемой «User» в вашем приложении. – Ray

+0

Я имею в виду фактических пользователей MySQL. Мы позволяем MySQL обрабатывать пользовательские привилегии как можно больше. Таким образом, пользователи могут подключаться только к нашему приложению, если они действительно могут подключаться к базе данных и получать доступ к ней. – ErikvdW

ответ

2

У MySQL нет разрешений на основе строк. Лучшее, что вы можете сделать, это построить представления, чтобы показать определенные записи. Простым способом было бы добавить таблицу сопоставления с именами пользователей mysql к идентификаторам отдела, к которым у них есть доступ, и иметь представление, которое будет отображаться в этой таблице сопоставления, присоединенной к оригиналу, где она ограничена текущим запрашивающим пользователем. Вы можете использовать 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 колонке департамента при необходимости. Текущий пользователь возвращает точного пользователя, поэтому используйте полную пользовательскую строку (имя пользователя @ localhost, имя пользователя @% и т. Д.) Или измените представление, чтобы отрубить хост в сравнении.

Теперь пользователь может получить доступ к фильтруемому_view и видеть только строки, к которым у них есть доступ по отделам. Бонус: поскольку это много-ко-многим, вы можете иметь людей в нескольких отделах, если это необходимо - группа по первичному ключу исходной таблицы избегает дублирования записей.

Возможно, вам также захочется заблокировать права доступа к таблице сопоставления mysqluser_department.

+0

Хотя это не совсем решение (не хотите напрямую ограничивать каждую запись конкретным пользователем, но через ключ отдела), это очень помогает мне. Я не думал использовать представление, используя current_user(). Я подумал о создании временных просмотров для входа для каждого пользователя, но это намного проще. Благодаря! – ErikvdW

+1

@ ErikvdW см. Мое обновление. – Ray

+0

Спасибо за обновление! Это действительно то, что мне нужно. – ErikvdW

Смежные вопросы