0
我們有表的數據庫,使用Oracle 9i,(9.2),我們必須做出政策SELECT查詢,一些用戶組可以訪問確切行和一些不能,地規範它的觀點來解決:如何阻止在Oracle 9i中選擇的行?
- 做一些查看錶
- 起源
但是有一個問題,不斷變化的表名,我們不能改變表的名稱,它的官僚主義問題。
最後,它是一些機制或觸發器(沒有觸發器的選擇,但只是例子)來控制行訪問?
對不起,如果問題是假的,我沒有太多的DB經驗。
我們有表的數據庫,使用Oracle 9i,(9.2),我們必須做出政策SELECT查詢,一些用戶組可以訪問確切行和一些不能,地規範它的觀點來解決:如何阻止在Oracle 9i中選擇的行?
但是有一個問題,不斷變化的表名,我們不能改變表的名稱,它的官僚主義問題。
最後,它是一些機制或觸發器(沒有觸發器的選擇,但只是例子)來控制行訪問?
對不起,如果問題是假的,我沒有太多的DB經驗。
一種選擇是爲相關表格創建一個Virtual Private Database policy。
從演講中,我做了幾年前
設置環境
-- The SEMOP user has been granted the following privileges
-- CREATE SESSION
-- CREATE PROCEDURE
-- CREATE ANY CONTEXT
-- UNLIMITED TABLESPACE
-- CREATE TABLE
-- CREATE SEQUENCE
-- EXECUTE ON DBMS_RLS
-- EXECUTE ON DBMS_FGA
-- SELECT ON DBA_FGA_AUDIT_TRAIL
conn oow2009/oow2009;
create table patient (
patient_id number primary key,
patient_first_name varchar2(30),
patient_last_name varchar2(30),
vip_flag char(1)
);
create table service (
service_id number primary key,
service_name varchar2(30)
);
create table doctor (
doctor_id number primary key,
doctor_first_name varchar2(30),
doctor_last_name varchar2(30),
service_id number references service(service_id)
);
create table admission (
admission_id number primary key,
patient_id number references patient(patient_id),
service_id number references service(service_id),
primary_doctor_id number references doctor(doctor_id),
admission_date date,
discharge_date date
);
begin
insert into patient(patient_id, patient_first_name, patient_last_name, vip_flag)
values(1, 'Barack', 'Obama', 'Y');
insert into patient(patient_id, patient_first_name, patient_last_name, vip_flag)
values(2, 'Larry', 'Ellison', 'Y');
insert into patient(patient_id, patient_first_name, patient_last_name, vip_flag)
values(3, 'Justin', 'Cave', 'N');
insert into patient(patient_id, patient_first_name, patient_last_name, vip_flag)
values(4, 'Jane', 'Doe', 'N');
insert into service(service_id, service_name)
values(11, 'Obstetrics');
insert into service(service_id, service_name)
values(12, 'Cardiac');
insert into service(service_id, service_name)
values(13, 'Opthamology');
insert into service(service_id, service_name)
values(14, 'Emergency');
insert into doctor(doctor_id, doctor_first_name, doctor_last_name, service_id)
values(21, 'William', 'Mayo', 14);
insert into doctor(doctor_id, doctor_first_name, doctor_last_name, service_id)
values(22, 'George', 'Minot', 13);
insert into doctor(doctor_id, doctor_first_name, doctor_last_name, service_id)
values(23, 'Richard', 'Morton', 12);
insert into doctor(doctor_id, doctor_first_name, doctor_last_name, service_id)
values(24, 'Carl', 'Jung', 11);
insert into doctor(doctor_id, doctor_first_name, doctor_last_name, service_id)
values(25, 'Joseph', 'Lister', 12);
-- Obama has been admitted 3 times, twice for heart tests and once for an eye test
insert into admission(admission_id, patient_id, service_id, primary_doctor_id, admission_date, discharge_date)
values(31, 1, 12, 23, date '2009-04-01', date '2009-04-01');
insert into admission(admission_id, patient_id, service_id, primary_doctor_id, admission_date, discharge_date)
values(32, 1, 12, 25, date '2009-05-03', date '2009-05-03');
insert into admission(admission_id, patient_id, service_id, primary_doctor_id, admission_date, discharge_date)
values(33, 1, 13, 22, date '2009-05-03', date '2009-05-03');
-- Ellison was admitted to the emergency department following a yachting accident
insert into admission(admission_id, patient_id, service_id, primary_doctor_id, admission_date, discharge_date)
values(34, 2, 14, 21, date '2009-07-01', date '2009-07-03');
-- Justin was admitted earlier today for an eye exam and hasn't been discharged
insert into admission(admission_id, patient_id, service_id, primary_doctor_id, admission_date, discharge_date)
values(35, 3, 13, 22, date '2009-09-24', null);
-- Jane was admitted to obstatrics
insert into admission(admission_id, patient_id, service_id, primary_doctor_id, admission_date, discharge_date)
values(36, 4, 11, 24, date '2009-08-01', date '2009-08-10');
end;
/
創建安全上下文
create or replace context oow2009_ctx
using pkg_secure_context;
create or replace package pkg_secure_context
as
procedure login(p_doctor_first_name IN doctor.doctor_first_name%TYPE,
p_doctor_last_name IN doctor.doctor_last_name%TYPE);
procedure logout;
end;
/
create or replace package body pkg_secure_context
as
procedure login(p_doctor_first_name IN doctor.doctor_first_name%TYPE,
p_doctor_last_name IN doctor.doctor_last_name%TYPE)
as
l_doctor_id doctor.doctor_id%TYPE;
begin
SELECT doctor_id
INTO l_doctor_id
FROM doctor
WHERE doctor_first_name = p_doctor_first_name
AND doctor_last_name = p_doctor_last_name;
dbms_session.set_context('oow2009_CTX',
'DOCTOR_ID',
to_char(l_doctor_id));
end login;
procedure logout
as
begin
dbms_session.clear_context('oow2009_CTX');
end logout;
end;
/
創建策略函數
create or replace function policy_view_own_patients(schema_p IN VARCHAR2,
table_p IN VARCHAR2)
return VARCHAR2
is
begin
return 'patient_id IN
(SELECT patient_id
FROM admission
WHERE primary_doctor_id =
SYS_CONTEXT(''oow2009_CTX'', ''DOCTOR_ID''))';
end;
/
創建行級安全策略
begin
dbms_rls.add_policy (
object_schema => 'oow2009',
object_name => 'PATIENT',
policy_name => 'VIEW_OWN_PATIENTS',
policy_function => 'POLICY_VIEW_OWN_PATIENTS'
);
end;
/
該查詢返回0行現在
select patient_first_name || ' ' || patient_last_name patient_name,
service_name,
doctor_last_name,
admission_date,
discharge_date
from patient p,
doctor d,
service s,
admission a
where p.patient_id = a.patient_id
and a.service_id = s.service_id
and a.primary_doctor_id = d.doctor_id
order by patient_last_name;
如果你登錄爲威廉·梅奧,但是
exec pkg_secure_context.login('William', 'Mayo');
同樣的查詢返回行但只有那些爲Mayo的患者排隊的人。其他行繼續被過濾掉
select patient_first_name || ' ' || patient_last_name patient_name,
service_name,
doctor_last_name,
admission_date,
discharge_date
from patient p,
doctor d,
service s,
admission a
where p.patient_id = a.patient_id
and a.service_id = s.service_id
and a.primary_doctor_id = d.doctor_id
order by patient_last_name;
你的政策功能,可以驅除當前登錄的用戶或其他任何一條信息,如果你不想要或需要的安全環境。
+1順便說一句Oracle Row-Level-Security需要Enterprise Edition許可證。 – APC