PG 数据库安全策略层次结构:

image.png

行级安全策略概述

- 行级安全策略是提供更细粒度的访问控制,比如不同用户可以看到表中不同的数据。

- 行级安全策略可以加在表上,也可以加在角色上,也可以两者都加。命令可以是 ALL、SELECT、INSERT、UPDATE 和 DELETE,同一个策略也可以赋予多个角色。

- 超级用户(postgres)以及加上了 BYPASSRLS 属性的角色不受安全性的限制。

- 每个表可以定义多个策略,因为策略是针对表的,所以表内的多个策略名字必须唯一。

- 不同的表可以有同名的策略,当表有多个策略时,多个策略之间是 OR 的关系,所有策略中任意一个为 TRUE 都通过。

行级安全策略开关

-打开/关闭行级安全策略

ALTER TABLE tab_name ENABLE/DISABLE ROW LEVEL SECURITY;

 

行级安全策略创建

CREATE POLICY name ON table_name

[ AS { PERMISSIVE | RESTRICTIVE } ]

[ FOR { ALL | SELECT | INSERT | UPDATE | DELETE } ]

[ TO { role_name | PUBLIC | CURRENT_ROLE | CURRENT_USER | SESSION_USER } [, ...] ]

[ USING ( using_expression ) ]

[ WITH CHECK ( check_expression ) ]

- name:同一个表上的 policy 不能重复,不同表的 policy 可以重复。

- AS,policy 的生效模式,PERMISSIVE => or,RESTRICTIVE => and,默认 PERMISSIVE。

- FOR,对哪个操作生效,默认 ALL。

- TO,对哪个 role 生效,默认 public。

- USING:对表中的已有数据进行检查的语句,可实施在 select、update、delete、all 上。

- WITH CHECK:对新数据进行检查的语句,可实施在 insert、update、all 上。

 

行级安全策略删除

DROP POLICY [ IF EXISTS ] name ON table_name [ CASCADE | RESTRICT ]

CASCADE | RESTRICT 这些关键词没有任何影响,因为它们不依赖于策略。

 

行级安全策略修改

ALTER POLICY name ON table_name RENAME TO new_name

ALTER POLICY name ON table_name

[ TO { role_name | PUBLIC | CURRENT_ROLE | CURRENT_USER | SESSION_USER } [, ...] ]

[ USING ( using_expression ) ]

[ WITH CHECK ( check_expression ) ]

 

行级安全策略信息查询

行级安全策略查看:

select * from pg_policy;

查看表创建的安全策略规则:

select relname,relrowsecurity,relforcerowsecurity from pg_class where relname='tab_name';

查看某个角色跳过安全策略规则:

select rolname,rolbypassrls from pg_roles where rolname='role_name';

 

跳过/不跳过行级安全策略

alter user role_name bypassrls/nobypassrls;

 

行级安全策略实践案例

1、建模式与表

CREATE SCHEMA hisinfo;

CREATE TABLE hisinfo.patient(id int, patname name, doctname name);

INSERT INTO hisinfo.patient VALUES(1,'pat0l','doctor01');

INSERT INTO hisinfo.patient VALUES(2,'pat02','doctor02');

INSERT INTO hisinfo.patient VALUES(3,'pat03','doctor03');

 

2、启用行级安全策略

ALTER TABLE hisinfo.patient ENABLE ROW LEVEL SECURITY;

 

3、建模用户

create user doctor01 password 'kingbase';

create user doctor02 password 'kingbase';

create user doctor03 password 'kingbase';

 

4、授权

grant usage on schema hisinfo to doctor01;

grant usage on schema hisinfo to doctor02;

grant usage on schema hisinfo to doctor03;

grant select on hisinfo.patient to doctor01;

grant select on hisinfo.patient to doctor02;

grant select on hisinfo.patient to doctor03;

 

5、创建行级安全策略

create policy patient_rls on hisinfo.patient using (doctname=current_user);

 

6、验证

psql -U doctor01 -d postgres -c "select * from hisinfo.patient;"

psql -U doctor02 -d postgres -c "select * from hisinfo.patient;"

psql -U doctor03 -d postgres -c "select * from hisinfo.patient;"

psql -U u1 -d postgres -c "select * from hisinfo.patient;"

 

7、bypassrls/nobypassrls 验证

psql  -Uu1  -dpostgres  -c "select * from hisinfo.patient;"

pg大讲堂137直播回放.jpg