KingbaseES中不同user之间的权限关系

发布时间 2023-09-19 18:46:05作者: KINGBASE研究院

1.概念

1.schema是每个database中特有的。 schema概念有点像命名空间,这个逻辑空间包含若干表对象。
在DB里面,有了schema才可以创建对象,对象需要依赖于schema,默认为schema为 public
2.user是cluster级别的,它的逻辑架构位于数据库之上。可以在DB里创建与user同名的schema ,指定search_path
3.查询表时需要指定schema.tablename,表存在于某个特定schema中。
4.每个DB有自己的owner,默认为超级用户TEST

注意事项:
1.用户创建的所有对象都被创建在指定的schema(或namespace)中。其他用户可以被授予、也可以限制访问这些对象,甚至通过权限控制都不能在对应的schema中创建对象。
2.用户(或角色)是全局对象,不是定义在数据库中,而是定义在实例的级别。schema是用户在指定的数据库中创建的,其中包含数据库对象。
3.KingbaseES数据库默认有一个public schema,如果没有为对象显式地指定schema,默认使用public schema。
4.db owner不一定能操作其下面的某个schema (db里的 schema 的owner 可以指定其它user),但一般会将schema与同名的owner相关联,这就很像oracle的架构。
5.schema owner授权完成后, 不一定能操作其下面的某张表 (需要再授予表的相关权限)
6、授予某个用户select on all tables in schema XX时,需要先对用户授权usage访问schema XX,否则会出现报错Invalid operation: permission denied for schema XX;
grant usage on schema ce to owner_2;
grant select on all tables in schema ce to owner_2;
7、以上第6项用户只能查询该schema下已经存在的表,无法查询该schema下新建的表. 如果想对该schema下新建的表也获得权限,需要将该schema的owner授权给用户
如:
alter default privileges for user ce_owner in schema ce grant select on tables to owner_2;
--以后schema ce的owner ce_owner在schema ce下新建的表,用户owner_2都可以访问

alter default privileges in schema ce grant select on tables to owner_2;
--当前用户执行如上语句后,此用户在ce下新建的任何表,owner_2都可以访问(其他用户创建的表,owner_2不能访问)

alter default privileges for user user1,user2 in schema ce grant select on tables to owner_2;
--以后user1,user2在schema ce下新建的表,用户owner_2都可以访问

备注:目前没有一种方法,可以使以后任何用户在ce下新建的表,owner_2都可以访问。

2.测试

2.1 测试search_path对schema下创建对象的影响

[复制代码](javascript:void(0)?

#创建wy用户,2个db 

TEST=#CREATE USER wy WITH PASSWORD 'wy';
TEST=#CREATE DATABASE wydb OWNER wy;
TEST=#GRANT ALL PRIVILEGES ON DATABASE wydb TO wy;

TEST=#CREATE DATABASE wydb2 OWNER wy; 
TEST=#GRANT ALL PRIVILEGES ON DATABASE wydb2 TO wy; 

TEST=# \l
                               List of databases
   Name    | Owner  | Encoding |   Collate   |    Ctype    | Access privileges
-----------+--------+----------+-------------+-------------+-------------------
 security  | system | UTF8     | en_US.UTF-8 | en_US.UTF-8 |
 template0 | system | UTF8     | en_US.UTF-8 | en_US.UTF-8 | =c/system        +
           |        |          |             |             | system=CTc/system
 template1 | system | UTF8     | en_US.UTF-8 | en_US.UTF-8 | =c/system        +
           |        |          |             |             | system=CTc/system
 test      | system | UTF8     | en_US.UTF-8 | en_US.UTF-8 |
 test1     | system | GBK      | zh_CN.GBK   | zh_CN.GBK   |
 wydb      | wy     | UTF8     | en_US.UTF-8 | en_US.UTF-8 | =Tc/wy           +
           |        |          |             |             | wy=CTc/wy
 wydb2     | wy     | UTF8     | en_US.UTF-8 | en_US.UTF-8 | =Tc/wy           +
           |        |          |             |             | wy=CTc/wy
(7 rows)


ksql  -U wy -d wydb

wydb=> create table t1(a int);

wydb=> \dt
       List of relations
 Schema | Name | Type  | Owner 
--------+------+-------+-------
 public | t1   | table | wy
(1 row)


#创建和用户同名的schema wy
wydb=>  create schema wy;
CREATE SCHEMA
wydb=> create table t2(a int);
CREATE TABLE

wydb=> \dt
       List of relations
 Schema | Name | Type  | Owner
--------+------+-------+-------
 public | t1   | table | wy
 wy     | t2   | table | wy
(2 rows)


#因为search_path的设置如下,所以创建的表t2默认在schema wy下
wydb=> show search_path;
   search_path   
-----------------
 "$user", public
(1 row)

#创建新的schema为wysc, 我们发现新创建的schema, owner默认是我们的username 
create schema wysc;
wydb=> \dn
  List of schemas
  Name  |  Owner   
--------+----------
 wy   | wy
 wysc | wy
 public | system
(3 rows)

#设置search_path
set search_path = 'wysc',"$user",public;
wydb=> show search_path ;
       search_path       
-------------------------
 wysc, "$user", public
(1 row)

#创建T3表 指定wysc
wydb=>  create table wysc.t3(a int);
CREATE TABLE
wydb=> \dt
       List of relations
 Schema | Name | Type  | Owner
--------+------+-------+-------
 public | t1   | table | wy
 wy     | t2   | table | wy
 wysc   | t3   | table | wy
(3 rows)

#由于设置了search_path,此时即使创建表不加模式名前缀,新表的所属schema也是wysc
wydb=> create table t4(a int );
CREATE TABLE
wydb=> \dt
       List of relations
 Schema | Name | Type  | Owner
--------+------+-------+-------
 public | t1   | table | wy
 wy     | t2   | table | wy
 wysc   | t3   | table | wy
 wysc   | t4   | table | wy

[复制代码](javascript:void(0)?

2.2测试不同user之间的对象访问权限

[复制代码](javascript:void(0)?

#新创建用户wy2,新把wydb2授权给wy2;即wydb2同时授权给wy,wy2两个用户

TEST=#  CREATE USER wy2 WITH PASSWORD 'wy2';
CREATE ROLE
TEST=# 
TEST=#  GRANT ALL PRIVILEGES ON DATABASE wydb2 TO wy2; 
GRANT

TEST=# \l
                               List of databases
   Name    | Owner  | Encoding |   Collate   |    Ctype    | Access privileges
-----------+--------+----------+-------------+-------------+-------------------
 wydb      | wy     | UTF8     | en_US.UTF-8 | en_US.UTF-8 | =Tc/wy           +
           |        |          |             |             | wy=CTc/wy
 wydb2     | wy     | UTF8     | en_US.UTF-8 | en_US.UTF-8 | =Tc/wy           +
           |        |          |             |             | wy=CTc/wy        +
           |        |          |             |             | wy2=CTc/wy
(7 rows)

#以wy2 用户在wydb2中创建schema  testsc指定owner 为wy
TEST=# GRANT "wy" to wy2;
GRANT ROLE

#授权后,wy2在wy的member里
TEST=# \du
                                    List of roles
 Role name |                         Attributes                         | Member of
-----------+------------------------------------------------------------+------------
 wy        |                                                            | {}
 wy2       |                                                            | {wy}

ksql -U wy2 -d wydb2

wydb2=> create schema testsc AUTHORIZATION wy; 
CREATE SCHEMA

wydb2=> \dn 
  List of schemas
  Name  |  Owner   
--------+----------
 public | system
 testsc | wy
(2 rows)

set search_path = 'testsc',"$user",public;

#创建T5表指定testsc 

wydb2=>  create table testsc.t5(a int);
CREATE TABLE
wydb2=> \dt
       List of relations
 Schema | Name | Type  | Owner 
--------+------+-------+-------
 testsc | t5   | table | wy2
(1 row)

wydb2=> select user;
 user
------
 wy2
(1 row)

wydb2=> select * from testsc.t5;
 a
---
(0 rows)

#可以看到,这时虽然Schema的Owner是wy  ,但table的owner还是wy2,所以用wy是查不到t5的
ksql -U wy  -d wydb2

wydb2=>  select * from testsc.t5;
ERROR:  permission denied for table t5

#更改t5表的owner为wy后可以查询 
ksql  -U wy2  -d wydb2

wydb2=>  alter table testsc.t5 OWNER TO wy;
ALTER TABLE
wydb2=> \dt testsc.t5
       List of relations
 Schema | Name | Type  | Owner
--------+------+-------+-------
 testsc | t5   | table | wy
(1 row)

#再次以wy用户登录可以查询  
ksql  -U wy  -d wydb2

wydb2=>  select * from testsc.t5;
 a
---
(0 rows)

#现在无论用wy用户,还是wy2用户都可查询,因为wydb2库里面,wy2里有wy信息的Member
wydb2=> \du 
                                            List of roles
    Role name    |                         Attributes                         |       Member of       
-----------------+------------------------------------------------------------+-----------------------
 wy            |                                                            | {}
 wy2           |                                                            | {wy}

#当回收wy2用户里的 wy的member 信息时,就没有权限

TEST=# revoke  "wy" from wy2;
REVOKE ROLE
TEST=# \q
ksql  -U wy2 -d wydb2

wydb2=> select * from testsc.t5;
ERROR:  permission denied for schema testsc

#这时只要同时授权这2个权限, wy2可以又访问t5这张表了

ksql  -U wy -d wydb2

grant USAGE on SCHEMA testsc to wy2 ; --授权完成后,testsc既和wy用户关联,又和wy2用户关联

grant SELECT on testsc.t5 to wy2 ;

ksql -U wy2 -d wydb2

wydb2=> select * from testsc.t5;
 a 
---
(0 rows)

[复制代码](javascript:void(0)?