java 實現oracle VPD 許可權控制
實現思路和步驟:
- 業務資料有組織機構欄位
- ORACLE VPD 實現條件拼接
- JAVA 攔截器實現那些方法需要實現VPD行資料過濾
- 利用OracleConnection setEndToEndMetrics() 傳遞使用者許可權,後臺用userenv 獲取
模擬實現
建立訂單表
create table t_orders(
order_id number,
order_name varchar2(50),
org_id number
)
comment on table t_orders is ‘訂單表’;
comment on column t_orders.order_id is ‘訂單主鍵’;
comment on column t_orders.order_name is ‘訂單名稱’;
comment on column t_orders.org_id is ‘組織機構id’;
/**************************
insert into t_orders
select 1,’花生’,11 from dual
union all
select 2,’瓜子’,12 from dual
union all
select 3,’黃瓜’,11 from dual;
//賦予dmbs_pls 執行許可權
grant execute on sys.DBMS_RLS to vpd_test;
/****************/
create or replace function VPD_AUTHORITY_F(p_schema in varchar2 default NULL,
p_object in varchar2 default NULL)
RETURN varchar2 AS
begin
–拼接條件
return ‘1=1’;
end;
/*增加VPD策略***/
Begin
DBMS_RLS.ADD_POLICY ( OBJECT_SCHEMA => ‘vpd_test’,
OBJECT_NAME => ‘t_orders’,
POLICY_NAME => ‘t_orders’,
FUNCTION_SCHEMA => ‘vpd_test’,
POLICY_FUNCTION => ‘VPD_AUTHORITY_F’,
STATEMENT_TYPES => ‘SELECT’);
end;
/查詢結果*****/
1 1 花生 11
2 2 瓜子 12
3 3 黃瓜 11
/修改VPD策略函式*/
create or replace function VPD_AUTHORITY_F(p_schema in varchar2 default NULL,
p_object in varchar2 default NULL)
RETURN varchar2 AS
begin
–拼接條件
return ‘org_id=11’;
end;
/查詢結果*****/
1 1 花生 11
2 3 黃瓜 11
/*整合JAVA程式*********/
package cn.cowbt.vpd.test;
import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Types;
import oracle.jdbc.OracleConnection;
import oracle.jdbc.oracore.OracleType;
public class ConnectionTest {
public static void main(String[] args) throws SQLException {
String url = “jdbc:oracle:thin:@192.168.102.131:1521:orcl”;
String user = “vpd_test”;
String passwd = “tangxuhua”;
Connection connection = DriverManager.getConnection(url, user, passwd);
OracleConnection oCon = (OracleConnection) connection ;
String sql = “select * from t_orders”;
PreparedStatement ps = oCon.prepareStatement(sql);
String[] metrics = new String[4];
metrics[0] = “hello”;//action 後臺可以用userenv 取得
metrics[1] = “org_id = 12”;//client_identifier 後臺可以用userenv 取得
metrics[3] = “bobo”;//module 後臺可以用userenv 取得
/**
* v_action := sys_context(‘userenv’, ‘action’);
v_module := sys_context(‘userenv’, ‘module’);
v_client_identifer := sys_context(‘userenv’, ‘client_identifier’);
--後臺取得使用者的資訊,拼接成vpd 語句
create or replace procedure test_p(v_action out varchar2,
v_module out varchar2,
v_client_identifer out varchar2)
as
begin
v_action := sys_context('userenv', 'action');
v_module := sys_context('userenv', 'module');
v_client_identifer := sys_context('userenv', 'client_identifier');
null;
end test_p;
*/
oCon.setEndToEndMetrics(metrics, (short)0);
CallableStatement sts = connection.prepareCall("{call test_p(?,?,?)}");
sts.registerOutParameter(1,Types.VARCHAR);
sts.registerOutParameter(2,Types.VARCHAR);
sts.registerOutParameter(3,Types.VARCHAR);
sts.execute();
/* System.out.println(sts.getObject(1));
System.out.println(sts.getObject(2));
System.out.println(sts.getObject(3));*/
ResultSet rs = ps.executeQuery();
ResultSetMetaData rm = rs.getMetaData();
//System.out.println(rm.getColumnCount());
while(rs.next()){
Object o1 = rs.getObject(1);
Object o2 = rs.getObject(2);
Object o3 = rs.getObject(3);
System.out.print(o1);
System.out.print("---");
System.out.print(o2);
System.out.print("---");
System.out.print(o3);
System.out.println();
}
sts.close();
ps.close();
connection.close();
}
}
2—瓜子—12