Как добавить условие в конце SQL-запроса в WHERE и заставить его вступить в силу несмотря ни на что?(Запрос контроля доступа) - PullRequest
0 голосов
/ 21 ноября 2018

мне нужно написать контроль доступа для запросов, сделанных врачами (они могут написать запрос в текстовом поле, не спрашивая, почему это длинная история, это проект, а не сценарий реального мира) и я должен заставить врача видеть только своих пациентов в таблице пациентов, мой подход заключался в добавлении в приложение что-то вроде «И доктор_ид = $ doctor_id»

, а таблица пациентов - что-то вроде (имя, id, doctor_id, ...)

, но проблема заключается в таких запросах:

"выберите * из пациентов, где 1 = 1 ИЛИ 2 = 2"

Врач может просто сказать, что запрос и обойти это, и я должен реализовать это в приложении, а не в базе данных

так как я могу это сделать?как я могу добавить что-то подобное в конце запроса, чтобы оно работало независимо от того, что они вводили до этого?или у вас есть лучшее предложение?

(и у них должна быть возможность написать запрос, поэтому удаление это не вариант)

У меня есть парсер для этого, но я хочу, чтобы они могли написать что-то вроде select* от пациентов и получить только своих пациентов в этой таблице.

1 Ответ

0 голосов
/ 21 ноября 2018

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

CREATE OR REPLACE TEMPORARY VIEW patients
  AS SELECT * FROM patients_base_table WHERE doctor_id = 1234;

Если существует только пользователь базы данных и у него нет разрешения на чтение для patients_base_table, это другой пользователь справильные разрешения, которые должны создать это представление.Это можно сделать с помощью механизма SECURITY DEFINER, где функция выполняется с привилегиями ее создателя, а не вызывающей стороны:

-- Create this function as the privileged user that owns the patients table
CREATE FUNCTION create_view(doctor_id int) RETURNS void
AS $$
BEGIN
  EXECUTE 'CREATE OR REPLACE TEMPORARY VIEW patients  AS '
          'SELECT * FROM patients_base_table WHERE doctor_id=' || doctor_id;
  EXECUTE format('GRANT SELECT ON patients TO %I', session_user);
END
$$ LANGUAGE plpgsql SECURITY DEFINER;

Это не пулевое доказательство, поскольку врач всегда может вызвать create_view(other_doctor), еслиу них есть полный доступ к базе данных с общими учетными данными, но с общими учетными данными вы можете сделать так много ...

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...