Oracle Database 12C带来了新特性多租户功能,在此之上,权限和角色也有新的变化,接下来将讲解基于新特性下的赋予权限和角色。
1.公共角色
公共角色既可以存在于CDB root中,也可以存在于Application root中,同时应用于在root容器中的所有PDB。基于此特点,对于跨容器操作,公共角色是非常有用的,在操作之前要确保公共角色在每个PDB中都有角色。
公交角色的类型有2种:
1.Oracle自己提供的,例如DBA和PUBLIC。
2.用户自己创建的,在CDB root或者Application root下,通过CREATE ROLE ... CONTAINER = ALL语句创建,角色前缀必须是COMMON_USER_PREFIX,其默认值是c##或C##。
角色的作用范围取决于定义这个角色的容器,如果在CDB root下定义,那么其范围就是整个CDB。如果在Application root下定义,那么其范围就是整个Application容器。
2.本地角色
通过CREATE ROLE ... CONTAINER = CURRENT(CONTAINER = CURRENT是默认值)创建的角色是本地角色,该角色只存在于单一的PDB中,其作用范围也只限于所定义的PDB中。例如,在PDB1中创建了本地角色pdbrole,那么pdbrole就被限制于PDB1中,在其他PDB中是不可用的。
属于同一CDB或Application容器的PDB,可以创建相容名字的角色。例如,pdbrole创建于PDB1中,在PDB2中也可以创建相容名字的本地角色pdbrole。
3.赋予角色和权限
在CDB模式下,只有2种方式去赋予权限和角色,公共方式和本地方式。
1.公共方式:GRANT ... TO USER CONTAINER=ALL
2.本地方式:GRANT ... TO USER CONTAINER=CURRENT
权限和角色如果以公共方式被赋予,那么其作用范围就在整个容器内,包括现有的PDB和未来新创建的PDB;如果以本地方式被赋予,那么其作用范围就在当前容器内。
用户和角色可能是公共的或者本地的,但权限并不这样区分。在CDB中,当前的容器是CDB root,那么以公共方式赋权,那就意味着在整个CDB中都是有效的,包括容器下的所有PDB和未来创建的PDB,如果以本地方式赋权,那就意味着只在当前容器有效。
下面来举例来说明:
1) 创建公共角色c##user1,并以本地方式赋予create session权限
2) 创建公共角色c##role1,并本地方式赋予select any table权限
3) 本地方式将c##role1赋予c##user1
4) c##user1连接pdb1,连接失败,缺少create session权限,这是因为本地方式赋予c##user1的create session只在CDB root中有效
5) 连接pdb1,本地方式赋予c##user1权限connect和resource,再次用c##user1连接pdb1,连接成功
6) 查询表现有表scott.emp,查询失败,报出表或视图不存在错误
7) 在CDB root下,公共方式赋予c##role1权限select any table,再次c##user1连接pdb1,并查询scott.emp,但还是报错
8) 在CDB root下,公共方式赋予c##user1角色c##role1,再次c##user1连接pdb1,并查询scott.emp,终于成功