【Oracle】如何让一个用户能够访问另外一个用户下所有的表
根据需求的不同,也分为好几种方法,且看下文。
先构造基本的环境:创建两个用户AA,BB,基本需求为用户AA能够访问用户BB下所有的表,即用户AA有对BB下所有的表有“select on”权限。
SYS@zkm> create user aa identified by oracle account unlock;
User created.
SYS@zkm> create user bb identified by oracle account unlock;
User created.
SYS@zkm> grant connect,resource to aa,bb;
Grant succeeded.
SYS@zkm> create table bb.t1(id int);
Table created.
SYS@zkm> create table bb.t2(id int);
Table created.
SYS@zkm> conn aa/oracle
Connected.
AA@zkm> select * from bb.t1;
select * from bb.t1
*
ERROR at line 1:
ORA-00942: table or view does not exist
对用户BB创建了两张表T1和T2,用户AA并没有对这两张表访问权限。
根据需求,有方法1:
SYS@zkm> select 'grant select on "'||owner||'"."'||table_name||'" to aa;' grant_sql from dba_tables where owner='BB';
GRANT_SQL
--------------------------------------------------------------------------------
grant select on "BB"."T1" to aa;
grant select on "BB"."T2" to aa;
SYS@zkm> grant select on "BB"."T1" to aa;
Grant succeeded.
SYS@zkm> grant select on "BB"."T2" to aa;
Grant succeeded.
SYS@zkm> conn aa/oracle
Connected.
AA@zkm> select * from bb.t1;
no rows selected
AA@zkm> select * from bb.t2;
no rows selected
缺点也很明显,对于新增加的表用户AA仍然无权限访问。
方法2:
回收权限,重新进行新的实验。
AA@zkm> conn bb/oracle
Connected.
BB@zkm> revoke select on "BB"."T1" from aa;
Revoke succeeded.
BB@zkm> revoke select on "BB"."T2" from aa;
Revoke succeeded.
BB@zkm> conn aa/oracle
Connected.
AA@zkm> select * from bb.t1;
select * from bb.t1
*
ERROR at line 1:
ORA-00942: table or view does not exist
方法如下:
SYS@zkm> grant select any table to aa;
Grant succeeded.
SYS@zkm> conn aa/oracle
Connected.
AA@zkm> select * from bb.t1;
no rows selected
AA@zkm> select * from bb.t2;
no rows selected
这种方法对新增加的表也有访问权限,缺点是除了SYS用户以外所有用户的表AA均有访问权限,由于权限被放大了,也就存在安全隐患。客户能接受是最方便的办法了。
方法3:
根据需求,不放大权限,并且对新建的表也有权限访问的话,目前我只想到用触发器来实现。先使用方法1对当前现有的表授权访问权限给AA,编写触发器实现BB创建新表后,触发授权动作达到目的。
回收select any table权限,并使用方法1对已有的表授权访问权限。
SYS@zkm> revoke select any table from aa;
Revoke succeeded.
SYS@zkm> grant select on "BB"."T1" to aa;
Grant succeeded.
SYS@zkm> grant select on "BB"."T2" to aa;
Grant succeeded.
不过在研究过程还是遇到一个问题,对于触发器触发的动作只能是DML操作,不能是DDL或者DCL。grant这个动作属于DCL操作会报错。详细见下文。
BB@zkm> create or replace trigger new_table_grant_tri
2 after create
3 on schema
4 declare
5 sqlstr varchar2(100);
6 begin
7 sqlstr:='grant select on '||ora_dict_obj_name||' to aa';
8 execute immediate sqlstr;
9 end;
10 /
Trigger created.
BB@zkm> create table t3(id int);
create table t3(id int)
*
ERROR at line 1:
ORA-00604: error occurred at recursive SQL level 1
ORA-30511: invalid DDL operation in system triggers
ORA-06512: at line 5
BB@zkm> !oerr ora 30511
30511, 00000, "invalid DDL operation in system triggers"
// *Cause: An attempt was made to perform an invalid DDL operation
// in a system trigger. Most DDL operations currently are not
// supported in system triggers. The only currently supported DDL
// operations are table operations and ALTER?COMPILE operations.
// *Action: Remove invalid DDL operations in system triggers.
上网找资料,发现一种技术叫“自治事务”,以前接触过一下没在意。
自治事务是在某个会话中独立开启一个事务,在其中处理的操作不会影响到同一会话中其他事务未提交的内容。反过来也是,同一会话的事务不会影响自治事务的内容。
于是将触发器改写如下:
BB@zkm> CREATE OR REPLACE TRIGGER new_table_grant_tri
2 after create
3 ON SCHEMA
4 DECLARE
5 PRAGMA AUTONOMOUS_TRANSACTION;
6 sqlstr varchar2(100);
7 BEGIN
8 IF ora_dict_obj_type='TABLE' THEN
9 sqlstr:='grant select on '||ora_dict_obj_name||' to aa';
10 execute immediate sqlstr;
11 COMMIT;
12 end if;
13 END;
14 /
Trigger created.
BB@zkm> create table t3(id int);
create table t3(id int)
*
ERROR at line 1:
ORA-00604: error occurred at recursive SQL level 1
ORA-04020: deadlock detected while trying to lock object BB.T3
ORA-06512: at line 7
目前尚不清楚ORA-4020错误产生原因。
换另外一种实现方式,先创建存储过程,该存储过程实现对新表授权动作。再创建触发器,调用该存储过程。如下:
BB@zkm> create or replace procedure new_table_grant_procedure(v_tabname IN VARCHAR2)
2 is
3 sqlstr VARCHAR2(200);
4 begin
5 sqlstr := 'grant select on ' || v_tabname ||' to aa';
6 execute immediate sqlstr;
7 end;
8 /
Procedure created.
BB@zkm> CREATE OR REPLACE TRIGGER new_table_grant_tri
2 after create
3 ON SCHEMA
4 DECLARE
5 PRAGMA AUTONOMOUS_TRANSACTION;
6 lv_job NUMBER;
7 BEGIN
8 IF ora_dict_obj_type='TABLE' THEN
9 DBMS_JOB.SUBMIT(lv_job,'new_table_grant_procedure('''||ora_dict_obj_name||''');');
10 COMMIT;
11 end if;
12 END;
13 /
Trigger created.
BB@zkm> create table t3(id int);
Table created.
BB@zkm> conn aa/oracle
Connected.
AA@zkm> select * from bb.t3;
no rows selected
如果不使用DBMS_JOB.SUBMIT的方式同样会报错ORA-4020,待探究。
关于触发器的其他知识点:
ora_client_ip_address:用于返回客户端的IP地址
ora_database_name:用于返回当前数据库名
ora_des_encrypted_password:用于返回DES加密后的用户口令
ora_dict_obj_name:用于返回DDL操作所对应的数据库对象名
ora_dict_obj_name_list(name_list_ OUT ora_name_list_t):用于返回字事件中被修改的对象名列表
ora_dict_obj_owner:用于返回DDL操作所对应的对象的所有者名。
ora_dict_obj_ower_list(ower_list OUT ora_name_list_t):用于返回在事件中被修改对象的所有者列表
ora_dict_obj_type:用于返回DDL操作所对应的数据库对象的类型。
ora_grantee(user_list OUT ora_name_list_t):用于返回授权时事件授权者。
ora_instance_num:用于返回历程号。
ora_is_alter_column(column_name IN VARCHAR2):用于检测特定列是否被修改
ora_is_creating_nested_table:用于检测是否正在建立嵌套表
ora_is_drop_column(column_name IN VARCHAR2):用于检测特定列是否被删除
ora_is_servererror(error_number):用于检测是否返回了特定Oracle错误。
ora_login_user:用于返回登录用户名
ora_sysevent :用于返回触发 触发器的系统时间名。
内容大致以上这些。
【Oracle】如何让一个用户能够访问另外一个用户下所有的表的更多相关文章
- yabeblog.me 关于Tomcat7部署 一台机器部署两个项目,一个用域名访问,一个用IP访问
该内容来自 http://www.yabeBlog.me,转载请说明出处. 1.使用IP访问的项目放在Tomcat7 的webapps目录下面:比如:AAA 2.使用域名访问的项目放在Tomcat7的 ...
- houxiurong.com 关于Tomcat7部署 一台机器部署两个项目,一个用域名访问,一个用IP访问
该内容来自 http://houxiurong.com,转载请说明出处. 1.使用IP访问的项目放在Tomcat7 的webapps目录下面:比如:AAA 2.使用域名访问的项目放在Tomcat7的w ...
- 玩转SSRS第九篇---匿名访问的一个间接方法
SSRS是一个功能丰富的报表平台,我们可以在这个平台上实现各种不同需求的报表应用,所以这个平台也吸引了很多.net框架之外的技术,希望能在应用中引入SSRS的报表,比如JSP或者PHP页面,这个时候系 ...
- MFC一个类访问另一个类成员对象的成员变量值
MFC中一个类要访问另外一个类的的对象的成员变量值,这就需要获得原来那个类对象的指针,其实有好几种方法都可以实现. 比如维护一个单例模式.设置静态变量等等.我们这里举个列子,实现多个类之间的相互访问. ...
- XAMPP环境访问非Web DocumentRoot下绝对路径
假设你的XAMPP网站文档根目录在C:/xampp/apache/htdocs/下面,那么访问这个目录下的文件是很直接的. 但是有时候需要把用户上传文件指定到特殊目录,比如E盘,那么就需要用户能够访问 ...
- 利用 awk 统计nginx 中某一个用户的访问次数
线上总是会遇到攻击,所以就需要分析 access.log 看看那些用户的访问次数不正常,针对这些不正常的用户,要做处理,以 access.log为例说明下怎么统计. 通过 access.log 日志来 ...
- 创建一个欢迎 cookie 利用用户在提示框中输入的数据创建一个 JavaScript Cookie,当该用户再次访问该页面时,根据 cookie 中的信息发出欢迎信息。
创建一个欢迎 cookie 利用用户在提示框中输入的数据创建一个 JavaScript Cookie,当该用户再次访问该页面时,根据 cookie 中的信息发出欢迎信息. <html> & ...
- Oracle总结【视图、索引、事务、用户权限、批量操作】
前言 在Oracle总结的第一篇中,我们已经总结了一些常用的SQL相关的知识点了...那么本篇主要总结关于Oralce视图.序列.事务的一些内容... 在数据库中,我们可以把各种的SQL语句分为四大类 ...
- oracle ebs应用产品安全性-定义访问权限集
定义 定义访问权限集是一项分配至责任层的可选的安全功能,是对Oracle 11i应用产品弹性域安全性定义的功能扩展,对总帐管理模块的一些内容进行安全性定义和权限分配的集合,以控制不同的责任对一些内容的 ...
随机推荐
- 第五届蓝桥杯JavaC组省赛真题
解题代码部分来自网友,如果有不对的地方,欢迎各位大佬评论 题目1.猜年龄 题目描述 小明带两个妹妹参加元宵灯会.别人问她们多大了,她们调皮地说:"我们俩的年龄之积是年龄之和的6倍" ...
- Java实现LeetCode_0035_SearchInsertPosition
package javaLeetCode.primary; public class SearchInsertPosition_35 { public static void main(String[ ...
- Java实现 蓝桥杯 算法提高金属采集
问题描述 人类在火星上发现了一种新的金属!这些金属分布在一些奇怪的地方,不妨叫它节点好了.一些节点之间有道路相连,所有的节点和道路形成了一棵树.一共有 n 个节点,这些节点被编号为 1~n .人类将 ...
- java实现第六届蓝桥杯加法变乘法
加法变乘法 题目描述 我们都知道:1+2+3+ - + 49 = 1225 现在要求你把其中两个不相邻的加号变成乘号,使得结果为2015 比如: 1+2+3+-+1011+12+-+2728+29+- ...
- Python学习之斐波那契数列实现篇
描述 一个斐波那契序列,F(0) = 0, F(1) = 1, F(n) = F(n-1) + F(n-2) (n>=2),根据n的值,计算斐波那契数F(n),其中0≤n≤1000. 输入 输入 ...
- CICD | Jenkins & Gitlab集成:WebHook触发构建
在上一篇博客中,我们学习了Jenkins的搭建和插件+流水线的基本使用方法,Jenkins极大地提升了部署效率. 最近想学习一下如何集成GitLab webhook,实现进一步解放双手,目标: 推送( ...
- (十一)DVWA全等级SQL Injection(Blind)盲注--手工测试过程解析
一.DVWA-SQL Injection(Blind)测试分析 SQL盲注 VS 普通SQL注入: 普通SQL注入 SQL盲注 1.执行SQL注入攻击时,服务器会响应来自数据库服务器的错误信息,信息提 ...
- Python如何绘制可视化图?给你一段代码,你能自己做出来吗
前言 本文的文字及图片来源于网络,仅供学习.交流使用,不具有任何商业用途,版权归原作者所有,如有问题请及时联系我们以作处理. 喜欢的朋友欢迎关注小编,除了分享技术文章之外还有很多福利 没有数据生成的图 ...
- Azure AD(四)知识补充-服务主体
一,引言 又到了新的一周了,也到了我新的分享的时间了,还记得上一周立得Flag,其中 “保证每周输出一篇文章” ,让我特别“在意”(这里用词不太恰当).主要是我的一个大学舍友,他突然问了我一个关于写博 ...
- HashMap常问面试题整理
去面试时,hashmap总是被经常问的问题,下面总结了几道关于hashmap的问题. 1.hashmap的主要参数都有哪些? 2.hashmap的数据结构是什么样子的?自己如何实现一个hashmap? ...