暂无图片
暂无图片
1
暂无图片
暂无图片
暂无图片

MogDB数据库用户权限管理

1313

1.用户权限分类

MogDB数据库用户权限可以分为三类:系统权限,对象权限和行级访问控制权限。

系统权限

系统权限又称为用户属性,包括以下权限。

系统权限 缺省值 描述
INHERIT / NOINHERIT INHERIT 角色是否具有继承角色的权限。
CREATEROLE / NOCREATEROLE NOCREATEROLE 角色是否可以创建其他的角色。
CREATEDB / NOCREATEDB NOCREATEDB 角色是否可以创建数据库。
LOGIN / NOLOGIN CREAT USER 命令缺省为LOGIN;CREATE ROLE 命令缺省为NOLOGIN。 角色是否可以登录数据库。
REPLICATION / NOREPLICATION NOREPLICATION 角色是否允许流复制或设置系统为备份模式。
AUDITADMIN / NOAUDITADMIN NOAUDITADMIN 角色是否为审计管理员。
SYSADMIN / NOSYSADMIN NOSYSADMIN 角色是否为系统管理员。
USEFT / NOUSEFT NOUSEFT 角色是否可以操作外表。
MONADMIN / NOMONADMIN NOMONADMIN 角色是否为监控管理员。
OPRADMIN / NOOPRADMIN NOOPRADMIN 角色是否为运维管理员。
POLADMIN / NOPOLADMIN NOPOLADMIN 角色是否为安全策略管理员。

对象权限

数据库对象(表和视图、指定字段、数据库、函数、模式、表空间等)的相关权限。
数据库中的对象权限如下:

对象权限 说明
ALTER 允许用户修改指定对象的属性,但不包括修改对象的所有者和修改对象所在的模式。
COMMENT 允许用户定义或修改指定对象的注释。
CONNECT 允许用户连接到指定的数据库。
CREATE 对于数据库,允许在数据库里创建新的模式。对于模式,允许在模式中创建新的对象。如果要重命名一个对象,用户除了必须是该对象的所有者外,还必须拥有该对象所在模式的CREATE权限。对于表空间,允许在表空间中创建表,允许在创建数据库和模式的时候把该表空间指定为缺省表空间。
DELETE 允许执行DELETE命令删除指定表中的数据。通常,delete命令也需要select权限来查询出哪些行需要删除。
DROP 允许用户删除指定的对象。
EXECUTE 允许使用指定的函数,以及利用这些函数实现的操作符。
INDEX 允许用户在指定表上创建索引,并管理指定表上的索引,还允许用户对指定表执行REINDEX和CLUSTER操作。
INSERT 允许对指定的表执行INSERT命令。
REFERENCES 创建一个外键约束,必须拥有参考表和被参考表的REFERENCES权限。
SELECT 允许对指定的表、视图、序列执行SELECT命令,update或delete时也需要对应字段上的select权限。
TRUNCATE 允许执行TRUNCATE语句删除指定表中的所有记录。
UPDATE 允许对声明的表中任意字段执行UPDATE命令。通常,update命令也需要select权限来查询出哪些行需要更新。SELECT…FORUPDATE和SELECT…FORSHARE除了需要SELECT权限外,还需要UPDATE权限。
USAGE 对于过程语言,允许用户在创建函数的时候指定过程语言。对于模式,USAGE允许访问包含在指定模式中的对象,若没有该权限,则只能看到这些对象的名称。对于序列,USAGE允许使用nextval函数。对于DataSource对象,USAGE是指访问权限,也是可赋予的所有权限,即USAGE与ALLPRIVILEGES等价。
TEMPORARY/TEMP 允许创建临时表。
TRIGGER 允许在指定表上创建触发器。
VACUUM 允许用户对指定的表执行ANALYZE和VACUUM操作。

各对象支持的权限列表如下:

对象名称 权限列表
TABLE SELECT/INSERT/UPDATE/DELETE/TRUNCATE/REFERENCES/ALTER/DROP/COMMENT/INDEX/VACUUM/TRIGGER
TABLE_COLUMN SELECT/INSERT/UPDATE/REFERENCES/COMMENT
DATABASE CREATE/CONNECT/TEMPORARY/TEMP/ALTER/DROP/COMMENT
DOMAIN USAGE
FOREIGN DATA WRAPPER USAGE
FOREIGN SERVER USAGE/ALTER/DROP/COMMENT
FUNCTION EXECUTE/ALTER/DROP/COMMENT
LANGUAGE USAGE
LARGE OBJECT SELECT/UPDATE
SCHEMA CREATE/USAGE/ALTER/DROP/COMMENT
TABLESPACE CREATE/ALTER/DROP/COMMENT
TYPE USAGE/ALTER/DROP/COMMENT
DATA SOURCE USAGE

行级访问控制权限

行级访问控制特性将数据库访问控制精确到数据表行级别。不同用户执行相同的SQL查询操作,读取到的结果是不同的。

2.系统权限分配与回收

系统权限一般通过CREATE/ALTER ROLE语法来指定。其中,SYSADMIN权限可以通过GRANT/REVOKE ALL PRIVILEGE授予或撤销。但系统权限无法通过ROLE和USER的权限被继承,也无法授予PUBLIC。

例2.1:赋予用户系统管理员权限

语法:
ALTER USER user_name [ [ WITH ] option [ … ] ];
where option can be:
{CREATEDB | NOCREATEDB}
| {CREATEROLE | NOCREATEROLE}
| {INHERIT | NOINHERIT}
| {AUDITADMIN | NOAUDITADMIN}
| {SYSADMIN | NOSYSADMIN}
| {MONADMIN | NOMONADMIN}
| {OPRADMIN | NOOPRADMIN}
| {POLADMIN | NOPOLADMIN}
| {USEFT | NOUSEFT}
| {LOGIN | NOLOGIN}
| {REPLICATION | NOREPLICATION}
| {INDEPENDENT | NOINDEPENDENT}
| {VCADMIN | NOVCADMIN}
| {PERSISTENCE | NOPERSISTENCE}
| CONNECTION LIMIT connlimit
| [ ENCRYPTED | UNENCRYPTED ] PASSWORD { ‘password’ [ EXPIRED ] | DISABLE | EXPIRED }
| [ ENCRYPTED | UNENCRYPTED ] IDENTIFIED BY { ‘password’ [ REPLACE ‘old_password’ | EXPIRED ] | DISABLE }
| VALID BEGIN ‘timestamp’
| VALID UNTIL ‘timestamp’
| RESOURCE POOL ‘respool’
| USER GROUP ‘groupuser’
| PERM SPACE ‘spacelimit’
| TEMP SPACE ‘tmpspacelimit’
| SPILL SPACE ‘spillspacelimit’
| NODE GROUP logic_cluster_name
| ACCOUNT { LOCK | UNLOCK }
| PGUSER

gsql工具中,查看alter user命令语法

\help alter user

给用户赋予系统管理员权限

ALTER USER enmo WITH SYSADMIN; 或 GRANT ALL PRIVILEGE TO enmo;

例2.2:解锁/锁定用户

语法:参考例2.1
解锁用户

ALTER USER enmo ACCOUNT UNLOCK;

锁定用户

ALTER USER enmo ACCOUNT LOCK;

3.对象权限分配与回收

数据库系统管理员可以给任何角色或用户授予/撤销任何权限。拥有CREATEROLE权限的角色可以赋予或者撤销任何非系统管理员角色的权限。

3.1对象权限分配与回收

GRANT/REVOKE命令用户数据库对象授予/回收。
任何角色或用户都将拥有通过GRANT直接赋予的权限和所属的权限,再加上PUBLIC的权限。

例3.1.1:给用户赋予单张表的查询权限

首先赋予用户表的查询权限:

语法:GRANT { { SELECT | INSERT | UPDATE | DELETE | TRUNCATE | REFERENCES | ALTER | DROP | COMMENT | INDEX | VACUUM } [, …] | ALL [ PRIVILEGES ] } ON { [ TABLE ] table_name [, …] | ALL TABLES IN SCHEMA schema_name [, …] } TO { [ GROUP ] role_name | PUBLIC } [, …] [ WITH GRANT OPTION ];

GRANT SELECT ON all_data IN SCHEMA enmo TO alice, bob, peter;

为了让用户成功的查询不属于它自己的sechma下的表,除了要执行上面语句赋予该用户对表的查询权限以外,还需要赋予该用户使用表所属shema的使用权限:

语法:GRANT { { CREATE | USAGE | ALTER | DROP | COMMENT } [, …] | ALL [ PRIVILEGES ] } ON SCHEMA schema_name [, …] TO { [ GROUP ] role_name | PUBLIC } [, …] [ WITH GRANT OPTION ];

GRANT USAGE ON SCHEMA enmo TO alice, bob, peter;

如果不具有表所属schema的usage权限,用户在查询表数据时会报错:

enmo=> select * from enmo.all_data; ERROR: permission denied for schema enmo

例3.1.2:给用户赋予某个schema下所有表的查询权限

将模式A的usage权限赋给用户B
语法:参考例3.1.1

GRANT USAGE ON SCHEMA A TO B;

将模式A下所有表的select权限赋给用户B
语法:参考例3.1.1

GRANT SELECT ON ALL TABLES IN SCHEMA A TO B;

3.2public权限

任何角色或用户都将拥有通过GRANT直接赋予的权限和所属的权限,再加上PUBLIC的权限。
默认public具有以下权限:数据库的CONNECT权限和CREATE TEMP TABLE权限、函数的EXECUTE特权、语言和数据类型(包括域)的USAGE特权。
要撤销或重新授予用户和角色对PUBLIC的权限,可通过在GRANT和REVOKE指定关键字PUBLIC实现。
例3.2.1: 撤销public执行某个schema下执行存储过程权限

语法:REVOKE [ GRANT OPTION FOR ]
{ { EXECUTE | ALTER | DROP | COMMENT } [, …] | ALL [ PRIVILEGES ] }
ON { FUNCTION {function_name ( [ {[ argmode ] [ arg_name ] arg_type} [, …] ] )} [, …]
| ALL FUNCTIONS IN SCHEMA schema_name [, …] }
FROM { [ GROUP ] role_name | PUBLIC } [, …]
[ CASCADE | RESTRICT ];

REVOKE EXECUTE ON ALL FUNCTIONS IN SCHEMA enmo FROM PUBLIC;

3.3WITH GRANT OPTION

如果声明了WITH GRANT OPTION,则被授权的用户也可以将此权限赋予他人,否则就不能授权给他人。这个选项不能赋予PUBLIC。

例3.3.1:赋给用户表的select权限,并允许该用户将此权限赋予他人

语法:参考例3.1.1

GRANT SELECT ON all_data IN SCHEMA enmo TO alice WITH GRANT OPTION;

3.4对象默认权限
对象的所有者缺省具有该对象上的所有权限,出于安全考虑所有者可以舍弃部分权限,但ALTER、DROP、COMMENT、INDEX、VACUUM以及对象的可再授予权限属于所有者固有的权限,隐式拥有。
对象创建时初始的默认权限可以使用ALTER DEFAULT PRIVILEGES命令修改。

例3.4.1:设置用户A将来创建的表的查询权限默认赋给用户B

语法:ALTER DEFAULT PRIVILEGES [ FOR { ROLE | USER } target_role [, …] ] [ IN SCHEMA schema_name [, …] ] abbreviated_grant_or_revoke;
where abbreviated_grant_or_revoke can be:
grant_on_tables_clause | grant_on_functions_clause | grant_on_types_clause | revoke_on_tables_clause | revoke_on_functions_clause | revoke_on_types_clause
where grant_on_tables_clause can be:
GRANT { { SELECT | INSERT | UPDATE | DELETE | TRUNCATE | REFERENCES | ALTER | DROP | COMMENT | INDEX | VACUUM } [, …] | ALL [ PRIVILEGES ] } ON TABLES TO { [ GROUP ] role_name | PUBLIC } [, …] [ WITH GRANT OPTION ]

ALTER DEFAULT PRIVILEGES FOR USER A GRANT SELECT ON TABLES TO B;

3.5角色权限的分配与回收

将一个角色或用户的权限授予一个或多个其他角色或用户。在这种情况下,每个角色或用户都可视为拥有一个或多个数据库权限的集合。
当声明了WITH ADMIN OPTION,被授权的用户可以将该权限再次授予其他角色或用户,以及撤销所有由该角色或用户继承到的权限。当授权的角色或用户发生变更或被撤销时,所有继承该角色或用户权限的用户拥有的权限都会随之发生变更。

例3.5.1:将角色A权限赋予B

语法:GRANT role_name [, …] TO role_name [, …] [ WITH ADMIN OPTION ];

GRANT A TO B;

4.行级访问控制权限设置

行级访问控制的目的是控制表中行级数据可见性。用户可以在数据表创建行访问控制(Row Level Security)策略,该策略是指针对特定数据库用户、特定SQL操作生效的表达式。当数据库用户对数据表访问时,若SQL满足数据表特定的Row Level Security策略,在查询优化阶段将满足条件的表达式,按照属性(PERMISSIVE | RESTRICTIVE)类型,通过OR|AND方式拼接,应用到执行计划上,影响最终的执行结果。当前受影响的SQL语句包括SELECT,UPDATE,DELETE。

4.1开启表的行级访问策略

语法:ALTER TABLE [ IF EXISTS ] { table_name [*] | ONLY table_name | ONLY ( table_name )} ENABLE ROW LEVEL SECURITY;

ALTER TABLE all_data ENABLE ROW LEVEL SECURITY;

4.2关闭表的行级访问策略

语法:ALTER TABLE [ IF EXISTS ] { table_name [*] | ONLY table_name | ONLY ( table_name )} DISABLE ROW LEVEL SECURITY;

ALTER TABLE all_data DISABLE ROW LEVEL SECURITY;

4.3创建行级访问控制策略

语法:CREATE [ ROW LEVEL SECURITY ] POLICY policy_name ON table_name [ AS { PERMISSIVE | RESTRICTIVE } ]  [ FOR { ALL | SELECT | UPDATE | DELETE } ]  [ TO { role_name | PUBLIC } [, ...] ]  USING ( using_expression )
CREATE ROW LEVEL SECURITY POLICY all_data_rls ON all_data USING(role = CURRENT_USER);

4.4删除行级访问控制策略

语法:DROP [ ROW LEVEL SECURITY ] POLICY [ IF EXISTS ] policy_name ON table_name [ CASCADE | RESTRICT ]

DROP ROW LEVEL SECURITY POLICY all_data_rls ON all_data;

4.5修改行级访问控制策略名称

语法:ALTER [ ROW LEVEL SECURITY ] POLICY [ IF EXISTS ] policy_name ON table_name RENAME TO new_policy_name;

ALTER ROW LEVEL SECURITY POLICY all_data_rls ON all_data RENAME TO all_data_new_rls;

4.6修改行级访问控制策略影响用户

语法:ALTER [ ROW LEVEL SECURITY ] POLICY policy_name ON table_name [ TO { role_name | PUBLIC } [, …] ] [ USING ( using_expression ) ];

    ALTER ROW LEVEL SECURITY POLICY all_data_new_rls ON all_data TO alice, bob;

4.7查询数据库中表的行级访问策略

    select *from PG_RLSPOLICIES;

4.8测试

a.创建行级访问控制策略,并验证策略生效

        enmo=> select * from enmo.all_data;         id | role | data         ----+-------+------------         1 | alice | alice data         2 | bob | bob data         3 | peter | peter data         (3 rows)         enmo=> \d+ all_data         Table "enmo.all_data"         Column | Type | Modifiers | Storage | Stats target | Description         --------+------------------------+-----------+----------+--------------+-------------         id | integer | | plain | |         role | character varying(100) | | extended | |         data | character varying(100) | | extended | |         Has OIDs: no         Options: orientation=row, compression=no         enmo=> --打开行访问控制策略开关         enmo=> ALTER TABLE all_data ENABLE ROW LEVEL SECURITY;         ALTER TABLE         enmo=> --创建行访问控制策略,当前用户只能查看用户自身的数据         enmo=> CREATE ROW LEVEL SECURITY POLICY all_data_rls ON all_data USING(role = CURRENT_USER);         CREATE ROW LEVEL SECURITY POLICY         enmo=> \d+ all_data         Table "enmo.all_data"         Column | Type | Modifiers | Storage | Stats target | Description         --------+------------------------+-----------+----------+--------------+-------------         id | integer | | plain | |         role | character varying(100) | | extended | |         data | character varying(100) | | extended | |         Row Level Security Policies:         POLICY "all_data_rls" FOR ALL         TO public         USING (((role)::name = "current_user"()))         Has OIDs: no         Options: orientation=row, compression=no, enable_rowsecurity=true         enmo=> select *from PG_RLSPOLICIES;         -[ RECORD 1 ]----+----------------------------------         schemaname | enmo         tablename | all_data         policyname | all_data_rls         policypermissive | PERMISSIVE         policyroles | {public}         policycmd | ALL         policyqual | ((role)::name = "current_user"())         enmo=>--行级访问策略对表的所有者无效         enmo=> select * from enmo.all_data;         id | role | data         ----+-------+------------         1 | alice | alice data         2 | bob | bob data         3 | peter | peter data         (3 rows)         enmo=> \c - alice         Password for user alice:         Non-SSL connection (SSL connection is recommended when requiring high-security)         You are now connected to database "enmo" as user "alice".         enmo=>--用户alice只能访问到role='alice'的数据行         enmo=> select *from enmo.all_data;         id | role | data         ----+-------+------------         1 | alice | alice data         (1 row)         enmo=>--用户alice对表enmo.all_data的insert操作未受行级访问控制影响         enmo=> INSERT INTO enmo.all_data VALUES(4, 'ogdb', 'ogdb data');         INSERT 0 1         enmo=> SELECT * FROM enmo.all_data;         id | role | data         ----+-------+------------         1 | alice | alice data         (1 row)         enmo=> \conninfo         You are connected to database "enmo" as user "enmo" via socket in "/opt/OpenGauass/tmp" at port "15400".         enmo=> SELECT * FROM enmo.all_data;         id | role | data         ----+-------+------------         1 | alice | alice data         2 | bob | bob data         3 | peter | peter data         4 | ogdb | ogdb data         (4 rows)         enmo=>--用户alice对表enmo.all_data的update操作只能修改role='alice'的数据行         enmo=> update enmo.all_data set id=id+10;         UPDATE 1         enmo=> EXPLAIN(COSTS OFF) update enmo.all_data set id=id+10;         QUERY PLAN         ----------------------------------------------------------------         Update on all_data         -> Seq Scan on all_data         Filter: ((role)::name = 'alice'::name)         Notice: This query is influenced by row level security feature         (4 rows)         enmo=> SELECT * FROM enmo.all_data;         id | role | data         ----+-------+------------         11 | alice | alice data         (1 row)         enmo=> \conninfo         You are connected to database "enmo" as user "enmo" via socket in "/opt/OpenGauss/tmp" at port "15400".         enmo=> SELECT * FROM enmo.all_data;         id | role | data         ----+-------+------------         2 | bob | bob data         3 | peter | peter data         4 | ogdb | ogdb data         11 | alice | alice data         (4 rows)         enmo=>--用户alice对表enmo.all_data的delete操作只能删除role='alice'的数据行         enmo=> delete from enmo.all_data;         DELETE 1         enmo=> EXPLAIN(COSTS OFF) delete from enmo.all_data;         QUERY PLAN         ----------------------------------------------------------------         Delete on all_data         -> Seq Scan on all_data         Filter: ((role)::name = 'alice'::name)         Notice: This query is influenced by row level security feature         (4 rows)         enmo=> SELECT * FROM enmo.all_data;         id | role | data         ----+------+------         (0 rows)         enmo=> \conninfo         You are connected to database "enmo" as user "enmo" via socket in "/opt/OpenGauss/tmp" at port "15400".         enmo=> SELECT * FROM enmo.all_data;         id | role | data         ----+-------+------------         2 | bob | bob data         3 | peter | peter data         4 | ogdb | ogdb data         (3 rows)         enmo=> --用户bob只能访问到role='bob'的数据行         enmo=> \c - bob         Password for user bob:         Non-SSL connection (SSL connection is recommended when requiring high-security)         You are now connected to database "enmo" as user "bob".         enmo=> SELECT * FROM enmo.all_data;         id | role | data         ----+------+----------         2 | bob | bob data         (1 row)         enmo=> EXPLAIN(COSTS OFF) SELECT * FROM enmo.all_data;         QUERY PLAN         ----------------------------------------------------------------         Seq Scan on all_data         Filter: ((role)::name = 'bob'::name)         Notice: This query is influenced by row level security feature         (3 rows)         enmo=>--行级访问策略对数据库初始化用户无效         enmo=# \c - ogdb         Non-SSL connection (SSL connection is recommended when requiring high-security)         You are now connected to database "enmo" as user "ogdb".         enmo=# select *from enmo.all_data;         id | role | data         ----+-------+------------         1 | alice | alice data         2 | bob | bob data         3 | peter | peter data         (3 rows)         enmo=#

b.修改行级访问控制策略名称,并设置仅对alice用户生效

        enmo=> ALTER ROW LEVEL SECURITY POLICY all_data_rls ON all_data RENAME TO all_data_new_rls;         ALTER ROW LEVEL SECURITY POLICY         enmo=> ALTER ROW LEVEL SECURITY POLICY all_data_new_rls ON all_data TO alice;         ALTER ROW LEVEL SECURITY POLICY         enmo=> select *from PG_RLSPOLICIES;         -[ RECORD 1 ]----+----------------------------------         schemaname | enmo         tablename | all_data         policyname | all_data_new_rls         policypermissive | PERMISSIVE         policyroles | {alice}         policycmd | ALL         policyqual | ((role)::name = "current_user"())         enmo=> \c - alice         Password for user alice:         Non-SSL connection (SSL connection is recommended when requiring high-security)         You are now connected to database "enmo" as user "alice".         enmo=>--用户alice只能访问到role='alice'的数据行         enmo=> SELECT * FROM enmo.all_data;         id | role | data         ----+-------+------------         1 | alice | alice data         (1 row)         enmo=> \c - bob         Password for user bob:         Non-SSL connection (SSL connection is recommended when requiring high-security)         You are now connected to database "enmo" as user "bob".         enmo=> --行级访问策略对用户bob无效         enmo=> SELECT * FROM enmo.all_data;         id | role | data         ----+-------+------------         1 | alice | alice data         2 | bob | bob data         3 | peter | peter data         (3 rows)         enmo=>

c.对表禁用行级访问控制后,行级访问控制策略失效

        enmo=> \conninfo         You are connected to database "enmo" as user "enmo" via socket in "/opt/OpenGauss/tmp" at port "15400".         enmo=> ALTER TABLE all_data DISABLE ROW LEVEL SECURITY;         ALTER TABLE         enmo=> \x         Expanded display is on.         enmo=> select *from PG_RLSPOLICIES;         -[ RECORD 1 ]----+----------------------------------         schemaname | enmo         tablename | all_data         policyname | all_data_new_rls         policypermissive | PERMISSIVE         policyroles | {alice}         policycmd | ALL         policyqual | ((role)::name = "current_user"())         enmo=> \dt+ all_data         List of relations         -[ RECORD 1 ]---------------------------------         Schema | enmo         Name | all_data         Type | table         Owner | enmo         Size | 8192 bytes         Storage | {orientation=row,compression=no}         Description |         enmo=> SELECT * FROM enmo.all_data;         id | role | data         ----+-------+------------         2 | bob | bob data         3 | peter | peter data         4 | ogdb | ogdb data         1 | alice | alice data         (4 rows)         enmo=> \c - alice         Password for user alice:         Non-SSL connection (SSL connection is recommended when requiring high-security)         You are now connected to database "enmo" as user "alice".         enmo=>--行级访问控制策略未对alice用户生效         enmo=> SELECT * FROM enmo.all_data;         id | role | data         ----+-------+------------         2 | bob | bob data         3 | peter | peter data         4 | ogdb | ogdb data         1 | alice | alice data          (4 rows)         enmo=> EXPLAIN(COSTS OFF) SELECT * FROM enmo.all_data;         QUERY PLAN         ----------------------         Seq Scan on all_data         (1 row)         enmo=>
最后修改时间:2021-12-10 15:15:51
「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论