Halo Tech

Halo数据库用户角色权限管理

1、用户和角色

1.1 用户角色概述

    在 Halo 数据库中,角色被广泛用于管理数据库访问权限,以确保数据的安全性和访问控制。角色可以分为以下几类,每种角色具有不同的权限和用途:

1)超级用户(如 halo):超级用户可以绕过除登录权限(login)之外的所有安全检查。超级用户的权限是全局的,无法通过 REVOKE命令撤销。即使尝试撤销超级用户的某些权限,Halo也会忽略这些操作。通常用于数据库的系统维护和高级管理任务等。

2)普通用户:根据需要创建,拥有有限的权限。用于日常的数据库操作,如数据查询、插入、更新等。

3)用户(User):拥有登录数据库的权限。

4)角色(Role):可以拥有数据库对象(如表、索引)的权限,并可将这些权限授予其他角色。

5)组(Group):一种特殊的角色,不拥有REPLICATION或 CONNECTION LIMIT 属性。

    角色是在数据库集簇层面上定义的,因此它们在集簇内的所有数据库中都是可用的。即在同一个服务器的不同数据库中,角色是相同的。

核心区别:

对象类型默认属性典型用途
角色(Role)NOLOGIN权限组、逻辑分组
用户(User)LOGIN实际登录的数据库账户

等效关系:

CREATE USER dev_user;  -- 等价于  CREATE ROLE dev_user LOGIN;

1.2 创建用户与角色

    在 Halo数据库中,创建用户和角色是权限管理的基础操作。通过 CREATE USER和 CREATE ROLE命令,可以灵活地定义不同类型的用户和角色,并为它们分配相应的角色属性。

CREATE {USER|ROLE} user_name [ WITH     [ SUPERUSER | NOSUPERUSER ]    [ CREATEDB | NOCREATEDB ]    [ CREATEROLE | NOCREATEROLE ]    [ INHERIT | NOINHERIT ]    [ LOGIN | NOLOGIN ]     [ REPLICATION | NOREPLICATION ]    [ BYPASSRLS | NOBYPASSRLS ]    [ CONNECTION LIMIT connlimit ]    [ VALID UNTIL 'timestamp' ]    [ IN ROLE role_name [, ...] ]    [ ROLE role_name [, ...] ]    [ ADMIN role_name ]    [ PASSWORD 'password' ]];

角色属性参数:

选项意义默认值
SUPERUSER / NOSUPERUSER角色是否为超级用户,拥有所有权限NOSUPERUSER
CREATEDB/NOCREATEDB角色是否可以创建数据库NOCREATEDB,SUPERUSER 角色不受此属性影响
CREATEROLE/NOCREATEROLE角色是否可以创建其他角色NOCREATEDB,SUPERUSER 角色不受此属性影响
INHERIT/NOINHERIT角色是否继承其父角色的权限INHERIT
LOGIN/NOLOGIN角色是否可以登录数据库CREATE ROLE默认为 NOLOGIN CREATE USER 默认为 LOGIN,SUPERUSER角色依旧受此属性影响
REPLICATION/NOREPLICATION角色是否可以用于复制操作NOREPLICATION,SUPERUSER角色不受此属性影响
BYPASSRLS/NOBYPASSRLS角色是否可以绕过行级安全性(RLS)策略NOBYPASSRLS,SUPERUSER角色不受此属性影响
CONNECTION LIMIT connlimit角色的最大并发连接数-1(无限制),SUPERUSER 角色不受此属性影响
[ENCRYPTED] PASSWORD password/ PASSWORD NULL设置角色的密码,空密码导致认证失败未指定则无密码
VALID UNTIL  'timestamp'设置密码的有效期,过期后密码失效永久有效
IN ROLE role_name [, ...]将角色添加到指定角色列表中-
IN GROUP role_name [, ...]与IN ROLE相同,是已过时的语法-
ROLE role_name [, ...]将指定角色作为新角色的成员-
ADMIN role_name [, ...]将指定角色作为新角色的管理员成员,并赋予管理权限-

需要注意:

1)使用ALTER ROLE修改角色属性,DROP ROLE用于删除角色。角色ROLE默认为NOLOGIN(不可登录数据库),所有CREATE ROLE属性均可被ALTER修改。

2)属性LOGIN、SUPERUSER、BYPASSRLS、REPLICATION和CREATEROLE被视为特殊权限,它们不会像其它数据库对象的普通权限那样被继承。

3)使用GRANT和REVOKE增加或移除组角色成员。

4)VALID UNTIL定义口令过期时间,而不是为一个角色本身定义了一个过期时间。非口令认证时无效。

5)INHERIT属性控制权限继承,**不适用于特殊角色属性**。

6)CREATE ROLE无继承概念,可创建权限不同的角色。 

7)拥有SUPERUSER属性的角色或用户,依然受 LOGIN/ NOLOGIN属性控制是否可登录数据库,

8)用户角色为数据库中对象拥有者时,删除此用户将会报错,需要更改依赖对象的所有权,或者删除此角色拥有的数据库对象。

-- 先级联删除角色拥有的对象(慎用),再删除角色DROP OWNED BY rolename CASCADE;DROP ROLE rolename;

Image

1.3 修改用户角色属性

    创建用户或角色后,可能需要根据实际需求调整其属性,例如更改密码、调整权限、修改角色名称或设置会话参数等。Halo中提供了 ALTER ROLE 和 ALTER USER 语句来修改角色属性。这两个命令在功能上是相似的。

ALTER {ROLE | USER} role_name [WITH] option;-- option 为角色属性,详细参考1.2 中角色属性参数

还可以使用下列语句更改角色名或角色会话参数值:

1)使用ALTER ROLE role_name RENAME TO new_role语句重命名角色。

2)使用ALTER ROLE role_name SET param=value语句更改配置变量的角色会话默认值。

例如:

Image

查询系统视图pg_roles可查询角色拥有的属性。

select * from pg_roles where rolname = 'role_name';

Image

1.4 角色组权限继承机制

    角色组权限继承是Halo中一种高效且灵活的权限管理机制,通过它可以实现权限的批量分配和集中管理。这种机制允许用户或角色继承所属角色组的权限,从而简化权限的分配和维护过程,同时提高权限管理的可扩展性和可维护性。角色组权限继承是通过创建特定权限的组角色,并将用户或角色分配给这些组角色,实现权限自动传递。组角色无登录权限,但可拥有数据库对象权限。

    如下例,创建了一个名为read_only的角色组,该角色组仅具有对 test 模式下所有表的 USAGE和 SELECT权限。然后,创建了一个名为 dev_user的用户,并将该用户添加到 read_only角色组中,dev_user用户继承了read_only权限,拥有test模式下所有表的 USAGE 和 SELECT权限。

-- 创建角色组CREATE ROLE read_only;  grant usage on schema test TO read_only;GRANT SELECT ON ALL TABLES IN SCHEMA test TO read_only;  
-- 将用户加入角色组CREATE USER dev_user;GRANT read_only TO dev_user;
-- 检查角色继承关系SELECT rolname AS "子角色", array_agg(roleid::regrole) AS "继承的父角色"FROM pg_auth_members JOIN pg_roles ON member = pg_roles.oidGROUP BY rolname;
-- 验证权限继承SET ROLE dev_user; SELECT * FROM test.products; -- 成功执行INSERT INTO test.products(item_id, item_name, price)VALUES (1001, 'Special Widget', 49.99); -- 执行失败,无此表insert权限
-- 将用户移除角色组SET ROLE halo;REVOKE read_only FROM dev_user;SET ROLE dev_user; SELECT * FROM test.products; -- 移除角色组无权限,执行失败。

Image

1.5 权限传递控制(WITH ADMIN OPTION)

    在 Halo中,权限管理不仅包括授予或撤销角色的权限,还涉及权限的传递控制。通过使用 WITH ADMIN OPTION,可以允许被授权者将角色权限转授给其他用户或角色。这种机制为权限管理提供了更大的灵活性,但是需要谨慎使用,以避免权限扩散带来的安全风险。

CREATE USER admin_user;GRANT read_only TO admin_user WITH ADMIN OPTION;  -- admin_user 可将 read_only 授予其他用户

Image

2、数据库级别权限管理

    数据库级别的权限管理构成了Halo权限体系的核心,主要负责控制用户对数据库的全局访问权限,涵盖连接数据库、创建数据库对象、使用临时表等关键操作。通过恰当配置这些权限,可以有效地限定用户在特定数据库内的活动范围,从而保障数据库的安全性和稳定性。

2.1 数据库级别权限类别

权限名称作用描述典型场景
CONNECT允许用户连接到数据库(基础前置权限)普通用户访问生产环境数据库
CREATE允许用户在指定的数据库中创建新的schema开发者在测试库创建临时 Schema
TEMPORARY允许创建临时表(会话级存储,常用于复杂查询中间结果)数据分析时存储中间计算结果

注:默认创建的普通用户仅具有CONNECT、TEMPORARY权限,但不具有CREATE权限,即不可在数据库中创建新的数据库对象。

2.2 授权与撤销权限

   授权和撤销权限是数据库权限管理的核心操作。通过 GRANT和 REVOKE语句,可以精确地控制角色(用户或组)在数据库中的访问权限。下列语句可以授予与撤销角色在数据库上的权限。

GRANT { { CREATE | CONNECT | TEMPORARY | TEMP } [, ...] | ALL [ PRIVILEGES ] }ON DATABASE database_name [, ...]TO role_specification [, ...] [ WITH GRANT OPTION ]
REVOKE [ GRANT OPTION FOR ]{ { CREATE | CONNECT | TEMPORARY | TEMP } [, ...] | ALL [ PRIVILEGES ] }ON DATABASE database_name [, ...]FROM role_specification [, ...][ CASCADE | RESTRICT ]
-- 其中role_specification可以是,[ GROUP ] role_name | PUBLIC | CURRENT_USER | SESSION_USER

    如果指定了WITH GRANT OPTION,特权的接收者可以接着把它授予给其他人。如果没有授权选项,接收者就不能这样做。授权选项不能被授予给PUBLIC。

    一般情况下,普通用户拥有对数据库的CONNECT与TEMPORARY权限(template0与template1数据库除外)。

Image

   SUPERUSER用户拥有数据库级别所有权限。

Image

   使用has_database_privilege(RoleName, DbName,PrivilegeType)函数查询用户数据库级别权限,下列语句可查询指定角色的数据库级权限。

SELECT     d.datname AS "DbName",    r.rolname AS "RoleName",    CASE         WHEN has_database_privilege(r.rolname, d.datname, 'CONNECT') THEN 'YES'        ELSE 'NO'    END AS "CONNECT",    CASE         WHEN has_database_privilege(r.rolname, d.datname, 'CREATE') THEN 'YES'        ELSE 'NO'    END AS "CREATE",    CASE         WHEN has_database_privilege(r.rolname, d.datname, 'TEMPORARY') THEN 'YES'        ELSE 'NO'    END AS "TEMPORARY"FROM    pg_roles r, pg_database d WHERE r.rolname = 'username'ORDER BY d.datname;

2.3 权限验证操作

示例1:测试使用Halo临时表应具有的权限:

-- 创建测试用户create user test1;-- 移除默认权限干扰revoke all ON database test FROM public;-- 仅赋予数据库连接权限grant connect on database test TO test1;-- 赋予schema所有权限(排除权限干扰)grant all on schema public TO test1;-- 查看用户权限SELECT     d.datname AS "DbName",    r.rolname AS "RoleName",    CASE         WHEN has_database_privilege(r.rolname, d.datname, 'CONNECT') THEN 'YES'        ELSE 'NO'    END AS "CONNECT",    CASE         WHEN has_database_privilege(r.rolname, d.datname, 'CREATE') THEN 'YES'        ELSE 'NO'    END AS "CREATE",    CASE         WHEN has_database_privilege(r.rolname, d.datname, 'TEMPORARY') THEN 'YES'        ELSE 'NO'    END AS "TEMPORARY"FROM    pg_roles r, pg_database d WHERE r.rolname = 'test1'ORDER BY d.datname;-- 创建全局临时表(验证)\c test test1CREATE TEMPORARY TABLE temp_sales_data (    id SERIAL PRIMARY KEY,    product_name VARCHAR(100),    quantity INT,    price NUMERIC(10, 2));     -- 创建临时表将被拒绝,需要 TEMPORARY 权限\c - halogrant temporary on database test to test1 ;  -- 赋予  TEMPORARY 权限\c - test1CREATE TEMPORARY TABLE temp_sales_data (    id SERIAL PRIMARY KEY,    product_name VARCHAR(100),    quantity INT,    price NUMERIC(10, 2));    -- 成功创建临时表

Image

示例2:不可移除超级用户的权限,因为超级用户可以绕过除登录权限(login)之外的所有安全检查。

-- 创建超级用户create user test2 superuser;-- 查看超级用户数据库级权限SELECT     d.datname AS "DbName",    r.rolname AS "RoleName",    CASE         WHEN has_database_privilege(r.rolname, d.datname, 'CONNECT') THEN 'YES'        ELSE 'NO'    END AS "CONNECT",    CASE         WHEN has_database_privilege(r.rolname, d.datname, 'CREATE') THEN 'YES'        ELSE 'NO'    END AS "CREATE",    CASE         WHEN has_database_privilege(r.rolname, d.datname, 'TEMPORARY') THEN 'YES'        ELSE 'NO'    END AS "TEMPORARY"FROM    pg_roles r, pg_database d WHERE r.rolname = 'test2' AND d.datname = 'test';-- 尝试移除超级用户对test库所有权限,无效revoke all on database test FROM public;revoke all on database test FROM test2;-- 再次查看超级用户数据库级权限,权限未被移除SELECT     d.datname AS "DbName",    r.rolname AS "RoleName",    CASE         WHEN has_database_privilege(r.rolname, d.datname, 'CONNECT') THEN 'YES'        ELSE 'NO'    END AS "CONNECT",    CASE         WHEN has_database_privilege(r.rolname, d.datname, 'CREATE') THEN 'YES'        ELSE 'NO'    END AS "CREATE",    CASE         WHEN has_database_privilege(r.rolname, d.datname, 'TEMPORARY') THEN 'YES'        ELSE 'NO'    END AS "TEMPORARY"FROM    pg_roles r, pg_database d WHERE r.rolname = 'test2' AND d.datname = 'test';\c test test2

Image

3、Schema 级权限管理 

   Schema 级权限管理构成了Halo数据库权限体系的核心部分,它负责控制用户在特定 Schema 中对对象的访问(需配合对象级权限使用)和创建权限。通过恰当配置 Schema 级权限,可以实现对用户操作范围的细致管理,从而确保数据的安全性和隔离性。通常,Schema 级权限需要与对象级权限相结合,以达成更为全面的权限控制。

3.1 核心权限类型  

权限名称作用描述典型场景
USAGE允许访问 Schema 内的对象(需配合对象级权限使用)查询表、调用函数
CREATE允许在 Schema 中创建新对象(表、视图、索引等,依赖USAGE权限)开发环境动态创建测试表

    一般情况下普通用户拥有public和部分系统schema的USAGE权限,无CREATE权限。Schema 级权限仅控制用户对 Schema 的访问和创建能力,具体对象(如表、视图、函数)的权限还需要通过对象级权限进行管理。Schema 级权限可以通过 GRANT 和 REVOKE语句进行管理,具体操作如下:

GRANT { { CREATE | USAGE } [, ...] | ALL [ PRIVILEGES ] }ON SCHEMA schema_name [, ...]TO role_specification [, ...] [ WITH GRANT OPTION ]
REVOKE [ GRANT OPTION FOR ]{ { CREATE | USAGE } [, ...] | ALL [ PRIVILEGES ] }ON SCHEMA schema_name [, ...]FROM role_specification [, ...][ CASCADE | RESTRICT ]-- 其中role_specification可以是,[ GROUP ] role_name | PUBLIC | CURRENT_USER | SESSION_USER

3.2 权限查询方法  

has_schema_privilege(RoleName,SchemaName,PrivilegeType)函数查询用户Schema级别权限,用于检查指定角色(用户或组)是否拥有对某个 Schema 的特定权限。下列语句可查询指定角色的schema级权限。

SELECT     n.nspname AS schema_name,    r.rolname AS rolname,    CASE         WHEN has_schema_privilege(r.rolname, n.nspname, 'USAGE') THEN 'YES'        ELSE 'NO'    END AS "USAGE",    CASE         WHEN has_schema_privilege(r.rolname, n.nspname, 'CREATE') THEN 'YES'        ELSE 'NO'    END AS "CREATE"FROM    pg_roles rJOIN pg_namespace n ON trueWHERE r.rolname = 'username'ORDER BY n.nspname;

3.3 权限验证操作

示例1:数据库级CREATE与schema级别的CREATE权限对比

-- 创建测试用户create user test1;create user test2;-- 移除测试库权限干扰revoke create on database test FROM public;revoke create on schema public FROM public;-- 赋予 test1 数据库级别 create权限grant create on database test TO test1;-- 赋予 tes2 schema 级别 create权限grant create on schema public TO test2;-- 查看两个用户数据库级权限SELECT     d.datname AS "DbName",    r.rolname AS "RoleName",    CASE         WHEN has_database_privilege(r.rolname, d.datname, 'CONNECT') THEN 'YES'        ELSE 'NO'    END AS "CONNECT",    CASE         WHEN has_database_privilege(r.rolname, d.datname, 'CREATE') THEN 'YES'        ELSE 'NO'    END AS "CREATE",    CASE         WHEN has_database_privilege(r.rolname, d.datname, 'TEMPORARY') THEN 'YES'        ELSE 'NO'    END AS "TEMPORARY"FROM    pg_roles r, pg_database d WHERE (r.rolname = 'test1' OR r.rolname = 'test2') AND d.datname = 'test';-- 验证数据库级 CREATE 权限\c test test1create schema test1;        -- 创建成功,test1拥有数据库级别 create \c test test2create schema test2;        -- 执行失败,无权-- 查看两个用户schema级权限SELECT     n.nspname AS schema_name,    r.rolname AS rolname,    CASE         WHEN has_schema_privilege(r.rolname, n.nspname, 'USAGE') THEN 'YES'        ELSE 'NO'    END AS "USAGE",    CASE         WHEN has_schema_privilege(r.rolname, n.nspname, 'CREATE') THEN 'YES'        ELSE 'NO'    END AS "CREATE"FROM    pg_roles rJOIN pg_namespace n ON trueWHERE (r.rolname = 'test1' OR r.rolname = 'test2') AND n.nspname = 'public';-- 验证 schema 级 CREATE 权限\c test test1CREATE TABLE public.test_table (    id SERIAL PRIMARY KEY,    name VARCHAR(50));        -- test1无 public 的 CREATE 权限,执行失败\c test test2CREATE TABLE public.test_table (    id SERIAL PRIMARY KEY,    name VARCHAR(50));        -- 执行成功

Image

Image

示例2:schema级USAGE权限需配合对象级权限使用

-- 创建测试用户create user test1;create user test2;-- 移除test1 USAGE权限revoke USAGE on schema public FROM test1;-- 赋予 tes2 schema 级别 create权限grant create on schema public TO test2;-- 创建测试表\c test test2CREATE TABLE public.test_table (    id SERIAL PRIMARY KEY,    name VARCHAR(50));        -- 执行成功\dt public.test_table-- 查看两个用户schema级权限SELECT     n.nspname AS schema_name,    r.rolname AS rolname,    CASE         WHEN has_schema_privilege(r.rolname, n.nspname, 'USAGE') THEN 'YES'        ELSE 'NO'    END AS "USAGE",    CASE         WHEN has_schema_privilege(r.rolname, n.nspname, 'CREATE') THEN 'YES'        ELSE 'NO'    END AS "CREATE"FROM    pg_roles rJOIN pg_namespace n ON trueWHERE (r.rolname = 'test1' OR r.rolname = 'test2') AND n.nspname = 'public';-- 查询public.test_tableselect * from public.test_table;-- 赋予test1 USAGE 权限\c test halogrant USAGE on schema public TO public;-- test1 虽有 USAGE 权限 ,但无此表 select 权限(需配合对象级权限)\c test test1select has_table_privilege('test1','public.test_table','select');select * from public.test_table;-- 赋予test1 select 表权限\c test halogrant select ON table public.test_table TO test1;\c test test1select * from public.test_table;  -- 执行成功

Image

Image

4、元对象级权限管理

    元对象级权限管理是 Halo中最细粒度的权限控制方式,用于控制用户对具体对象(如表、视图、函数、序列等)的操作权限。这种权限管理方式允许数据库管理员根据用户的角色和需求,精确地授予或撤销对特定对象的访问权限。对于使用schema中元对象,首先得拥有对schema的USAGE权限,必要情况下还需拥有schema的CREATE权限。

4.1 表与视图权限  

    表和视图的权限管理是 Halo中重要的安全机制,用于控制用户对数据的访问和操作能力。以下是表和视图的常见权限类型及其作用描述和依赖关系:

权限名称作用描述依赖关系
SELECT读取数据(视图必备权限)无
INSERT插入新数据无
UPDATE修改数据无
DELETE删除数据无
TRUNCATE快速清空表数据无
REFERENCES创建外键约束被引用表需有此权限
TRIGGER创建/删除触发器表所有者权限

下列语句可以授予与撤销角色对表或视图的权限。

GRANT { { SELECT | INSERT | UPDATE | DELETE | TRUNCATE | REFERENCES | TRIGGER }[, ...] | ALL [ PRIVILEGES ] }ON { [ TABLE ] table_name [, ...]| ALL TABLES IN SCHEMA schema_name [, ...] }TO role_specification [, ...] [ WITH GRANT OPTION ]
-- 可对特定列赋权GRANT { { SELECT | INSERT | UPDATE | REFERENCES } ( column_name [, ...] )[, ...] | ALL [ PRIVILEGES ] ( column_name [, ...] ) }ON [ TABLE ] table_name [, ...]TO role_specification [, ...] [ WITH GRANT OPTION ]

REVOKE [ GRANT OPTION FOR ]{ { SELECT | INSERT | UPDATE | DELETE | TRUNCATE | REFERENCES | TRIGGER }[, ...] | ALL [ PRIVILEGES ] }ON { [ TABLE ] table_name [, ...]| ALL TABLES IN SCHEMA schema_name [, ...] }FROM role_specification [, ...][ CASCADE | RESTRICT ]
-- 可对特定列进行权限回收REVOKE [ GRANT OPTION FOR ]{ { SELECT | INSERT | UPDATE | REFERENCES } ( column_name [, ...] )[, ...] | ALL [ PRIVILEGES ] ( column_name [, ...] ) }ON [ TABLE ] table_name [, ...]FROM role_specification [, ...][ CASCADE | RESTRICT ]

通过 information_schema.table_privileges视图或者 has_table_privilege(RoleName,TableName,PrivilegeType) 函数可查询用户对表的相关权限。语句如下:

-- 通过视图查询SELECT grantee, table_schema, table_name, privilege_typeFROM information_schema.table_privilegesWHERE grantee = 'username' AND table_name = 'table_name';
-- 通过快捷键查询\dp+ TableName
-- 例如:test=# \dp+ public.test_table Access privileges Schema | Name | Type | Access privileges | Column privileges | Policies --------+------------+-------+---------------------+-------------------+---------- public | test_table | table | test2=arwdDxt/test2+| | | | | test1=arwdDxt/test2 | | (1 row)
-- 权限标识符说明:a=INSERT, r=SELECT, w=UPDATE, d=DELETE, D=TRUNCATE, x=REFERENCES, t=TRIGGER *=WITH GRANT OPTION(表示可转授权限)

以下是一个完整的测试示例,用于验证 Halo 中的列级安全功能。将创建一个表 employees,为用户 test1 赋予对部分列(name, department)的权限,并验证列级安全。

-- 创建测试表CREATE TABLE public.employees (    id SERIAL PRIMARY KEY,    name TEXT NOT NULL,    salary NUMERIC(10, 2),    department TEXT);INSERT INTO public.employees (name, salary, department)VALUES ('Alice', 5000.00, 'HR'),('Bob', 6000.00, 'Engineering'),('Charlie', 7000.00, 'Finance');-- 创建测试用户并赋权create user test1;grant all (name, department) on table public.employees to test1;-- 查看表权限\dp+ public.employees-- 列级安全测试\c test test1SELECT name, department from public.employees;   -- 查询授权列,成功SELECT name, salary, department from public.employees;   -- 查询包含未授权列,执行失败

Image

 4.2 函数与序列权限

对象类型权限名称作用描述依赖关系
函数、存过(FUNCTION、PROCEDURE、ROUTINE)EXECUTE执行函数/存储过程无
序列USAGE访问序列值无
序列SELECT使用 nextval()/currval()无
序列UPDATE修改序列值 (setval())需 USAGE

下列语句可以授予与撤销函数与序列的权限。

GRANT { EXECUTE | ALL [ PRIVILEGES ] }ON { { FUNCTION | PROCEDURE | ROUTINE } routine_name [ ( [ [ argmode ][ arg_name ] arg_type [, ...] ] ) ] [, ...]| ALL { FUNCTIONS | PROCEDURES | ROUTINES } IN SCHEMA schema_name[, ...] }TO role_specification [, ...] [ WITH GRANT OPTION ]
GRANT { { USAGE | SELECT | UPDATE }[, ...] | ALL [ PRIVILEGES ] }ON { SEQUENCE sequence_name [, ...]| ALL SEQUENCES IN SCHEMA schema_name [, ...] }TO role_specification [, ...] [ WITH GRANT OPTION ]

REVOKE [ GRANT OPTION FOR ]{ EXECUTE | ALL [ PRIVILEGES ] }ON { { FUNCTION | PROCEDURE | ROUTINE } function_name [ ( [ [ argmode ][ arg_name ] arg_type [, ...] ] ) ] [, ...]| ALL { FUNCTIONS | PROCEDURES | ROUTINES } IN SCHEMA schema_name[, ...] }FROM role_specification [, ...][ CASCADE | RESTRICT ]
REVOKE [ GRANT OPTION FOR ]{ { USAGE | SELECT | UPDATE }[, ...] | ALL [ PRIVILEGES ] }ON { SEQUENCE sequence_name [, ...]| ALL SEQUENCES IN SCHEMA schema_name [, ...] }FROM role_specification [, ...][ CASCADE | RESTRICT ]
-- 若需要将整个shcema下的函数、存过和序列赋予某用户时,可使用下列语句grant all on all ROUTINES IN SCHEMA schema_name to rolename;grant all on all SEQUENCES IN SCHEMA schema_name to rolename;

通过查询函数 has_function_privilege(RoleName,FunName,PrivilegeType)、has_sequence_privilege(RoleName,SequenceName,PrivilegeType)

如下例:

Image

Image

4.3 外部对象权限

对象类型权限名称作用描述
外部数据包装器 (FOREIGN DATA WRAPPER)USAGE使用外部数据包装器
外部服务器(FOREIGN SERVER)USAGE使用外部服务器配置
域 (DOMAIN)USAGE使用自定义域类型
类型 (TYPE)USAGE使用自定义数据类型

下列语句可以授予与撤销角色对外部对象的权限。

GRANT { USAGE | ALL [ PRIVILEGES ] }ON { DOMAIN domain_name [, ...] | FOREIGN DATA WRAPPER fdw_name [, ...]| FOREIGN SERVER server_name [, ...] | TYPE type_name [, ...] }TO role_specification [, ...] [ WITH GRANT OPTION ]
REVOKE [ GRANT OPTION FOR ]{ USAGE | ALL [ PRIVILEGES ] }ON { DOMAIN domain_name [, ...] | FOREIGN DATA WRAPPER fdw_name [, ...]| FOREIGN SERVER server_name [, ...] | TYPE type_name [, ...] }FROM role_specification [, ...][ CASCADE | RESTRICT ]

使用函数has_foreign_data_wrapper_privilege(RoleName,FdwName,PrivilegeType)has_server_privilege(RoleName,ServerName,PrivilegeType)has_type_privilege(RoleName,TypeName,PrivilegeType)可查询相关对象权限,此处不再示例展出。

 4.4 大对象与表空间权限

对象类型权限名称作用描述
大对象(LARGE OBJECT)SELECT读取大对象内容
大对象(LARGE OBJECT)UPDATE修改大对象内容
表空间(TABLESPACE)CREATE在表空间创建对象

下列语句可以授予与撤销角色对大对象与表空间的权限。

GRANT { { SELECT | UPDATE } [, ...] | ALL [ PRIVILEGES ] }ON LARGE OBJECT loid [, ...]TO role_specification [, ...] [ WITH GRANT OPTION ]
GRANT { CREATE | ALL [ PRIVILEGES ] }ON TABLESPACE tablespace_name [, ...]TO role_specification [, ...] [ WITH GRANT OPTION ]
REVOKE [ GRANT OPTION FOR ]{ { SELECT | UPDATE } [, ...] | ALL [ PRIVILEGES ] }ON LARGE OBJECT loid [, ...]FROM role_specification [, ...][ CASCADE | RESTRICT ]
REVOKE [ GRANT OPTION FOR ]{ CREATE | ALL [ PRIVILEGES ] }ON TABLESPACE tablespace_name [, ...]FROM role_specification [, ...][ CASCADE | RESTRICT ]

使用函数has_tablespace_privilege(RoleName,TablespaceName,PrivilegeType)可对查询表空间相关权限。

Image

4.5 其他对象权限 

对象类型权限名称作用描述
语言(LANGUAGE)USAGE使用编程语言
触发器(TRIGGER)隐式拥有通过表TRIGGER权限控制

下列语句可以授予与撤销角色对语言的权限。

GRANT { USAGE | ALL [ PRIVILEGES ] }ON LANGUAGE lang_name [, ...]TO role_specification [, ...] [ WITH GRANT OPTION ]
REVOKE [ GRANT OPTION FOR ]{ USAGE | ALL [ PRIVILEGES ] }ON LANGUAGE lang_name [, ...]FROM role_specification [, ...][ CASCADE | RESTRICT ]

Image

4.6 行级安全(Row-Level Security,RLS)

    RLS是一种强大的功能,用于通过基于用户角色、属性或其他条件的细粒度访问控制来限制对表中行的访问。RLS 在多租户应用程序或管理敏感数据时非常有用。默认情况下,表的行级安全是禁用的。启用行级安全后,如果没有定义任何策略,默认策略是“拒绝所有”(default-deny),即没有任何行对用户可见(超级用户可绕过此限制)。要启用行级安全,可以使用以下命令:

-- 启用行级安全ALTER TABLE table_name ENABLE ROW LEVEL SECURITY;

下例中

-- 创建数据库 hrCREATE DATABASE hr;
-- 切换到 hr 数据库\c hr
-- 创建 departments 表CREATE TABLE departments ( id SERIAL PRIMARY KEY, name VARCHAR(255) NOT NULL UNIQUE, manager VARCHAR(255) NOT NULL);
-- 插入初始数据INSERT INTO departments (name, manager)VALUES ('Sales', 'alice'),('Marketing', 'bob'),('IT', 'jack');
-- 创建组角色 managersCREATE ROLE managers;
-- 授予 managers 角色对 public 模式中所有表的 SELECT 权限GRANT SELECT ON ALL TABLES IN SCHEMA public TO managers;
-- 创建部门经理角色并分配到 managers 组CREATE ROLE alice WITH LOGIN IN ROLE managers;CREATE ROLE bob WITH LOGIN IN ROLE managers;CREATE ROLE jack WITH LOGIN IN ROLE managers;
-- 在 departments 表上启用行级安全性ALTER TABLE departments ENABLE ROW LEVEL SECURITY;
-- 创建行级安全策略CREATE POLICY department_managersON departments FOR SELECTUSING (manager = current_user);
-- 使用 alice 角色连接到 hr 数据库\c hr alice-- 查询 departments 表SELECT * FROM departments;
-- 使用 bob 角色连接到 hr 数据库\c hr bob-- 查询 departments 表SELECT * FROM departments;
-- 使用超级用户连接到 hr 数据库\c hr haloSELECT * FROM departments;

Image

Image

4.7 权限生效判断逻辑  

Image