对象的访问权限知识点
对象的分类
在数据库中,数据库的表、索引、视图、缺省值、规则、触发器等等、都可以被称为数据库对象,其中对象主要分为两类
1、模式(schema)对象:模式对象可以理解为一个存储目录、包含视图、索引、数据类型、函数和操作符等。也就是放在模式下的对象,都被叫做模式对象
2、非模式对象:其他的数据库对象、如数据库、表空间、用户
对象访问权限概述
1、对象都会有owner(所有者),所有者一般是对象的创建者,但所有者是可以被改变的;如使用root用户创建了一个目录,该目录当前的所有者是root,当然还可以使用chown命令来将所有者改为kingbase
2、初始转态下,只有所有者(或者超级用户)呢个够对改对象执行任何操作
3、其他用户和角色想要使用该对象,需要被授予相关的权限
定义访问权限(GRANT 权限 ON 对象类型 对象名 TO 用户/角色)
定义访问权限,相当与给予某个用户或角色权限:记住GRANT 权限 ON 对象类型 对象名 TO 用户/角色,即给用户/角色授予针对某个对象的某种权限
授予权限主要是使用GRANT来授权,但不同的对象类型支持的权限类型是有差异的
1、针对数据库的授权
在此之前,我们应该先明白数据库具有什么权限,才能为数据库进行正确的授权
语法:GRANT [CREATE | CONNECT | TEMPORARY | TEMP |…| ALL [PRIVILEGES] ]
ON DATABASE database_name;给哪个数据库权限
TO role_specification;给哪个用户
权限 | 描述 |
---|---|
CRETAE | 在数据库下创建对象的权限 |
CONNECT | 连接数据库的权限 |
TEMPORARY | 在数据库下创建临时表 |
TEMP | 在数据库下创建临时表 |
2、针对模式的授权
GRANT [ CREATE | USAGE |…| ALL [PRIVILEGES] ]
ON SCHEMA schema_name;给哪个模式授权
TO role_specification;给哪个用户授权
权限 | 描述 |
---|---|
CREATE | 在这个模式下可以再创建对象 |
USAGE | 因为模式相当与一个文件夹,当有了usage权限后就可以进入该文件夹内 |
3、针对表空间授权
GRANT [ CREATE | ALL [ PRIVILEGES ] ]
ON TABLESPACE tablespace_name
TO role_specification
4、针对表的授权
GRANT [ SELECT | INSERT | UPDATE | TRUNCATE | REFERENCES | TRIGGER | DELETE |…| ALL [PRIVILEGES]]
ON { [ TABLE ] table_name
| ALL TABLES IN SCHEMA schema_name }
TO role_specification
权限 | 描述 |
---|---|
SELECT | 查询 |
INSERT | 插入 |
UPDATE | 更新 |
TRUNCATE(truncate) | 截断,快速删除表中的所有数据 |
REFERENCES(references) | 外键约束,在表中创建一个字段 |
TRIGGER(trigger) | 触发器 |
EDLETE | 删除 |
5、针对列的授权
GRANT { [ SELECT | INSERT | UPDATE | REFERNCES] ( column_name […] ) […] | ALL [PRIVILEGES] ( colume_name […] ) }
ON [ TABLE ] table_name
TO role_specification
6、针对序列的授权
GRANT { [ USAGE | SELECT | UPDATE ] … [ ALL [PRIVILEGES ]]}
ON { SEQUENCE sequence_name
| ALL SEQUENCES IN SCHEMA schema_name }
TO role_specification
7、针对函数的授权
GRANT { EXECUTE | ALL [PRIVILEGES ] }
ON { FUNCTION function_name ( [ argmode [arg_name] arg_type ] ) | ALL FUNCTIONS IN SCHEMA schema_name }
TO role_specfication
移除访问权限(REVOKE 权限 ON 对象类型 对象名 TO 用户/角色)
移除访问权限,就是针对某个用户或角色去除它的权限,记住:REVOKE 权限 ON 对象类型 对象名 TO 用户/角色,即给用户/角色去除针对某个对象的某种权限
1、针对数据库的授权
REVOKE [ GRANT OPTION FOR ] [CREATE | CONNECT | TEMPORARY | TEMP |…| ALL [PRIVILEGES] ]
ON DATABASE database_name;给哪个数据库权限
FROM { [ GROUP ] role_name | PUBLIC } […] [ CASCADE | RESTRICT ]
2、针对模式授权
REVOKE [ GRANT OPTION FOR ] [ CREATE | USAGE |…| ALL [PRIVILEGES] ]
ON SCHEMA schema_name;给哪个模式授权
FROM { [ GROUP ] role_name | PUBLIC } […] [ CASCADE | RESTRICT ]
3、针对表空间授权
REVOKE [ GRANT OPTION FOR ] [ CREATE | ALL [ PRIVILEGES ] ]
ON TABLESPACE tablespace_name
FROM { [ GROUP ] role_name | PUBLIC } […] [ CASCADE | RESTRICT ]
4、针对表授权
REVOKE [ GRANT OPTION FOR ] [ SELECT | INSERT | UPDATE | TRUNCATE | REFERENCES | TRIGGER | DELETE |…| ALL [PRIVILEGES]]
ON { [ TABLE ] table_name
| ALL TABLES IN SCHEMA schema_name }
FROM { [ GROUP ] role_name | PUBLIC } […] [ CASCADE | RESTRICT ]
5、针对列的授权
REVOKE [ GRANT OPTION FOR ] { [ SELECT | INSERT | UPDATE | REFERNCES] ( column_name […] ) […] | ALL [PRIVILEGES] ( colume_name […] ) }
ON [ TABLE ] table_name
FROM { [ GROUP ] role_name | PUBLIC } […] [ CASCADE | RESTRICT ]
6、针对序列授权
REVOKE [ GRANT OPTION FOR ] { [ USAGE | SELECT | UPDATE ] … [ ALL [PRIVILEGES ]]}
ON { SEQUENCE sequence_name
| ALL SEQUENCES IN SCHEMA schema_name }
FROM { [ GROUP ] role_name | PUBLIC } […] [ CASCADE | RESTRICT ]
7、针对函数授权
REVOKE [ GRANT OPTION FOR ] { EXECUTE | ALL [PRIVILEGES ] }
ON { FUNCTION function_name ( [ argmode [arg_name] arg_type ] ) | ALL FUNCTIONS IN SCHEMA schema_name }
TO role_specfication
权限描述符
符号 | 全称 | 解释 |
---|---|---|
a | INSERT | 插入,针对表或视图进行 |
r | SELECT | 查询,针对表或视图进行 |
w | UPDATE | 更新,针对表或视图进行 |
d | DELECT | 删除,针对表或视图进行 |
D | TRUNCATE | 清空记录,针对表 |
x | REFERENCES | 参照引用,针对表 |
t | TRIGGER | 创建触发器,针对表 |
X | EXECUTE | 执行,针对存储过程(pl/sql对象) |
U | USAGE | 使用权,针对模式,可以进入到模式下 |
C | CREATE | 创建对象,针对模式或数据库 |
c | CONNECT | 创建连接,针对数据库 |
T | TEMPORARY | 创建临时表,针对数据库 |
如"user01=ar*/SYSTEM"
上述内容对应的是[被授权用户]=权限明细[*]/授权用户,其中[被授权用户]是user01
ar表示INSERT和SELECT,r*表示user01拥有r(SELECT)权限的转授权,SYSTEM说明user01的ar*权限是来自与SYSTEM用户的授权
"*"表示被授权用户拥有该权限的转授权(用于级联授权)
实验1:查看对象访问权限的主要方式
图形化界面查看权限
查看system对数据库的对象权限,右键[system]用户,点击[编辑用户],点击[对象权限]即可查看全部权限
通过"ksql元命令"来查看权限
查看数据库下的权限
登录system用户查看system对数据库的存储权限,可以使用"\l"来查看权限、
test=# \l数据库列表名称 | 拥有者 | 字元编码 | 校对规则 | Ctype | 存取权限
-----------+--------+----------+-------------+-------------+-------------------kingbase | system | UTF8 | zh_CN.UTF-8 | zh_CN.UTF-8 | security | system | UTF8 | zh_CN.UTF-8 | zh_CN.UTF-8 | template0 | system | UTF8 | zh_CN.UTF-8 | zh_CN.UTF-8 | =c/system +| | | | | system=CTc/systemtemplate1 | system | UTF8 | zh_CN.UTF-8 | zh_CN.UTF-8 | =c/system +| | | | | system=CTc/systemtest | system | UTF8 | zh_CN.UTF-8 | zh_CN.UTF-8 |
(5 行记录)
可以看到存储权限那一列中,就采用了权限描述符来描述权限的具体信息
如"system=CTc/system",其表示有system授予system权限,C允许创建数据库的权限,T允许创建临时表的权限,c允许连接的权限
查看模式下的权限
可以使用元命令"\dn+",可以从存储权限中看到权限描述符
如sso=UC/system;表示有system用户授予sso,U表示sso用户可以进入到模式下,C表示sso用户可以在模式下创建对象
test=# \dn+架构模式列表名称 | 拥有者 | 存取权限 | 描述
------------------+--------+------------------+------------------------anon | system | system=UC/system+| | | sso=UC/system | dbms_sql | system | | public | system | system=UC/system+| standard public schema| | =UC/system | src_restrict | system | system=UC/system+| | | sso=UC/system | sysaudit | system | system=UC/system+| | | sso=UC/system +| | | sao=UC/system +| | | =UC/system | sysmac | system | system=UC/system+| | | sso=UC/system +| | | =U/system | xlog_record_read | system | |
(7 行记录)
查看表下的权限
使用元命令"\dp"可以查看表的信息
test=# \dp存取权限架构模式 | 名称 | 类型 | 存取权限 | 列特权 | 策略
----------+-------------------------+------+-----------------------+--------+------public | sys_stat_statements | 视图 | system=arwdDxt/system+| | | | | =r/system | | public | sys_stat_statements_all | 视图 | system=arwdDxt/system+| | | | | =r/system | |
(2 行记录)
1、使用system用户登录test数据库
test=# \conninfo
以用户 "system" 的身份,通过套接字"/tmp"在端口"54321"连接到数据库 "test"
2、创建user01用户
test=# create user user01;
test=# alter user user01 password 'kingbase'
test-# ; //修改user01的密码
ALTER ROLE
3、在public模式下创建t01表(字段为id和name,类型分别为int和text)
test=# create table public.t01 (id int,name text);
CREATE TABLE
4、向t01表中插入数据
test=# insert INTO public.t01 values (100,'a'),(200,'b');
INSERT 0 2
test=# select * from public.t01
test-# ;id | name
-----+------100 | a200 | b
(2 行记录)
5、授权user01用户可查询t01表(第一行数据为100,‘a’;200,‘b’)
test=# grant SELECT on public.t01 TO user01;
GRANT
test=# \c - user01
您现在已经连接到数据库 "test",用户 "user01".
test=> select * from public.t01 ;id | name
-----+------100 | a200 | b
(2 行记录)
6、查看授权结果
test=# \dp public.t01 存取权限架构模式 | 名称 | 类型 | 存取权限 | 列特权 | 策略
----------+------+--------+-----------------------+--------+------public | t01 | 数据表 | system=arwdDxt/system+| | | | | user01=r/system | |
(1 行记录)
通过"数据字典"查看访问权限
数据字典是将数据库系统的信息组织到表中统一管理,也可称之数据字典表SystemCatalogTable,KES中的数据字典组织到Schema中
就是将数据库的全部信息全部都放在一张表内,以供我们查询,而这种表就被称为数据字典(类似与密码字典)
但是这种方法难度较大,需要记忆较多数据字典的视图以及其对应的字段
通过权限查询函数来查看访问权限
通过使用权限查询函数。来观察返回值是true还是flase
实验2:对象所有权限实验
查看表的所有者
使用"\dt+ table_name"可以查看表的拥有者
test=# \dt+ 关联列表架构模式 | 名称 | 类型 | 拥有者 | 大小 | 描述
----------+------+--------+--------+-------+------public | t01 | 数据表 | system | 16 kB | public | t02 | 数据表 | user02 | 16 kB |
(2 行记录)
验证对象的创建者默认就是对象的所有者
创建t02表
1、使用system用户身份登录test数据库
test=# \conninfo
以用户 "system" 的身份,通过套接字"/tmp"在端口"54321"连接到数据库 "test"
2、在public模式中创建t02表
test=# create table public.t02 (id int,name text);
CREATE TABLE
查看t02的所有者
test=# \dt+ public.t02 关联列表架构模式 | 名称 | 类型 | 拥有者 | 大小 | 描述
----------+------+--------+--------+------------+------public | t02 | 数据表 | system | 8192 bytes |
(1 行记录)
可以看到我们有system用户创建的t02表这个对象,那么t02表就是属于system用户的
改变对象的所有者
创建user02用户;查看t02表的所有者
test=# create user user02;
CREATE ROLE
test=# alter user user02 password 'kingbase';
ALTER ROLE
test=# \dt+ t02关联列表架构模式 | 名称 | 类型 | 拥有者 | 大小 | 描述
----------+------+--------+--------+------------+------public | t02 | 数据表 | system | 8192 bytes |
(1 行记录)
将t02表的拥有者修改为user02;查看t02表的所有者
test=# alter table public.t02 owner to user02;
ALTER TABLE
test=# \dt+ public.t02 关联列表架构模式 | 名称 | 类型 | 拥有者 | 大小 | 描述
----------+------+--------+--------+------------+------public | t02 | 数据表 | user02 | 8192 bytes |
可以看到经过我们修改之后,public模式下的t02表的拥有着从system更改到user02上
拥有者在对象上的特殊权限不能被授予或撤销
像DROP、GRANT、REVOKE这些特殊权限总是隐式地属于所有者,是不能直接查询到这些权限信息的,需要在使用数据字典来查看
使用元命令查看t02表的权限列表
test=# \dt+ public.t02 关联列表架构模式 | 名称 | 类型 | 拥有者 | 大小 | 描述
----------+------+--------+--------+------------+------public | t02 | 数据表 | user02 | 8192 bytes |
(1 行记录)
test=# \dp+ public.t02 存取权限架构模式 | 名称 | 类型 | 存取权限 | 列特权 | 策略
----------+------+--------+----------+--------+------public | t02 | 数据表 | | |
(1 行记录)
用数据字典查看t02表的权限列表
在数据字典内可以看到如DROP、GRANT等这些特殊权限的列表
test=# select * from information_schema.table_privileges where table_catalog='test' and table_schema='public' and table_name='t02'; grantor | grantee | table_catalog | table_schema | table_name | privilege_type | is_grantable | with_hierarchy
---------+---------+---------------+--------------+------------+----------------+--------------+----------------user02 | user02 | test | public | t02 | INSERT | YES | NOuser02 | user02 | test | public | t02 | SELECT | YES | YESuser02 | user02 | test | public | t02 | UPDATE | YES | NOuser02 | user02 | test | public | t02 | DELETE | YES | NOuser02 | user02 | test | public | t02 | TRUNCATE | YES | NOuser02 | user02 | test | public | t02 | REFERENCES | YES | NOuser02 | user02 | test | public | t02 | TRIGGER | YES | NO
(7 行记录)
最终验证对象拥有着的DROP、GRANT、REVOKE等特殊权限不能被授予或撤销
test=# revoke drop on TABLE t02 from user02;
错误: 未知的权限类型: "drop
test=# REVOKE GRANT ON TABLE t02 FROM user02;
错误: 语法错误 在 "ON" 或附近的
第1行REVOKE GRANT ON TABLE t02 FROM user02;
test=# GRANT drop on table t02 to user02;
错误: 未知的权限类型: "drop"
test=# GRANT revoke on table t02 to user02;
错误: 未知的权限类型: "revoke"
报错提示未知权限的原因是在普通的查询权限中根本是查不到DROP、GRANT等这种特殊权限的,所以才会显示未知权限
所有者或system可以撤销所有者在表中的普通权限
修改t02表的所有者user02用户的权限,只保留对t02表的查询权限
使用user02用户或system用户登录test数据库
1、撤销user02用户在t02表上的所有普通权限
test=# revoke all on TABLE t02 from user02;
REVOKE
2、授予用户user02对t02表的查询权限
test=# grant SELECT on TABLE t02 to user02;
GRANT
3、实验验证user02对t02表的权限
test=# insert INTO public.t02 values (100,'a');
INSERT 0 1
查看t02表的权限信息
test=# \dt+ public.t02 //查看public.t02的拥有者关联列表架构模式 | 名称 | 类型 | 拥有者 | 大小 | 描述
----------+------+--------+--------+-------+------public | t02 | 数据表 | user02 | 16 kB |
(1 行记录)
test=# \dp public.t02 //查看public.t02下的权限存取权限架构模式 | 名称 | 类型 | 存取权限 | 列特权 | 策略
----------+------+--------+-----------------+--------+------public | t02 | 数据表 | user02=r/user02 | |
(1 行记录)
可以看到原本user02是t02的所有者,应该拥有全部的普通权限,但我们依然可以撤销user02的普通权限,并且再加上select的权限给user02
实验3:授权普通用户访问对象
实验准备
1、再schema为public下创建测试表t03,其中t03的字段分别为id和name,类型分别为int和text
test=# create table public.t03 (id int,name text);
CREATE TABLE
2、创建user03用户,密码为kingbase
test=# create user user03 password 'kingbase';
CREATE ROLE
授予用户访问数据库的权限
1、给user03授予可以连接数据库test的权限
test=# grant CONNECT ON DATABASE test TO user03;
GRANT
2、查看test数据库的权限列表
test=# \l test 数据库列表名称 | 拥有者 | 字元编码 | 校对规则 | Ctype | 存取权限
------+--------+----------+-------------+-------------+-------------------test | system | UTF8 | zh_CN.UTF-8 | zh_CN.UTF-8 | =Tc/system +| | | | | system=CTc/system+| | | | | user03=c/system
(1 行记录)
授予用户访问模式(schema)的权限
1、授予user03用户可以访问public模式
test=# grant USAGE ON SCHEMA public TO user03;
GRANT
2、查看public模式的权限列表
test=# \dn+ public 架构模式列表名称 | 拥有者 | 存取权限 | 描述
--------+--------+------------------+------------------------public | system | system=UC/system+| standard public schema| | =UC/system +| | | user03=U/system |
(1 行记录)
授予用户访问表的权限
1、授权user03可以查询t03表
test=# grant SELECT ON TABLE public.t03 TO user03;
GRANT
2、查看t03表的权限列表
test=# \dp public.t03存取权限架构模式 | 名称 | 类型 | 存取权限 | 列特权 | 策略
----------+------+--------+-----------------------+--------+------public | t03 | 数据表 | system=arwdDxt/system+| | | | | user03=ar/system | |
(1 行记录)
授予用户先表中插入数据的权限
1、授予user03可以向t03表插入数据
test=# grant INSERT ON TABLE public.t03 TO user03 ;
GRANT
2、查看t03表的权限列表
test=# \dp public.t03存取权限架构模式 | 名称 | 类型 | 存取权限 | 列特权 | 策略
----------+------+--------+-----------------------+--------+------public | t03 | 数据表 | system=arwdDxt/system+| | | | | user03=ar/system | |
(1 行记录)
如图,user03=ar/system表示有system用户授予user03,"a"插入权限。"r"查询权限
验证
1、使用user03用户登录test数据库
test=# \c test user03
您现在已经连接到数据库 "test",用户 "user03".
test=> \conninfo
以用户 "user03" 的身份,通过套接字"/tmp"在端口"54321"连接到数据库 "test"
2、user03用户能查询t03表
test=> select * from public.t03 ;id | name
----+------
(0 行记录)
3、user03能先t03表中插入数据,插入数据为(1,‘a’)和(2,‘b’)
test=> select * from public.t03 ;id | name
----+------1 | a2 | b
(2 行记录)
收回public角色的默认权限
查看public角色拥有的默认权限
1、查看public角色再test数据库中的权限
其中"=Tc"表示public角色内的所有用户对test数据库拥有Tc权限
补充说明:T表示TEMPORARY拥有临时创建表权限,c表示CONNECT拥有连接权限
test=> \l test数据库列表名称 | 拥有者 | 字元编码 | 校对规则 | Ctype | 存取权限
------+--------+----------+-------------+-------------+-------------------test | system | UTF8 | zh_CN.UTF-8 | zh_CN.UTF-8 | =Tc/system +| | | | | system=CTc/system+| | | | | user03=c/system
(1 行记录)
2、查看public角色在public模式中的权限
注:"=UC"表示public角色内的所有用户对public模式拥有UC权限
"U"表示USAGE能够进入public模式下,"C"表示能在public模式下创建对象
test=> \dn+ public 架构模式列表名称 | 拥有者 | 存取权限 | 描述
--------+--------+------------------+------------------------public | system | system=UC/system+| standard public schema| | =UC/system +| | | user03=U/system |
(1 行记录)
验证public角色拥有的默认权限
注:所有用户默认都属于public,所有用户默认能登录test库,能在public模式下创建对象
1、使用system用户登录test数据库,创建user04用户
您现在已经连接到数据库 "test",用户 "system".
test=# \conninfo
test=# create user user04 password 'kingbase';
CREATE ROLE
2、使用user04登录test数据库,使用user04在public模式下创建表t04
test=> \conninfo
以用户 "user04" 的身份,通过套接字"/tmp"在端口"54321"连接到数据库 "test"
test=> create table public.t04 (id int,name text);
CREATE TABLE
收回public角色在test数据库的默认权限
1、使用system登录test数据库,回收public角色在test数据库的所有权限
test=# revoke all ON DATABASE test FROM PUBLIC ;
REVOKE
查看test数据库的权限列表,此时应该"UC/system"已经消失
2、验证,此时user04已经无权登录test数据库了
test=# \c test user04
致命错误: 访问数据库"test"的权限不够
描述: 用户没有CONNECT权限.
保留上一次连接
回收public角色在public模式中的默认权限
1、显式的授权user04可登录test数据库,显式的意思就是使用system直接给user04授予权限
test=# grant CONNECT ON DATABASE test TO user04 ;
GRANT
2、收回public角色在public模式中的所有权限
可以看到public模式下"=UC/system"已经消失(被收回)
test=# revoke ALL ON SCHEMA public FROM PUBLIC ;
REVOKE
test=# \dn+ public 架构模式列表名称 | 拥有者 | 存取权限 | 描述
--------+--------+------------------+------------------------public | system | system=UC/system+| standard public schema| | user03=U/system |
(1 行记录)
3、验证user04用户在模式中创建对象的权限
如果操作没有问题,那么user04是不能在public模式下创建对象(一个表)
test=> create table public.t05 (id int,name text);
错误: 对模式 public 权限不够
第1行create table public.t05 (id int,name text);
总结
我们在学习数据库中的角色/用户的权限的时候,一定要知道数据库的层级关系是怎么样的,从而授予/回收权限
如,test数据库下是public模式,public模式下是t03数据表等等
在授权一个用户/角色可以读取表时,也是按照这样的层级关系来授权;授予用户对test数据库的连接(CONNECT)权限,接着授予用户对public模式的进入(USAGE)权限,最后授予用户对t03数据表有插入和查询权限(INSERT和SELECT);这样一个最基本的用户/角色授权就完成了
当我们不去授权用户/角色对数据库和模式的权限时,而是直接授权对数据表的权限时,其实也是可以正常地查询到数据表的,这就是因为public角色的存在,默认情况下,所有创建的用户都是属于public角色的;而public角色是对数据库有"Tc"权限的,T表示可以创建临时表,c表示允许连接,对所有的模式有UC权限的,U表示进入模式权限,C表示允许在模式下创建对象