Introduction
Cette fonctionnalité permet de limiter l'accès aux utilisateurs à des records auxquels ils ne doivent pas accéder.
Pour l'utiliser, la manière la plus simple est de filtrer sur la table pivot (ex. HRM_PERSON) de manière à ce que l'utilisateur ne puisse voir aucune information liée à des employés supérieurs p.ex.
Limitations
La VPD n'est disponible qu'en enterprise edition ( compris dans le prix ).
Attention, des warnings peuvent apparaître lors de la génération des dumps indiquant que tous les records n'ont peut être pas été exportés du fait de la policy. SYS n'est pas soumis aux policies, contrairement à tous les autres utilisateurs. Si c’est un user tiers qui effectue les travaux de maintenance ( backup ), il faut que celui-ci ait de manière directe ou via un rôle : EXEMPT ACCESS POLICY
Lors de la copie de sociétés, les policies doivent être refaites manuellement sur la société cible. Elles ne sont pas implicitement copiées.
Détermination de la règle
Exemple : l'utilisation d'un champ virtuel au niveau de l'utilisateur détermine les départements auxquels il a accès. Du côté des enregistrements des employés, une colonne de la table détermine cette information. On ne veut donc voir que les employés appartenant à des départements accessibles par l'utilisateur.
Attention : le critère doit se trouver dans la table. Il n'existe pas de possibilité de faire un exists() sur une autre table par exemple.
Définition du package qui détermine le droit (PCS)
La fonction déterminante (predicate) est celle qui retourne la condition à ajouter lors de chaque query. Dans l'exemple ci-dessous, pour la table HRM_PERSON, la condition est que le département de l'employé doit figurer dans la liste des départements autorisés.
CREATE OR REPLACE package VPD_IND_SETTINGS as /* Procédure définissant le contexte des droits */ PROCEDURE set_department; /* fonction retournant la clause where de la policy */ function predicate (obj_schema varchar2, obj_name varchar2) return varchar2; end VPD_IND_SETTINGS; / CREATE OR REPLACE package body VPD_IND_SETTINGS as /* Filtre sur les départements présents sur l'utilisateur */ function predicate (obj_schema varchar2, obj_name varchar2) return varchar2 is begin if obj_name = 'HRM_PERSON' then return 'INSTR(SYS_CONTEXT(''hrm_ctx'', ''dic_department_id''),DIC_DEPARTMENT_ID)>0 or SYS_CONTEXT(''hrm_ctx'', ''dic_department_id'') =''EVERYTHING'''; end if; end predicate; /* Définition du contexte */ PROCEDURE set_department AS department varchar2(255); BEGIN SELECT CVF_CHAR INTO department FROM com_vfields_value r, pc_user u WHERE cvf_tabname = 'PC_USER' AND cvf_REC_ID = PC_USER_ID AND USE_NAME = user AND cvf_fldname = 'VFLD_DEPARTMENTS'; DBMS_SESSION.SET_CONTEXT('hrm_ctx', 'dic_department_id', department); /* Pour gérer les utilisateurs système dans le cadre des dumps, aucun filtre n'est appliqué pour les users oracle qui ne sont pas définis dans PCS */ EXCEPTION WHEN NO_DATA_FOUND THEN DBMS_SESSION.SET_CONTEXT('hrm_ctx', 'dic_department_id', 'EVERYTHING'); END set_department; end VPD_IND_SETTINGS; /
Création du contexte
Un contexte doit être créé en tant que SYS pour contenir l’information qui déterminera le filtre.
CREATE OR REPLACE CONTEXT hrm_ctx USING pcs.vpd_ind_settings;
Définition de la policy ( pour chaque société )
begin dbms_rls.add_policy ( OBJECT_SCHEMA =>'C_SUVA', OBJECT_NAME =>'HRM_PERSON', POLICY_NAME =>'PERSON_DEPT', FUNCTION_SCHEMA =>'PCS', POLICY_FUNCTION =>'VPD_IND_SETTINGS.predicate', STATEMENT_TYPES => 'select,update,delete', POLICY_TYPE => DBMS_RLS.CONTEXT_SENSITIVE); end;
Suppression d'une policy
BEGIN DBMS_RLS.DROP_POLICY('C_SUVA','HRM_PERSON','PERSON_DEPT'); END;
Définition du logon_trigger (SYS)
Le logon trigger est indispensable de manière à définir le contexte d'utilisation de l'utilisateur en fonction d'une de ses caractéristique ( ex. champ virtuel ).
Ce trigger est également utilisé de manière à transporter les informations nécessaires entre les connexions dans le cadre des rapports Crystal.
CREATE OR REPLACE TRIGGER SYS_PC_CRYSTAL_LOGON_TRIGGER /** * Description * Trigger sur l'événemnt LOGON de la base de données * permettant d'initialiser PC_INIT_SESSION et indirectement les paramètres NLS * @created fp 07.06.2007 * @lastUpdate */ AFTER LOGON ON DATABASE DECLARE vIsCrystalSession BOOLEAN := FALSE; vnbcomp PLS_INTEGER := 0; vPipeName VARCHAR2 (128); vTerminal VARCHAR2 (100); vOsUser VARCHAR2 (30); vMachine VARCHAR2 (100); v_dep_id VARCHAR2 (255); BEGIN SELECT COUNT (*) INTO vnbcomp FROM pcs.pc_comp a, pcs.pc_scrip b WHERE a.pc_scrip_id = b.pc_scrip_id AND b.scrdbowner = USER; -- Si on se connecte avec un utilisateur "Société" IF vNbComp > 0 THEN vIsCrystalSession := PCS.PC_PIPE_MANAGEMENT.initCrystalSession; IF vIsCrystalSession THEN pcs.vpd_ind_settings.set_department; END IF; ELSE if user <> 'PCS' then select count(*) into vnbcomp from pcs.pc_user where use_name = user; if vnbcomp > 0 then PCS.PC_INIT_SESSION.SETUSER(USER); -- Uniquement pour les versions antérieures à 11.01 : PCS.PC_INIT_SESSION.SETUSERID(PCS.PC_INIT_SESSION.GETUSERID); pcs.vpd_ind_settings.set_department; end if; end if; END IF; END SYS_PC_CRYSTAL_LOGON_TRIGGER; /
Activation de la configuration société PC_CRYSTAL_PIPE
Pour permettre l'utilisation de crystal reports de données liées aux tables protégées, il est nécessaire d'activer cette configuration. Sinon aucune donnée d'employé n'apparaît.