1)权限,角色和用户的关系
权限(privilege):Oracle数据库预先定义好的、执行某些操作的能力。
角色(role):一组相关权限的集合。可以利用角色来简化权限的管理。
用户(user):通过给用户授予适当的权限或角色,用户就能够登录数据库,在数据库中执行特定的DDL和DML操作。通过回收权限或角色,就能减少用户对数据库的操作能力。
按照权限所针对的控制对象,可以将其分为系统权限、对象权限。
系统权限(system privilege):指在系统级控制数据库的存取和使用的机制,即执行某种SQL语句的能力。如,是否能启动、停止数据库,是否能修改数据库参数,是否能连接到数据库,是否能创建、删除、更改方案对象(如表、索引、视图、过程)等。它一般是针对某一类方案对象或非方案对象的某种操作的全局性能力。
例如,拥有SELECT ANY DICTIONARY权限,则可以查询数据字典中的以"DBA_"开头的数据字典视图。
GRANT SELECT ANY DICTIONARY TO SCOTT;
REVOKE SELECT ANY DICTIONARY FROM SCOTT;
拥有CREATE SESSION权限,才能够登陆数据库。
对象权限(object privilege):指在对象级控制数据库的存取和使用的机制,即访问其他用户的方案对象的能力。如,用户可以存取哪个用户的方案中的哪个对象,是否能对该对象进行查询、插入、更新等。对象权限一般是针对其他用户的某个特定的方案对象的某种操作的局部性能力。
例如,一般一个用户不能访问其他用户的对象,例如,MYUSER用户不能查询用户SCOTT用户的A表
GRANT SELECT ON A TO MYUSER;
但如果SCOTT用户将A表的SELECT对象权限授予MYUSER后,MYUSER用户就可以查询SCOTT用户的A表,但还是不能做任何更改操作。
应用程序、用户、权限、角色、数据库之间的关系如图所示。
可以用GRANT语句将系统权限、对象权限授予指定的用户、角色或者PUBLIC公共用户组。(PUBLIC公共用户组是一个在创建数据库时,就被自动创建的用户组。该用户组有什么权限,数据库中所有用户就有什么权限。可以利用这个特点,将公共权限授予数据库中所有的用户。)
权限的授予是可以传递的,已经具有某种权限的用户可以将他们的权限或其中一部份权限再授予或传递给其他用户。(在获取该权限时使用了WITH ADMIN OPTION选项(对于系统权限),或使用了WITH GRANT OPTION选项(对于对象权限),或该用户本身就具有GRANT ANY PRIVILEGE系统权限。)
可以使用REVOKE语句来回收系统权限和对象权限。
用户的权限信息被保存在数据字典中。
2)系统权限
可以通过SYSTEM_PRIVILEGE_MAP数据字典视图来查询Oracle数据库中的所有系统权限。
SELECT * FROM SYSTEM_PRIVILEGE_MAP; --所有系统权限,包括sysdba或sysoper系统权限
如果要授予系统权限,则用户必须具有此权限并且得到该系统权限时也得到了WITH ADMIN OPTION选项。
用户回收别的用户的系统权限时候,必须本身具有此系统权限,并且该系统权限上,得到了WITH ADMIN OPTION选项。
回收系统权限不会级联。
系统权限总的来说,一类是针对方案对象的,一类是针对非方案对象的。
针对方案对象的系统权限分为具有ANY关键字的(如 CREATE ANY TABLE)和不具有ANY关键字的(如CREATE TABLE)。
具有ANY关键字的系统权限表示可以在任何用户方案中进行操作(如在任何用户方案中都可以创建表);
不具有ANY关键字的系统权限表示只在自己的方案中进行操作(如在自己的方案中可以创建表)。
一般地,应该给数据库管理员授予带有ANY关键字的系统权限,以便其管理所有用户的方案对象。但不应该将其授予普通用户,以防其影响其他用户的工作。
针对非方案对象的系统权限都没有ANY关键字,如CREATE TABLESPACE。因为它们只与数据库管理中全局的、唯一的数据库维护操作有关,而与局部的、非唯一的方案对象操作无关,如表空间是针对数据库的全局的概念,不是针对哪个用户的局部的概念。
为了保护数据字典基础表的安全,Oracle提供了数据字典基础表的保护机制。对数据字典基础表的访问只局限于拥有SYSOPER或SYSDBA系统权限的用户。并提供了一个初始化参数 O7_DICTIONARY_ACCESSIBILITY来控制普通用户对数据字典基础表的访问。
ALTER SYSTEM SET O7_DICTIONARY_ACCESSIBILITY=TRUE SCOPE=SPFILE; --需重启数据库使生效
O7_DICTIONARY_ACCESSIBILITY=TRUE时,一个具有ANY TABLE系统权限的用户可以访问sys用户的对象,包括数据字典基础表。O7_DICTIONARY_ACCESSIBILITY=FALSE时,一个具有ANY TABLE系统权限的用户就只能访问除sys用户之外的其他用户的对象,也就无权访问数据字典基础表。
通过设置O7_DICTIONARY_ACCESSIBILITY=FALSE,并将SELECT ANY DICTIONARY系统权限授予非sys用户,既可以使其能查询数据字典视图和动态性能视图,又可以使其不能访问数据字典基础表。(此时,sys用户连接到数据库时必须指定AS SYSOPER或AS SYSDBA选项,否则不需要)
查看系统权限:
SELECT * FROM DBA_SYS_PRIVS; --授予给所有用户和角色的系统权限
SELECT * FROM USER_SYS_PRIVS; --授予给当前用户的系统权限
SELECT * FROM USER_ROLE_PRIVS; --授予给当前用户的角色(或FROM DBA_ROLE_PRIVS WHERE GRANTEE=...)
SELECT * FROM ROLE_SYS_PRIVS; --此视图包含了授予给当前用户的角色的系统权限的信息
SELECT * FROM SESSION_PRIVS; --当前会话可以使用的系统权限(包括直接授予的和通过角色授予的系统权限)
SELECT * FROM SESSION_ROLES;--当前会话可以使用的角色。包括嵌套授权的角色。例如将DBA角色授予了一个用户,DBA角色已经被授予的角色(例如SELECT_CATALOG_ROLE等)也会被查询出来
--一般情况下,下面2条语句执行结果是等价的
1. SELECT DISTINCT(PRIVILEGE) FROM ROLE_SYS_PRIVS UNION SELECT DISTINCT(PRIVILEGE) FROM USER_SYS_PRIVS;
2. SELECT PRIVILEGE FROM SESSION_PRIVS;
SELECT * FROM SYSTEM_PRIVILEGE_MAP; --所有系统权限,包括sysdba或sysoper系统权限
SELECT * FROM V$PWFILE_USERS; --所有被授予sysdba或sysoper系统权限的用户信息
3)对象权限
Oracle数据库中总共有9种不同的对象权限。不同类型的对象有不同的对象权限。有些对象(如集群、索引、触发器、数据库连接)没有对应的对象权限,即他们是通过系统权限来控制的,例如,如要修改集群,用户必须要具有ALTER ANY CLUSTER系统权限。
如果是自己创建的对象,则具有该对象的所有对象权限。
如果要授予对象权限,则该对象必须是自己方案中的对象,或得到该对象权限时也得到了WITH GRANT OPTION选项。
WITH GRANT OPTION选项不能被授予角色。
授权者只能从自己授权的用户那里回收对象权限。
用户不能有选择性地回收列权限,必须首先回收该对象权限,然后再将合适的列权限授予用户。
假如基于一个对象权限创建了过程、视图,那么回收该对象权限后,这些过程、视图将变为无效。
回收对象权限会级联。
1. Alter(更改)
表上的ALTER权限保证在相关的表上执行ALTER TABLE或LOCK TABLE语句。可以重命名表、添加列、删除列、更改数据类型和列的长度,以及把表转换成一个分区(partitioned)表。
序列上的ALTER权限可以保证能够在相关序列上执行ALTER SEQUENCE语句,可以重设授权序列对象的最小值、增量和缓冲区大小
2. Delete(删除)
允许在授权对象上执行DELETE语句,以便从表或者视图中删除行。SELECT权限必须随同DELETE权限授予,否则被授权的人将不能够选择行,因此也就无法删除行。DELETE权限还允许被授权者锁定相应的表
3. Execute(运行)
包上的EXECUTE权限允许被授权者执行或者使用在相应的包规定中声明的任何程序或者程序对象。
操作符(operator)或者类型(type)上的EXECUTE权限允许在SQL或者PL/SQL中使用该操作符。
数据库对象上的EXECUTE权限允许被授权者使用相关的数据库对象并且调用其方法。
4. Index(索引)
允许被授权者在相关的表上创建索引或者锁定该表。
当一个方案(schema)拥有一个表而另一个方案拥有其索引的时候,会出现混乱。在授予这种权限时要小心。
5. Insert(插入)
允许被授权者在相关的表或视图中创建行。
如果该INSERT权限建立在相关表或者视图的特定列上,则只能在具有INSERT权限的列上插入数据。
INSERT权限还隐含地给被授权者以锁定该表的能力
6. Read(读)
只能在目录上授予。
允许被授权者读取指定目录中的BFILE。
Read权限与SELECT权限有区别,后者允许用户读取一个表或者视图。
7. Reference(引用)
只能在表上授予用户,而不能授予角色。
允许被授权者创建引用该表的参照完整性约束。被授权者可以锁定该表。
8. Select(选择)
允许被授权者在表或者视图上执行SELECT语句。
允许被授权者读取表或者视图的内容。
SELECT权限只能授予整个表,不能授予表中的列。因此,如果希望用户只能查询表中的部分列,就需要在该表上创建视图,然后将该视图的SELECT权限授予用户。
序列上的SELECT权限允许被授权者获取当前值(CURRVAL)或者通过选择NEXTVAL增大该值。
9. Update(更新)
允许被授权者更改表或者视图中的数据值。SELECT权限必须随同UPDATE权限一起授予,这样就使被授权者隐含具有了锁定表的能力。
10. All(所有)
对于可以具有多项权限的对象,可以授予或者撤消专门的权限ALL。
例如,对于表而言,ALL中包含了SELECT、INSERT、UPDATE和DELETE以及INDEX、ALTER和REFERENCE。所以,在表上授予AIL权限时要小心,因为可能并不想授予INDEX、ALTER和REFERENCE权限。
对象、对象权限的对应关系如下:
对象 |
对象权限 |
||||||||
Alter 更改 |
Delete 删除 |
Execute 运行 |
Index 索引 |
Insert 插入 |
Read 读 |
Reference 引用 |
Select 选择 |
Update 更新 |
|
Directory目录 |
√ | ||||||||
Function函数 |
√ |
||||||||
Procedure子程序 |
√ |
||||||||
Package包 |
√ |
||||||||
DB Object数据库对象 |
√ |
||||||||
Library库 |
√ |
||||||||
Operator操作符 |
√ |
||||||||
Sequence序列 |
√ |
√ |
|||||||
Table表 |
√ |
√ |
√ |
√ |
√ |
√ |
√ |
||
Type类型 |
√ |
||||||||
View视图 |
√ |
√ |
√ |
查看用户对象权限:
视图 |
说明 |
DBA_TAB_PRIVS ALL_TAB_PRIVS USER_TAB_PRIVS |
DBA视图包含了数据库中所有用户或角色的对象权限 ALL视图包含了当前用户或PUBLIC的对象权限 USER视图列出当前用户的对象权限 |
DAB_COL_PRIVS ALL_COL_PRIVS USER_COL_PRIVS |
DBA视图描述了数据库中的所有用户或角色的列对象权限 ALL视图描述了当前用户或PUBLIC是其所有者、授予者或被授予者的,所有的列对象权限 USER视图描述了当前用户是其所有者、授予者或被授予者的,所有的列对象的权限 |
ALL_COL_PRIVS_MADE USER_COL_PRIVS_MADE |
ALL视图列出了当前用户是其所有者、授予者的,所有的列对象权限 USER视图描述了当前用户是其授予者的,所有的列对象权限 |
ALL_COL_PRIVS_RECD USER_COL_PRIVS_RECD |
ALL视图描述了当前用户或PUBLIC是其被授予者的,所有的列对象的权限 USER视图描述了当前用户是其被授予者的所有的列对象的权限 |
ALL_TAB_PRIVS_MADE USER_TAB_PRIVS_MADE |
ALL视图列出了当前用户所做的所有的对象授权或者是在当前用户所拥有的对象上的授权 USER视图列出了当前用户所做的所有对象上的授权 |
ALL_TAB_PRIVS_RECD USER_TAB_PRIVS_RECD |
ALL视图列出了当前用户或PUBLIC是被授予者的对象权限 USER视图列出了当前用户是被授予者的对象权限 |
ROLE_TAB_PRIVS |
包含了授予角色的对象权限。它提供的只是该用户可以访问的角色的信息 |
4)用户
可以通过以下数据字典视图来查询用户信息。
SELECT * FROM DBA_USER;
SELECT * FROM ALL_USERS;
SELECT * FROM USER_USERS;
5)安全策略
Oracle 8i中引入了虚拟专用数据库(Virtual Private Database,VPD)的概念。只要将这个概念与安全应用环境(application context)(也称为应用上下文)相结合,就能实现精细访问控制。只需制定出相应的安全策略(security policy),就能对每个用户所能访问的数据进行控制。只需要在数据库服务器上创建一次安全策略就可以了。无论用户采用何种连接方式(如通过应用程序、通过SQL*Plus),安全策略都会起作用,并且安全策略对用户是透明的。
可以利用数据字典视图查询安全策略:
DBA_POLICIES,ALL_POLICIES,USER_POLICIES
可以启用/禁用、删除安全策略(利用DBMS_RLS包)。