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;

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语句更改配置变量的角色会话默认值。
例如:

查询系统视图pg_roles可查询角色拥有的属性。
select * from pg_roles where rolname = 'role_name';

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;-- 检查角色继承关系SELECTrolname AS "子角色",array_agg(roleid::regrole) AS "继承的父角色"FROM pg_auth_membersJOIN 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; -- 移除角色组无权限,执行失败。

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 授予其他用户

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数据库除外)。

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

使用has_database_privilege(RoleName, DbName,PrivilegeType)函数查询用户数据库级别权限,下列语句可查询指定角色的数据库级权限。
SELECTd.datname AS "DbName",r.rolname AS "RoleName",CASEWHEN has_database_privilege(r.rolname, d.datname, 'CONNECT') THEN 'YES'ELSE 'NO'END AS "CONNECT",CASEWHEN has_database_privilege(r.rolname, d.datname, 'CREATE') THEN 'YES'ELSE 'NO'END AS "CREATE",CASEWHEN has_database_privilege(r.rolname, d.datname, 'TEMPORARY') THEN 'YES'ELSE 'NO'END AS "TEMPORARY"FROMpg_roles r, pg_database dWHERE 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;-- 查看用户权限SELECTd.datname AS "DbName",r.rolname AS "RoleName",CASEWHEN has_database_privilege(r.rolname, d.datname, 'CONNECT') THEN 'YES'ELSE 'NO'END AS "CONNECT",CASEWHEN has_database_privilege(r.rolname, d.datname, 'CREATE') THEN 'YES'ELSE 'NO'END AS "CREATE",CASEWHEN has_database_privilege(r.rolname, d.datname, 'TEMPORARY') THEN 'YES'ELSE 'NO'END AS "TEMPORARY"FROMpg_roles r, pg_database dWHERE 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)); -- 成功创建临时表

示例2:不可移除超级用户的权限,因为超级用户可以绕过除登录权限(login)之外的所有安全检查。
-- 创建超级用户create user test2 superuser;-- 查看超级用户数据库级权限SELECTd.datname AS "DbName",r.rolname AS "RoleName",CASEWHEN has_database_privilege(r.rolname, d.datname, 'CONNECT') THEN 'YES'ELSE 'NO'END AS "CONNECT",CASEWHEN has_database_privilege(r.rolname, d.datname, 'CREATE') THEN 'YES'ELSE 'NO'END AS "CREATE",CASEWHEN has_database_privilege(r.rolname, d.datname, 'TEMPORARY') THEN 'YES'ELSE 'NO'END AS "TEMPORARY"FROMpg_roles r, pg_database dWHERE r.rolname = 'test2' AND d.datname = 'test';-- 尝试移除超级用户对test库所有权限,无效revoke all on database test FROM public;revoke all on database test FROM test2;-- 再次查看超级用户数据库级权限,权限未被移除SELECTd.datname AS "DbName",r.rolname AS "RoleName",CASEWHEN has_database_privilege(r.rolname, d.datname, 'CONNECT') THEN 'YES'ELSE 'NO'END AS "CONNECT",CASEWHEN has_database_privilege(r.rolname, d.datname, 'CREATE') THEN 'YES'ELSE 'NO'END AS "CREATE",CASEWHEN has_database_privilege(r.rolname, d.datname, 'TEMPORARY') THEN 'YES'ELSE 'NO'END AS "TEMPORARY"FROMpg_roles r, pg_database dWHERE r.rolname = 'test2' AND d.datname = 'test';\c test test2

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级权限。
SELECTn.nspname AS schema_name,r.rolname AS rolname,CASEWHEN has_schema_privilege(r.rolname, n.nspname, 'USAGE') THEN 'YES'ELSE 'NO'END AS "USAGE",CASEWHEN has_schema_privilege(r.rolname, n.nspname, 'CREATE') THEN 'YES'ELSE 'NO'END AS "CREATE"FROMpg_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;-- 查看两个用户数据库级权限SELECTd.datname AS "DbName",r.rolname AS "RoleName",CASEWHEN has_database_privilege(r.rolname, d.datname, 'CONNECT') THEN 'YES'ELSE 'NO'END AS "CONNECT",CASEWHEN has_database_privilege(r.rolname, d.datname, 'CREATE') THEN 'YES'ELSE 'NO'END AS "CREATE",CASEWHEN has_database_privilege(r.rolname, d.datname, 'TEMPORARY') THEN 'YES'ELSE 'NO'END AS "TEMPORARY"FROMpg_roles r, pg_database dWHERE (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级权限SELECTn.nspname AS schema_name,r.rolname AS rolname,CASEWHEN has_schema_privilege(r.rolname, n.nspname, 'USAGE') THEN 'YES'ELSE 'NO'END AS "USAGE",CASEWHEN has_schema_privilege(r.rolname, n.nspname, 'CREATE') THEN 'YES'ELSE 'NO'END AS "CREATE"FROMpg_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)); -- 执行成功


示例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级权限SELECTn.nspname AS schema_name,r.rolname AS rolname,CASEWHEN has_schema_privilege(r.rolname, n.nspname, 'USAGE') THEN 'YES'ELSE 'NO'END AS "USAGE",CASEWHEN has_schema_privilege(r.rolname, n.nspname, 'CREATE') THEN 'YES'ELSE 'NO'END AS "CREATE"FROMpg_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; -- 执行成功


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_tableAccess privilegesSchema | 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; -- 查询包含未授权列,执行失败

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)
如下例:


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)可对查询表空间相关权限。

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 ]

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 departmentsFOR 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;


4.7 权限生效判断逻辑





