您的位置:首页 > 数据库 > Oracle

Virtual Private Database (VPD) with Oracle

2009-10-06 23:33 423 查看
refer:http://www.adp-gmbh.ch/ora/security/vpd/

VirtualPrivateDatabaseisalsoknownasfinegraindaccesscontrol(FGAC).Itallowstodefinewhichrowsusersmayhaveaccessto.

Asimpleexample

Inthisexample,itisassumedthatacompanyconsistsofdifferentdepartments(witheachhavinganentryinthedepartmentstable).Anemployeebelongstoexactlyondepartment.Adepartmentcanhavesecretsthatgointothedepartment_secretstable.

createtabledepartment(
dep_idintprimarykey,
namevarchar2(30)
);

createtableemployee(
dep_idreferencesdepartment,
namevarchar2(30)
);

createtabledepartment_secrets(
dep_idreferencesdepartment,
secretvarchar2(30)
);


Fillinginsometrulyconfidentialsecrets:

insertintodepartmentvalues(1,'ResearchandDevelopment');
insertintodepartmentvalues(2,'Sales');
insertintodepartmentvalues(3,'HumanResources');

insertintoemployeevalues(2,'Peter');
insertintoemployeevalues(3,'Julia');
insertintoemployeevalues(3,'Sandy');
insertintoemployeevalues(1,'Frank');
insertintoemployeevalues(2,'Eric');
insertintoemployeevalues(1,'Joel');

insertintodepartment_secretsvalues(1,'R+DSecret#1');
insertintodepartment_secretsvalues(1,'R+DSecret#2');
insertintodepartment_secretsvalues(2,'SalesSecret#1');
insertintodepartment_secretsvalues(2,'SalesSecret#2');
insertintodepartment_secretsvalues(3,'HRSecret#1');
insertintodepartment_secretsvalues(3,'HRSecret#2');


Foranyemployee,itmustbepossibletoseeallsecretsofhisdepartment,butnosecretofanotherdepartment.
InordertomakethathappenwithOracle,weneedtocreateapackage,atrigger,andsetapolicy.
First,thepackageiscreated.

createorreplacepackagepck_vpd
as
p_dep_iddepartment.dep_id%type;

procedureset_dep_id(v_dep_iddepartment.dep_id%type);

functionpredicate(obj_schemavarchar2,obj_namevarchar2)returnvarchar2;
endpck_vpd;
/

createorreplacepackagebodypck_vpdas

procedureset_dep_id(v_dep_iddepartment.dep_id%type)is
begin
p_dep_id:=v_dep_id;
endset_dep_id;

functionpredicate(obj_schemavarchar2,obj_namevarchar2)returnvarchar2is
begin
return'dep_id='||p_dep_id;
endpredicate;

endpck_vpd;
/


Thenthetriggerisdefined.Thistriggerfireswheneversomeonelogontothedatabase.Itfindstheuser'sdepartementid(dep_id)andcallsset_dep_idinthepackage.

createorreplacetriggertrg_vpd
afterlogonondatabase
declare
v_dep_iddepartment.dep_id%type;
begin
selectdep_idintov_dep_id
fromemployeewhereupper(name)=user;

pck_vpd.set_dep_id(v_dep_id);
end;
/


Finally,thepolicyisdefined.Thepolicystateswhichprocedureisusedtoaddawhereclauseparttothewhereclauseifsomeoneexecutesaselectstatement.

begin
dbms_rls.add_policy(
user,
'department_secrets',
'choosablepolicyname',
user,
'pck_vpd.predicate',
'select,update,delete');
end;
/


Totestthesetup,someusersarecreated.

createuserfrankidentifiedbyfrankdefaulttablespaceuserstemporarytablespacetemp;
createuserpeteridentifiedbypeterdefaulttablespaceuserstemporarytablespacetemp;
createuserjuliaidentifiedbyjuliadefaulttablespaceuserstemporarytablespacetemp;


Thenecessaryprivilegesaregranted.

grantallondepartment_secretstofrank;
grantallondepartment_secretstopeter;
grantallondepartment_secretstojulia;

grantcreatesessiontofrank;
grantcreatesessiontopeter;
grantcreatesessiontojulia;


Apublicsynonymiscreated.

createpublicsynonymdepartment_secretsfordepartment_secrets;


Frank(belongingtoR+D)executesaquery....

connectfrank/frank;

select*fromdepartment_secrets;


DEP_IDSECRET
----------------------------------------
1R+DSecret#1
1R+DSecret#2


Peter(belongingtoSales)executesaquery....

connectpeter/peter;

select*fromdepartment_secrets;


DEP_IDSECRET
----------------------------------------
2SalesSecret#1
2SalesSecret#2


-------------------------------------------------------------------------------
--FileName:vpd2.sql
-------------------------------------------------------------------------------
--Maintainer:PeteFinnigan(http://www.petefinnigan.com)
--Copyright:Copyright(C)2009PeteFinnigan.comLimited.Allrights
--reserved.Allregisteredtrademarksarethepropertyoftheir
--respectiveownersandareherebyacknowledged.
-------------------------------------------------------------------------------
--Usage:Thescriptprovidedhereisavailablefree.Youcandoanything
--youwantwithitcommercialornoncommercialaslongasthe
--copyrightandthisnoticearenotremovedoreditedinanyway.
--Thescriptscannotbeposted/published/hostedorwhatever
--anywhereelseexceptatwww.petefinnigan.com/vpd2.sql
--------------------------------------------------------------------------------

prompt[*]connectasSYS
pause

connectsys/oracle1assysdba

prompt[*]Dropthetestuser
dropuserpxfcascade;

prompt[*]Recreatethetestuser

createuserpxfidentifiedbypxfdefaulttablespaceuserstemporarytablespacetemp;

grantcreatesessiontopxf;

grantcreateanycontexttopxf;

grantcreatetabletopxf;

grantunlimitedtablespacetopxf;

grantcreateproceduretopxf;

grantexecuteondbms_rlstopxf;

grantexecuteondbms_sessiontopxf;

createtablepxf.empasselect*fromscott.emp;

prompt[*]NowconnectasPXF
pause

connectpxf/pxf

prompt[*]Selectfromthesampletable-shouldbe15rows
pause

select*fromemp;

Prompt[*]LeteveryoneseethetableandconnectasSCOTTandselectagain
prompt[*]shouldstillbe15rows

grantselectonpxf.emptopublic;

connectscott/tiger

select*frompxf.emp;

prompt[*]connectasPXFagainandsetupasimpleVPD
prompt[*]thatrestrictsaccesstodept10
pause

connectpxf/pxf

createorreplacefunctionpredicate(pv_schemainvarchar2,pv_objectinvarchar2)
returnvarchar2
as
begin
return'deptno!=''10''';
end;
/

begin
dbms_rls.add_policy(
object_schema=>'PXF',
object_name=>'EMP',
policy_name=>'PXFTEST',
policy_function=>'PREDICATE');
end;
/

prompt[*]FinallyconnectasSCOTTandseeifheisblockedfromseeingthedata
prompt[*]shouldnowbe12rows!
pause

connectscott/tiger

select*frompxf.emp;

prompt[*]
pause
shouser

prompt[*]setuptraceanddumpthepredicate
pause
altersessionsetsql_trace=true;

altersessionsetevents'10730tracenamecontextforever';

prompt[*]Dumpthedatafromtheemptable
select*frompxf.emp;

prompt[*]Turntraceoff
altersessionsetevents'10730tracenamecontextoff';
altersessionsetsql_trace=false;

prompt[*]Letslookatthetracefile
pause

prompt[*]
pause

prompt[*]Viewthepredicate
pause

selectobject_owner,object_name,policy_name,
pf_owner,pf_owner,function
fromall_policies;

setserveroutputonsize1000000

declare
predicvarchar2(1000);
begin
dbms_output.put_line('Thepredicateis:'||pxf.predicate('PXF','EMP'));
end;
/

prompt[*]Ihaveseenthistypeofdesign:
prompt[*]wherethepredicatefunctionsareexecutablebyall
pause

connectpxf/pxf
grantexecuteonpredicatetopublic;
connectscott/tiger

setserveroutputonsize1000000

declare
predicvarchar2(1000);
begin
dbms_output.put_line('Thepredicateis:'||pxf.predicate('PXF','EMP'));
end;
/

prompt[*]Accessthedatadirectly
pause

---------------------------------------------------------
--changethefilenumberandblocknumbertosuityour
--databasenotmine.
---------------------------------------------------------

selectdistinctdbms_rowid.rowid_block_number(rowid)blk,
dbms_rowid.rowid_relative_fno(rowid)fno
frompxf.emp;

selectfile_namefromdba_data_files
wherefile_id=4;

altersystemdumpdatafile4block444;

prompt[*]Letstryagainasmonitor
pause

connectmonitor/monitor

selectdistinctdbms_rowid.rowid_block_number(rowid)blk,
dbms_rowid.rowid_relative_fno(rowid)fno
frompxf.emp;

selectfile_namefromdba_data_files
wherefile_id=4;

altersystemdumpdatafile4block444;


                                            
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: