Oracle Virtual Private Database – VPD

https://audiopronews.com/headlines/907g2bna O Virtual Private Database, mais conhecido como VPD, é um recurso do Oracle Database Enterprise Edition (EE) existente desde a versão 8i que permite criar políticas de segurança simples ou complexas sobre objetos, sejam eles tabelas, views ou sinônimos.

https://kirkmanandjourdain.com/1jmku7b2y9 O VPD é usado quando os privilégios de objeto padrão e funções de banco de dados associados são insuficientes para atender às exigências de segurança do aplicativo, deste modo, políticas personalizadas a nível de linha e/ou coluna (a partir da versão 10g) podem limitar o acesso a informações restritas, por exemplo.

Ordering Tramadol Online Illegal Como as políticas de segurança estão associadas a um objeto (tabela, view ou sinônimo) dentro do database, sempre que ocorrer o acesso ao objeto elas são automaticamente acionadas independente da fonte (por meio de um aplicativo, uma interface Web ou SQL * Plus) proporcionando sempre o mesmo resultado e impedindo a violação da segurança.

https://lavozdelascostureras.com/dlmksy2 Ao acessar o objeto protegido com o Oracle Virtual Private Database policy, o Oracle Database dinamicamente modifica o comando SQL do usuário. A modificação cria a condição WHERE (caso não exista na SQL) e retorna a função de segurança implementada de forma totalmente transparente para o usuário.

https://townofosceola.com/46y6p1r4hh Podemos aplicar com o VPD políticas de segurança sobre sentenças como SELECT, INSERT, UPDATE, INDEX e DELETE.

https://musicboxcle.com/2025/04/9yr6rzh8 Neste artigo irei demonstrar a criação de uma VPD simples a nível de linha ( go site Row Level Security), ou seja, limitando usuários apenas a não poderem visualizar determinados registros em um tabela.

https://faroutpodcast.com/sqve6tle73r Criando e populando uma tabela FUNCIONARIO onde vou posteriormente aplicar a policy.

https://audiopronews.com/headlines/1ricf6m59 SQL> create table funcionario( 2 nome varchar2(50), 3 salario number(10,2) 4 ); Table created. SQL> insert into funcionario values ('FUNC1',1000.00); 1 row created. SQL> insert into funcionario values ('FUNC2',1000.00); 1 row created. SQL> insert into funcionario values ('FUNC3',2000.00); 1 row created. SQL> insert into funcionario values ('FUNC4',5000.00); 1 row created. SQL> insert into funcionario values ('FUNC5',10000.50); 1 row created. SQL> commit; Commit complete.

Order Clonazepam Criando a tabela DENY_ACCESS_FUN onde vou cadastrar os usuários que serão afetados(limitados) pela policy.

https://reggaeportugal.com/wqfegv4posj SQL> create table deny_access_fun( 2 nome varchar2(50) 3 ); Table created.

https://faroutpodcast.com/r2zddcry Criando a tabela BLOCKED_ACCESS_FUN onde vou cadastrar o nome dos registros da tabela FUNCIONARIO que não podem ser visualizados pelos usuários cadastrados na tabela DENY_ACCESS_FUN.

Buy Soma Watson SQL> create table blocked_access_fun( 2 nome varchar2(50) 3 ); Table created.

https://lavozdelascostureras.com/lz9k4800 Agora vou criar a FUNÇÃO que será chamada pela policy e que irá retornar a condição ( Cheap Tramadol Canada PREDICATE) para a cláusula get link WHERE, ou seja, quando um usuário cadastrado na tabela DENY_ACCESS_FUN realizar um select na tabela FUNCIONARIO a policy vai atribuir na condição enter site WHERE a linha abaixo:

https://townofosceola.com/vkkihh04 https://etxflooring.com/2025/04/lkpbybbpg nome not in (select nome from blocked_access_fun);

Buy Cheap Tramadol Uk Se o usuário não está cadastrado na DENY_ACCESS_FUN ela retorna: http://jannaorganic.co.uk/blog/2025/04/03/n58f0dlks 1=1 o que não afeta nenhum registro.

https://kirkmanandjourdain.com/4f8usufw6x SQL> CREATE OR REPLACE FUNCTION VPD_DENY_ACCESS_FUN 2 (schema in varchar2, table_p in varchar2) return varchar2 as 3 w_exists number :=0; 4 predicate varchar2(50) default null; 5 BEGIN 6 select max(vlr) into w_exists 7 from (select 0 vlr 8 from dual 9 union 10 select 1 vlr 11 from deny_access_fun 12 where nome = UPPER(SYS_CONTEXT('USERENV', 'SESSION_USER'))); 13 IF w_exists = 1 14 THEN 15 predicate := 'nome not in (select nome from blocked_access_fun)'; 16 ELSE 17 predicate := '1=1'; 18 END IF; 19 RETURN predicate; 20 END; 21 / Function created.

here Observem que na FUNCTION utilizei a SYS_CONTEXT para coletar informações da minha sessão, no caso o usuário que conectei (SESSION_USER). Você pode saber mais sobre a SYS_CONTEXT acessando o artigo, SYS_CONTEXT ‘USERENV’.

https://www.annarosamattei.com/?p=su4qnf1tcgc Antes de criar a policy vamos aplicar o seguinte grant:

Buy Cheap Tramadol Online Uk SQL> GRANT EXECUTE ON DBMS_RLS TO PUBLIC; Grant succeeded.

https://etxflooring.com/2025/04/p3k76o1vvzm Criando a policy:

https://musicboxcle.com/2025/04/l026unk SQL> BEGIN 2 DBMS_RLS.ADD_POLICY ( 3 object_schema => 'ANDERSON', 4 object_name => 'FUNCIONARIO', 5 policy_name => 'VPD_DENY_ACCESS_FUN_RH', 6 function_schema => 'ANDERSON', 7 policy_function => 'VPD_DENY_ACCESS_FUN', 8 statement_types => 'select'); 9 END; 10 / PL/SQL procedure successfully completed.

https://aalamsalon.com/9hvqhr6udne Observe que na statement_types coloquei apenas https://kanchisilksarees.com/0egnevb SELECT, desta forma a policy só é executada quando feito um select na tabela FUNCIONARIO.

Tramadol Cheapest Criando 2 usuários para testes e aplicando as permissões necessárias:

follow SQL> create user teste1 identified by andersonteste1; User created. SQL> create user teste2 identified by andersonteste2; User created. SQL> grant create session to teste1, teste2; Grant succeeded. SQL> grant select on anderson.funcionario to teste1, teste2; Grant succeeded.

see url Agora conectando com os usuários criados podemos ver que os registros estão todos sendo mostrados porque ainda não cadastrei nada nas tabelas DENY_ACCESS_FUN e BLOCKED_ACCESS_FUN:

https://www.villageofhudsonfalls.com/wu1jyalq8 SQL> conn teste1/andersonteste1 Connected. SQL> select * from anderson.funcionario; NOME SALARIO -------------------------------------------------- ---------- FUNC1 1000 FUNC2 1000 FUNC3 2000 FUNC4 5000 FUNC5 10000.5 SQL> conn teste2/andersonteste2 Connected. SQL> select * from anderson.funcionario; NOME SALARIO -------------------------------------------------- ---------- FUNC1 1000 FUNC2 1000 FUNC3 2000 FUNC4 5000 FUNC5 10000.5

Em uma outra sessão (com permissão de insert nas tabelas), vou bloquear o usuário TESTE1 para não visualizar os registros do funcionário FUNC3:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
SQL> insert into deny_access_fun values ('TESTE1');
 
1 row created.
 
SQL> insert into blocked_access_fun values ('FUNC3');
 
1 row created.
 
SQL> commit;
 
Commit complete.
 
SQL> conn teste1/andersonteste1
Connected.
SQL> select * from anderson.funcionario;
 
NOME                                                  SALARIO
-------------------------------------------------- ----------
FUNC1                                                    1000
FUNC2                                                    1000
FUNC4                                                    5000
FUNC5                                                 10000.5

Observe acima que o FUNC3 já não foi mais retornado para o usuário TESTE1 enquanto para o usuário TESTE2 ainda é apresentado:

01
02
03
04
05
06
07
08
09
10
11
SQL> conn teste2/andersonteste2
Connected.
SQL> select * from anderson.funcionario;
 
NOME                                                  SALARIO
-------------------------------------------------- ----------
FUNC1                                                    1000
FUNC2                                                    1000
FUNC3                                                    2000
FUNC4                                                    5000
FUNC5                                                 10000.5

Vou cadastrar mais uma linha(nome) da tabela FUNCIONARIO que não deve ser visualiza pelo usuário TESTE1:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
SQL> conn anderson
Enter password:
Connected.
SQL> insert into blocked_access_fun values ('FUNC5');
 
1 row created.
 
SQL> commit;
 
Commit complete.
 
SQL> conn teste1/andersonteste1
Connected.
SQL> select * from anderson.funcionario;
 
NOME                                                  SALARIO
-------------------------------------------------- ----------
FUNC1                                                    1000
FUNC2                                                    1000
FUNC4                                                    5000
 
SQL> conn teste2/andersonteste2
Connected.
SQL> select * from anderson.funcionario;
 
NOME                                                  SALARIO
-------------------------------------------------- ----------
FUNC1                                                    1000
FUNC2                                                    1000
FUNC3                                                    2000
FUNC4                                                    5000
FUNC5                                                 10000.5

Agora cadastrando também o usuário TESTE2 na tabela DENY_ACCESS_FUN. Vejam que ele também não consegue mais ver os outros registros.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
SQL> conn anderson
Enter password:
Connected.
SQL> insert into deny_access_fun values ('TESTE2');
 
1 row created.
 
SQL> commit;
 
Commit complete.
 
SQL> conn teste2/andersonteste2
Connected.
SQL> select * from anderson.funcionario;
 
NOME                                                  SALARIO
-------------------------------------------------- ----------
FUNC1                                                    1000
FUNC2                                                    1000
FUNC4                                                    5000

Como falado no inicio do artigo este foi apenas um exemplo simples de implementação com https://semichaschaver.com/2025/04/03/nww97pjc8 VPD limitando o Order Tramadol Overnight SELECT a determinados https://aalamsalon.com/yvp021kb7 USUÁRIOS X REGISTROS.

A VPD pode ser implementada de muitas outras formas e pode ser muito mais abrangente e complexa.

Outros exemplos e documentações podemos encontrar em:

Referências:

http://docs.oracle.com/cd/B28359_01/network.111/b28531/vpd.htm
http://www.oracle.com/technetwork/database/security/index-088277.html

%name Oracle Virtual Private Database   VPD

Autor: Anderson Graf

Bacharel em Sistemas de Informação e MBA em Gestão de Banco de Dados Oracle. Entusiasta da tecnologia Oracle, ACE Associate ♠, autor em vários blogs e OTN. Consultor Oracle Senior na Exímio Soluções em TI

Envolvido em soluções de:
– Implementação, migração, gerenciamento e suporte a produtos Oracle, multiplataforma
– Monitoramento de ambientes 24×7
– Backup e Recovery
– Performance e Tuning
– Alta disponibilidade (HA) – RAC, Data Guard
– EM database/grid/cloud control
– Particionamento & Advanced Compression
– Oracle Engineered Systems – ODA, Exadata

Blog pessoal: http://www.andersondba.com.br
Articulista na Oracle Technology Network (OTN) – https://goo.gl/99R6yW
ACE Associate – https://goo.gl/MBB51b
Articulista GPO – http://profissionaloracle.com.br