我的设计是:
当一个SQL请求递交给Oracle引擎时,安全策略函数触发,在安全策略函数中取得递交的SQL语句(即使不能取得SQL语句,能取得where子句也好):怎么取得SQL语句???
具体实现如下:
1.
创建策略函数包:
CREATE OR REPLACE PACKAGE myP
AS
FUNCTION select_limit(
object_schema IN VARCHAR2,
object_name IN VARCHAR2) RETURN VARCHAR2;
END;
2.
实现策略函数包体:
CREATE OR REPLACE PACKAGE BODY myP
AS
FUNCTION select_limit(
object_schema IN VARCHAR2,
object_name IN VARCHAR2) RETURN VARCHAR2
IS
BEGIN
RETURN '1=2';
END;
END;
3.
映射策略:
begin
dbms_rls.add_policy
('system','test','myPP','system','myP.select_limit','select');
end;
这样,当用户select表test时,就会先执行包myP里的策略函数select_limit,把策略函数里的返回值作为where子句追加到用户的SQL后,再执行合成后的SQL语句。
我如何能在第二步(即在策略函数包体中)中,取得用户递交的SQL语句或where子句???
---------------------------------------------------------------
按照我的理解,策略的执行并非如你所说的:
"当用户select表test时,就会先执行包myP里的策略函数select_limit,把策略函数里的返回值作为where子句追加到用户的SQL后,再执行合成后的SQL语句。"
当用户SELECT表TEST时,系统会先执行包MYP里的策略函数SELECT_LIMIT,然后把表TEST用一个VIEW来取代,该VIEW是SELECT * FROM TEST WHERE...,WHERE条件就是策略函数返回的值,然后再对该VIEW进行SELECT操作. 虽然从结果来说是一样的,但实质意义并不同.所以没有必要预先知道用户执行的SQL语句.
不知道如何抓取用户提交的SQL语句.虽然可以用SQL_TRACEL或者V$SQL来跟踪.
---------------------------------------------------------------
我不知道你的这个用户进来的时候的权限是怎么断定的
应该和where条件本身无关吧,你不过是在where中追加一个条件而已
但对于同一个数据库用户,是否不论在哪里登陆近来其权限都一样?
还是说要根据session信息来判定?
如果相同数据库用户始终具有相同权限
那么,这个问题处理起来就简单的多,当然你也可以利用dbms_rls.add_policy 来实现调用者权限,这样同样一个包可以被不同的用户使用
当然,通过视图,同义词等也可以实现功能。
甚至,根据视图访问数据库,那视图中的一个字段用函数代替,而函数使用pragma可以执行自治事务,这样就可以控制oracle用户的查询操作。并可追踪查询用户记录