[Oracle ADF] Row Level Security using VPD and ADF - Шаг 2 - подготавливаем и включаем VPD
ШАГ 2: Что же со всем этим добром теперь делать?
Смотрим пример:
И здесь у меня 2 варианта:
Заработало у меня не сразу. Пришлось делать по шагам. Сначала фукнцию создавал вне пакета (как делается в видео), потом заработало и в в пакете.
Продолжаем дальше рассматривать вариант с пакетом
При создании policy я использовал 3 параметра как в видео и у меня вроде не работало. Может просто был не день Бекхама. Из этого вопроса, пришел к выводу, что можно использовать большее количество параметров.
https://stackoverflow.com/questions/36413922/implementing-vpd-predicate-function-ora-28110-policy-function-or-package-has
После того, как стал использовать такой способ. Стало работать.
Функцию нужно создавать под sysdba или под учеткой с достаточным количеством прав!
Я создавал под пользователем 2 часа не мог понять где ошибка!
На сервере где расположена база. (Разумеется это linux), делаю следующее:
$ cd /tmp
Создаю Enable и Disable скрипты. Сразу лучше написать disable, чтобы если что-то пошло не так, можно было бы быстро отключить.
Enable
$ vi policy-enable.sql
begin
dbms_rls.add_policy
(object_schema => 'MY_SCHEMA',
object_name => 'STORE',
policy_name => 'STORE_TABLE_VPD1',
function_schema => 'MY_SCHEMA',
policy_function => 'SEC_CTX_PKG.WHITE_ACESS_LIST',
statement_types => 'SELECT');
end;
/
$ sqlplus / as sysdba
@policy-enable.sql
Disable
$ vi policy-disable.sql
begin
DBMS_RLS.DROP_POLICY('MY_SCHEMA', 'STORE', 'STORE_TABLE_VPD1');
end;
/
$ sqlplus / as sysdba
@policy-disable.sql
Определение в голове пакета:
FUNCTION WHITE_ACESS_LIST (p_schema VARCHAR2, p_object VARCHAR2) RETURN VARCHAR2;
Функция в теле пакета:
FUNCTION WHITE_ACESS_LIST (
p_schema in varchar2,
p_object in varchar2)
RETURN VARCHAR2
AS
L_LOGGED_IN_USER varchar2(250);
L_RES VARCHAR2(255);
BEGIN
-- Удалять не стал. L_LOGGED_IN_USER подставляю в реальный запрос. Который не буду здесь писать.
-- Но если путаешься с кавычками как и я, смотри сюда: plsql.ru/docs/other/variables-concat/
-- Лично я на этих кавычках потерям много времени
-- SELECT SYS_CONTEXT ('SEC_CTX', 'user_id') INTO L_LOGGED_IN_USER FROM DUAL;
L_RES := 'STORE in (100, 101)';
RETURN L_RES;
END WHITE_ACESS_LIST;
Ну и собственно все.
Можно подключиться пользователем к схеме указанной в policy и сделать SELECT. В результате будет выведено всего 2 записи с указанными в policy ID.
Ну а чтобы ограничить данных разрешенных для пользователя, можно создать таблицу с разрешенными для пользователя ID. И делать что-то похожее на
SELECT * FROM ACCESS_LIST WHERE USER = _LOGGED_IN_USER;
При необходимости добавить decode по вкусу.