如何实现Oracle中用户B只能访问用户A的视图
我们有这样一个需求:在数据库中建立两个用户,用户A
用于创建一些视图,直接访问自己数据库中一个模式下的表,以及通过数据库链路访问其他数据库中的表;另一个用户B
能访问到这个用户A
中的视图,并且只能访问视图,且访问连接数有限制。
(miki西游的文档,原文链接 http://mikixiyou.iteye.com/blog/1543530)
这个用户B
是用来给其他系统访问的,因此对权限和资源使用都需要有限制条件。
这种需求在很多行业的应用中都很常见。假如这是一道面试题,您该如何去回答呢?
我采用下面的方法来回答这个问题。
第一步,创建新用户A
和B
。
这里用户名称分别为ryd_interface_src
和ryd_interface
,对这两个用户都授予非常有限的权限。
drop user ryd_interface_src cascade;
create user ryd_interface_src identified by ryd_interface_src;
grant connect,create view to ryd_interface_src;
drop user ryd_interface cascade;
create user ryd_interface identified by ryd_interface;
grant connect,create synonym to ryd_interface;
第二步,登录数据库一个模式中,授权给用户A
,使得用户A
能创建视图
conn qlzqclient/qlzqclient
grant select on INVEST_CLOCK to ryd_interface_src with grant option;
grant select on INVEST_LOG to ryd_interface_src with grant option;
这里授权方法加了一个with grant option
,请注意。
第三步,登录数据库用户A
中,创建视图
conn ryd_interface_src/ryd_interface_src
create or replace view run_views as
select id as doc_id, title,fbsj as upload_date,'' as branch_code from qlzq.runs_lantern@CLIENT_QLZQWEB
where EXT1='1' and sysdate > START_TIME
and sysdate < SOLID_TIME
union
select a.doc_id,a.title,a.upload_date,a.branch_code from qlzq.cms_doc_single_attr@CLIENT_QLZQWEB a
left join qlzq.cms_doc_category_map@CLIENT_QLZQWEB b on a.doc_id=b.doc_id
where
a.state =1 and a.is_delete =0
and a.upload_date> sysdate-90
and b.cat_id=4;
create or replace view INVEST_CLOCK_VIEWS as
select * from qlzqclient.INVEST_CLOCK;
create or replace view INVEST_LOG_VIEWS as
select * from qlzqclient.INVEST_LOG;
第四步,在数据库用户A
中,将视图查询权限授予给用户B
因为在步骤二中,加了with grant option
,所以这里视图查询权限可以成功授予。
grant select on INVEST_CLOCK_views to ryd_interface;
grant select on INVEST_LOG_views to ryd_interface;
grant select on run_views to ryd_interface;
第五步,在数据库用户B
中,检查视图能否查询得到,再创建同义词。
conn ryd_interface/ryd_interface
select count(*) from ryd_interface_src.run_views;
select count(*) from ryd_interface_src.INVEST_CLOCK_views;
select count(*) from ryd_interface_src.INVEST_LOG_views;
create synonym run_views for ryd_interface_src.run_views;
create synonym INVEST_CLOCK_views for ryd_interface_src.INVEST_CLOCK_views;
create synonym INVEST_log_views for ryd_interface_src.INVEST_log_views;
第三方的系统直接通过这个同义词就可以访问到用户A
中的视图。这也是对系统安全的一种保护措施。第三方系统登录后,只能看到其同义词,其他的都不会访问得到。
第六步,限制资源使用
因为用户B
是给第三方系统使用,我们无法控制第三方应用的质量,为了防止在应用出现异常连接时数据库会话数暴涨导致数据库整体服务出现故障,所以我们对该用户的数据库会
话数做一个限制。
这里采用profile
的sessions_per_user
功能,实现单个用户会话数的限制。
conn / as sysdba
alter system set resource_limite=true scope=both sid='*';
新建profile,
初始限制为1
,用于测试。
create profile third_user limit SESSIONS_PER_USER 1 FAILED_LOGIN_ATTEMPTS unlimited;
alter user ryd_interface profile third_user;
将会话数调整到30
alter profile third_user limit SESSIONS_PER_USER 30;
通过以上操作,我们就可以实现这个需求了。
再想一下,这个实现方法真的完全满足要求了吗?
请见下文:Oracle用户访问权限与PUBLIC角色的关系(http://mikixiyou.iteye.com/blog/1546581)
本文链接: http://mikixiyou.iteye.com/blog/1543530 欢迎转载,请注明出处和作者,谢谢合作。
1 楼
wukele
2012-05-29
不错。为什么需要同义词。b用户不是只能访问指定的视图了吗
2 楼
mikixiyou
2012-05-29
让用户B访问时,不用输入用户A.视图名称。
等于将用户A隐藏起来,减少一些技术还不熟练的好奇者的窥视。
3 楼
mikixiyou
2012-05-29
wukele 写道
不错。为什么需要同义词。b用户不是只能访问指定的视图了吗
让用户B访问时,不用输入用户A.视图名称。
等于将用户A隐藏起来,减少一些技术还不熟练的好奇者的窥视。
4 楼
bullet100
2012-05-29
这样的需求我也遇到过,不错!
5 楼
mikixiyou
2012-05-29
bullet100 写道
这样的需求我也遇到过,不错!
呵呵,谢谢鼓励!