oracle获取用户角色与权限常见误区

张勇,北京海天起点公司数据库管理员,Oracle一体机用户组成员,获有OCP证书,具有多年金融行业oracle, mysql数据库日常维护,故障排除,性能优化、数据迁移、容灾备份等方面的运营维护经验;具有丰富的数据库设计和架构搭建经验,擅长数据统计和分析,熟悉NoSql产品;

目的(目标)

在系统维护过程中,有时基于安全审计的需要,要求对数据库中所有业务用户的权限进行审计。这是一个简单的需求,网络上也提供了很多现成的脚本,但多并不意味着正确,在某些情况下,这些脚本并没有真正实现需求目标;下面实操一把,把不合理的情况举出来,作为知识点记录。

知识点回顾

我们清楚,在oracle数据库里,将权限分为两种类型:系统权限和对象权限。凡是涉及到数据库资源消耗的操作,都会要求其具有相应的权限,比如:用户能不能登录数据库,能否执行sql语句,或能否访问某个对象等等。

系统权限指的是用户能够做什么的权限。比如,建立连接,创建表空间或创建表等,都属于系统权限。Oracle数据库所有的系统权限都保存在system_privilege_map的数据字典表里。

对象权限指的是用户能够对某个特定对象做某些事情的权限。比如,A用户可以查询B用户下的T表,这就是一个对象权限。Oracle数据库所有的对象权限都保存在dba_tab_privs的数据字典表里。

一般情况下,为了更方便管理用户权限的授予和回收,在数据库中通常会使用角色;可以把角色理解为一组权限的集合,角色名就是集合的名称。我们可以将角色赋给某个用户,这样该用户就具有了角色所包含的所有权限,同样也可以将角色赋给另外的角色,不过角色之间不能形成闭环关系。Oracle数据库赋予角色(或用户)的权限和角色分别保存在dba_sys_privsdba_role_privs的数据字典表里,但是这两个字典表都只支持直接授权关系的查询,当角色存在嵌套情况时,就需要自己写脚本进行递归查找了,把潜在的间接权限也找出来。

不合理的情况

我们首先创建两个角色:ManagerDeveloper;其中Manager作为开发管理角色,Developer作为开发角色,用于对不同身份的用户进行统一的授权和管理。

角色权限信息如下:

自定义角色 授予的角色 授予的权限
Developer Resource,Connect create view,create synonym
Manager Developer grant any object privilege,grant any privilege

接着我们创建三个用户dev1dev2m1;其中dev1为开发用户,m1为开发管理用户。而dev2权限与dev1完全相同,但授权方式不同,只用作区分测试效果。

用户权限信息如下:

用户 授予的角色 授予的权限
dev1 Developer unlimited tablespace
dev2 unlimited tablespace, create view,create synonym,Resource,Connect
m1 Manager unlimited tablespace


现在获取用户所有的角色和权限信息,常见的脚本都是得到类似下面的结果:


这些脚本都只查了一层,在权限列中只看到了直接授予用户的权限,而对于角色中包涵权限我们就看不出来了。对于用户dev2,如果对数据库比较熟悉,因为CONNECT,RESOURCE都是系统中常见的内置角色,我们大概清楚其中有哪些权限;而对于MANAGER,DEVELOPER这类自定义角色,就不太能清楚了,最好是能进行递归查找,把其内部的权限也都一并找出来。

改进方法

    首先创建一个vw_user_role_graph视图,通过递归查找梳理出用户和角色的关系图:



视图中Lev表示分配在用户上角色的层级,0级表示用户本身,其它级别表示角色。Path列描述了角色从属关系,这里可以看出Developer角色下并列的包括了Connect,Resource两个角色。

接下来我们找出用户被授予的所有角色,只需要在vw_user_role_graph视图上去掉用户信息以及可能存在的重复记录就完成了。

创建vw_user_roles视图:


这个结果和session_roles视图效果一样,不过session_roles视图只能查找出当前用户的角色。

最后我们找出用户被授予的所有权限,因vw_user_role_graph上已经有了所有用户和角色,只需要结合dba_sys_privs视图依次关联出分配的权限就完成了。



这个结果和session_privs视图效果一样,不过session_privs视图只能查找出当前用户的权限;

另一方面,对象权限也存在类似的情况,直接用dba_users关联dba_tab_privs视图,得到的对象权限可能是不完整的;因为对于分配给角色的对象权限,在用户上直接查是得不到的,这就要求要先获得用户上的所有角色。


我们将scottemp表权限赋予Developer角色;


可以发现尽管用户dev1实际上对emp表有操作权限,却查不出记录。这里的权限被记录了在Developer角色上。

下面的语句,可以得到正确的结果:


从结果中我们还可以看出,用户dev2因没有Developer角色,也就表示它不能操作emp表。

到此我们就完成了用户的所有角色和权限处理。

未经允许不得转载:Oracle一体机用户组 » oracle获取用户角色与权限常见误区

相关推荐