经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » 数据库运维 » Oracle » 查看文章
Oracle 12c用户和安全管理
来源:cnblogs  作者:Leohahah  时间:2018/9/25 19:51:05  对本文有异议
前言:

Oracle 12c的多租户(multitenant)环境与SQL Server的架构非常相似,CDB$ROOT类似于master、PDB$SEED类似于model、各个pluggable database就相当于普通的业务库。
官方宣传了12c的很多好处但其实没卵用,12c设想通过合并多个库来避免DBLINK的性能问题,但其实还是通过压榨单一服务器来实现的,其他好处诸如PDB迁移方便、JSON支持、资源组、索引压缩、in-memory支持等等要么是炒冷饭,要么实际适用场景很少,不过这些新特性都还有待继续研究,一步一步来。
首先必须要解决的是登录问题,12c的多租户环境下用户与以前不同了,以前的用户性质都是一样的,而在12c中一个实例下可以有多个可插拔的数据库,因此用户管理与之前就有很大区别了,本文介绍12c用户及其管理,以12.2.0.1版本为例,所有观点来源于如下官网链接:
本文主要包含以下六个部分:
  • 关于用户安全的简易说明
  • 创建用户
  • 更改用户
  • 配置用户资源限额
  • 删除用户
  • 用户和profile的的数据字典
一、关于用户安全的简易说明:

每个数据库都有自己的用户列表,在创建用户时你可以为这个用户设置一系列的登录limits或resource limits,或者使用profile实现此功能,profile就是一个用户所拥有的属性的集合,你可以查看dba_profiles来详细了解。
此外你还可以为用户赋予一系列的权限和角色,参考:Configuring Privilege and Role Authorization
 
二、创建用户

这部分涉及的内容很多,保险起见还是全部列出来的比较好。
  • 关于Common User和Local User
在多租户的环境中,common user可以访问整个CDB而local user只能访问特定的PDB,关于CDB与PDB的关系这里用官网的一幅图来表示:

可以看到CDB其实就是指实例下的所有数据库,包含ROOT、Seed和其他所有PDBs,整个Instance可以看做一个容器,即Container DB(CDB).

你可以使用sysdba用户来启动PDB,有以下两种方式:
  1. 1.alter session set container=orclpdb1;
  2. alter database open;
  3. --对应关闭方式为shutdown immediate;
  4. 2.alter pluggable database orclpdb1 open;
  5. --对应关闭方式为alter pluggable database orclpdb1 close;
  6. Ps:PDB的关闭是指将PDBopen变为mount状态,彻底shutdown需要到root中关闭整个实例。

关于Common user:

Common user必须以C##或者c##开头,你可以通过修改common_user_prefix参数来更改这个prefix,而Local user则必须避免以这个prefix开头。
Common user的身份和密码对于每个PDB来说都是可见的,只要有合适的权限common user也可以操作PDB。
Common user通常用于在root中操作PDBs,例如插拔PDB数据库、更改PDB状态或者为CDB指定临时表空间等。
Common user只能在cdb$root中创建,cdb$root中也只能创建common user。
举例来讲,common user可做的操作有:创建或修改common/local user、向其他common/local user赋权限或者赋角色、对整个CDB执行ALTER DATABASE开头的恢复语句、通过ALTER PLUGGABLE DATABASE语句来来更改PDB的状态(必须是连接到CDB$ROOT库时)。当然一个local user如果有权限也可以更改其自身PDB的状态。
Oracle的系统用户如sys、system等,就是common user,即可操作ROOT数据库也可以操作任意PDB,除非某个PDB开启Vault-enabled来限制系统用户的权限。

当你将一个non-CDB的数据库作为PDB插入到CDB中时:

  1. non-CDB的系统用户将会与CDB common user合并,即non-CDB中的系统用户将会新增到CDB中,如果username冲突则不新增,这些冲突系统用户的密码全部按照CDB的来,原密码失效。
  2. 如果你曾经更改过原non-CDB系统用户的权限,那么合并之后这些差异权限只对这个PDB生效,对其他PDB无效。这里还不知道如果少了权限合并之后是不是依然少,有需要的时候再测试下好了。
当你将一个PDB插入CDB时:
  1. 原PDB的common user会失去它所有的公共权限,包括set container的权限。
  2. 如果目标CDB有与PDB同名的common user,那么这两个common user合并,CDB的common user密码优先生效。而PDB中其他不同名的common user将会被锁定。你可以对这些锁定的common user做如下任意一种处理:
    • 不处理这些locked用户,在权限适当的情况下你依然可以使用这些schema下的对象。
    • 使用EXPDP导出这些用户下的数据并导入到另一个用户下,然后删掉此locked user。
    • 关掉PDB,连接到CDB$ROOT,创建同名的common user,然后重开PDB,Oracle会自动处理权限差异,此时你可以unlock这些用户,他们的本地权限保持不变。
关于Local user:
Local user就是只存在于PDB中的用户,local user可以拥有管理类权限,但是这类权限只对local user所在的PDB有效。
Local user与common user的区别可以概括为以下几点:
  1. Local user不能创建common user,也不能在cdb$root中被授予权限。而common user只要有合适的权限,就能创建、修改common/local user,就能公共的或本地的grant/revoke权限。Local user如果权限充足,可以创建、修改local user,也可以在PDB中向common/local user赋权限。
  2. 你可以向local user赋予公共角色或权限(类似于select any table这种),但是这些公共角色或权限包含的权限只对其所属PDB有效。
  3. Local user在一个PDB中应当是唯一的。
  4. 如果local user有合适的权限,那么它也可以访问common user里的对象。
  5. Local user只能在PDB中被创建,PDB中也只能创建local user而不能创建common user。
  6. 你可以根据版本来选择是否禁用local user,但是却不能这么操作common user。
  • 创建用户示例
创建common user:
  1. $ sqlplus / as sysdba
  2. SQL> show pdbs;
  3. CON_ID CON_NAME OPEN MODE RESTRICTED
  4. ---------- ------------------------------ ---------- ----------
  5. 2 PDB$SEED READ ONLY NO
  6. 3 ORCLPDB1 READ WRITE NO
  7. 4 ORCLPDB2 MOUNTED
  8. SQL> show con_name
  9. CON_NAME
  10. ------------------------------
  11. CDB$ROOT
  12. SQL> alter pluggable database orclpdb1 open;
  13. Pluggable database altered.
  14. SQL> create user c##test identified by test container=all;
  15. --common user只能以c##开头,且强制container=all,创建时可以不用写container=all。
  16. SQL> grant dba to c##test;
  17. --至此common user c##test创建完毕,但是目前为止这个common user只能操作CDB$ROOT schema对象下的objects和创建PDB的local user,并没有操作PDB下objects的权限,一般来说common user不必有此权限,但是如果你想拥有,那么:
  18. SQL> alter session set container=orclpdb1; --切换至orclpdb1PDB后再次grant权限
  19. SQL> grant dba to c##test;
  20. --至此common user c##test就拥有了操作PDB orclpdb1下objects的权限了。但是这种common user删除时必须添加cascade:
  21. SQL> drop user c##test;
  22. drop user c##test
  23. *
  24. ERROR at line 1:
  25. ORA-65048: error encountered when processing the current DDL statement in pluggable database ORCLPDB1
  26. ORA-01922: CASCADE must be specified to drop 'C##TEST'
  27. SQL> drop user c##test cascade;
  28. User dropped.

创建local user:

  1. $ sqlplus / as sysdba
  2. SQL> alter session set container=orclpdb1;
  3. SQL> create user test identified by test default tablespace users quota 100M on example quota 200M on test temporary tablespace temp profile default container=current;
  4. --local user只能以非c##开头,且强制container=current,创建时可以不用写container=current。
  5. SQL> grant connect,resource,unlimited tablespace to test;
  6. $ sqlplus test/test@localhost/orclpdb1
  7. --至此local user创建完毕。
  8. --需要特别注意的一点是:12cresource角色中已经不包含unlimited tablespace权限因此需要单独赋予,或者通过quota项来分配一定的表空间限额。
  • 创建用户总结:
一般来说没有必要创建除系统用以外的common user,或者只需要创建一个不含操作具体PDB权限的common user,common user不应当用于操作具体业务数据,正如官方说明的那样,common user通常的操作应当是:
  创建或修改common/local user、向其他common/local user赋权限或者赋角色、对整个CDB执行ALTER DATABASE开头的恢复语句、通过ALTER PLUGGABLE DATABASE语句来来更改PDB的状态(必须是连接到CDB$ROOT库时)。
我们可以使用如下SQL来查看PDB或CDB$ROOT库内的用户:
  1. $ sqlplus / as sysdba
  2. SQL> alter session set container=orclpdb1;
  3. SQL> set lines 200
  4. SQL> set pages 100
  5. SQL> col username for a40
  6. SQL> select USERNAME,ACCOUNT_STATUS,COMMON from dba_users;
  7. --结果可以看到common user是在所有PDB中可见的,在单个PDB中查询dba_users你能看到所有common user和属于本PDBlocal user

再来考虑一种特殊情况,假如我们需要在一个PDB中访问另一个PDB中的数据呢?
使用local user是不可能的,因为local user完全PDB隔离,就算local user被赋予了类似dba、select any table这些公共权限,也只是在PDB内有效,无法跨库访问,那么只能使用common user。

接下来举例common user跨PDBs访问:

  1. SQL> show pdbs;
  2. CON_ID CON_NAME OPEN MODE RESTRICTED
  3. ---------- ------------------------------ ---------- ----------
  4. 2 PDB$SEED READ ONLY NO
  5. 3 ORCLPDB1 READ WRITE NO
  6. 4 ORCLPDB2 READ WRITE NO
  7. --我们有两个PDBorclpdb1orclpdb2都是open状态,各自有一个scott用户,用户下分别有一个test1test2表。我们先创建一个common user
  8. $ sqlplus / as sysdba
  9. SQL> create user c##scott identified by tiger;
  10. SQL> grant connect,resource,unlimited tablespace,select any table,create view to c##scott;
  11. --然后在orclpdb1中给c##scott赋权限
  12. SQL> alter session set container=orclpdb1;
  13. SQL> grant connect,resource,unlimited tablespace,select any table,create view to c##scott;
  14. --接下来在orclpdb2中给c##scott赋权限
  15. SQL> alter session set container=orclpdb2;
  16. SQL> grant connect,resource,unlimited tablespace,select any table,create view to c##scott;

至此c##scott用户就有了在两个pdb中查询的权限,但是此权限是严格PDB隔离的,不能跨库查询。虽然不能像SQL Server那样跨库直接查询,不过oracle却提供了变通的办法--CONTAINERS子句,参考网址如下(此特性开始于12.1.0.2版本):

举例:SELECT ename FROM CONTAINERS(scott.emp) WHERE CON_ID IN (45, 49);

想要使用CONTAINERS子句必须满足以下条件:

1.CONTAINERS子句中的表、视图或同义词必须在ROOT和所有PDB中都存在。
2.CONTAINERS子句中涉及的表、视图的属主必须是执行SQL语句的common user;如果是同义词,那么这个同义词必须是引用的此common user下的表或视图。
3.包含CONTAINERS子句的SQL必须在CDB$ROOT数据库下使用common user执行。

如果CONTAINERS子句涉及的表里有以下列类型,那么会被自动过滤掉:

1.用户定义的类型:object types, varrays, REFs, and nested tables
2.系统类型:ANYTYPE, ANYDATASET, URI types, SDO_TOPO_GEOMETRY, SDO_GEORASTER, and Expression
看完以上5条要求后突然发现这些要求很奇葩,如果CONTAINERS子句中的表、视图或同义词必须在ROOT和所有PDB中都存在,那我还为什么还要跨PDB查询,直接在ROOT中查不就得了?

稍微思考和实践了一下,发现使用CONTAINERS子句的条件应该是:

  • 必须使用common user在CDB$ROOT中查询
  • CONTAINERS()方法的输入是表、视图或同义词,这个对象必须在CDB$ROOT中有个名称+结构完全相同的对象,无论是表还是视图还是同义词,表可以没有数据。
  • 必须使用执行此查询的common user到表所在的PDB中创建一个同名view,这需要common user拥有查询此表的权限。

那么接着上边的实例就可以很容易的进行跨PDB查询了:

  1. 1.首先我们使用common user c##scott在orclpdb1中创建针对scott.test1的视图:
  2. $ sqlplus c##scott/tiger@orclpdb1
  3. SQL> create view test1 as select * from scott.test1;
  4. 2.然后使用common user c##scott在CDB$ROOT中创建同名的表或者视图:
  5. $ sqlplus c##scott/tiger
  6. SQL> create table test1(name varchar2(20));
  7. 3.此时我们就可以使用SQL查询了:
  8. SQL> select * from CONTAINERS(test1) where con_id=3;
  9. 4.如果还需要联结查询orclpdb2中的test2表,那么:
  10. $ sqlplus c##scott/tiger@orclpdb2
  11. SQL> create view test2 as select * from scott.test2;
  12. $ sqlplus c##scott/tiger
  13. SQL> create table test2(name varchar2(20));
  14. 5.这样就相当于test1test2CDB$ROOT中都有了一个接口,我们通过接口访问相应PDB中的common user下的视图,视图又是直接定义在最终表上的。
 
画一幅图来直观的表示:

 

三、修改用户

修改用户与创建用户的语法很相似:
  1. --一个官方示例:
  2. ALTER USER c##hr_admin
  3. DEFAULT TABLESPACE data_ts
  4. TEMPORARY TABLESPACE temp_ts
  5. QUOTA 100M ON data_ts
  6. QUOTA 0 ON test_ts
  7. SET CONTAINER_DATA = (emp_db, hr_db) FOR V$SESSION
  8. CONTAINER = CURRENT;
  9. --有以下几个地方需要解释:
  10. 1.QUOTA的大小表示在表空间上限额的总大小,而非增/减量。
  11. 2.SET CONTAINER_DATA表示此common userroot中访问v$session时可以获取到emp_dbhr_db相关的session信息。

此外一般用户的密码可以通过alter user语句修改,而sys密码可以通过orapwd工具修改:

  1. orapwd file='orapworcl' force=y
  2. orapwd input_file='orapworcl' file='orapwd' sys=y force=y
 
四、配置用户资源限额

这点可以通过一个视图很容易的看到:

因此修改用户资源限额就很简单了,例如:
  1. alter user scott limit password_life_time unlimited;
  2. --或者新建一个profile,然后将其指定为用户的profile
  3. CREATE PROFILE profile_scott LIMIT
  4. FAILED_LOGIN_ATTEMPTS 6
  5. PASSWORD_LIFE_TIME 60
  6. PASSWORD_REUSE_TIME 60
  7. PASSWORD_REUSE_MAX 5
  8. PASSWORD_LOCK_TIME 1/24
  9. PASSWORD_GRACE_TIME 10
  10. PASSWORD_VERIFY_FUNCTION DEFAULT;
  11. alter user scott profile profile_scott;

五、删除用户


六、用户和profile涉及的数据字典

  1. ALL_OBJECTS
  2. Describes all objects accessible to the current user
  3. ALL_USERS
  4. Lists users visible to the current user, but does not describe them
  5. DBA_PROFILES
  6. Displays all profiles and their limits
  7. DBA_TS_QUOTAS
  8. Describes tablespace quotas for users
  9. DBA_OBJECTS
  10. Describes all objects in the database
  11. DBA_USERS
  12. Describes all users of the database
  13. DBA_USERS_WITH_DEFPWD
  14. Lists all user accounts that have default passwords
  15. PROXY_USERS
  16. Describes users who can assume the identity of other users
  17. RESOURCE_COST
  18. Lists the cost for each resource in terms of CPUs for each session, reads for each session, connection times, and SGA
  19. USER_PASSWORD_LIMITS
  20. Describes the password profile parameters that are assigned to the user
  21. USER_RESOURCE_LIMITS
  22. Displays the resource limits for the current user
  23. USER_TS_QUOTAS
  24. Describes tablespace quotas for users
  25. USER_OBJECTS
  26. Describes all objects owned by the current user
  27. USER_USERS
  28. Describes only the current user
  29. V$SESSION
  30. Lists session information for the current database session
  31. V$SESSTAT
  32. Displays user session statistics
  33. V$STATNAME
  34. Displays decoded statistic names for the statistics shown in the V$SESSTAT view
 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号