乐趣区

关于数据库:技术贴-走进-PostgreSQL-行级安全策略

对于技术流系列

博客开物成务,厚积薄发。技术流系列博客 - 以“短小精悍”的模式遍及数据库硬核技术。置信大家的每一次浏览,都会间隔数据库内核更近一步。每一份来自你们的关注,都是咱们保持输入的满满能量!

一、行级平安介绍

行级平安(RLS,Row-Level Security)可管制用户拜访数据库的查看权限,简化应用程序的设计和编码,帮忙实现数据库行级数据的访问控制。每一次尝试拜访数据,都会受到 RLS 的限度,RLS 使得数据库安全零碎更加稳固、牢靠、弱小。

RLS 次要的利用场景是能够确保不同的用户拜访不同的数据内容。例如,针对公司员工信息,某部门组长只能拜访与其部门相干的员工信息数据行,而 HR 能够拜访整个公司所有员工的信息;一个地区的用户,只能拜访该地区用户的数据,不能拜访其余地区的用户数据,从而合乎数据安全要求和通用数据保护条例(GPDR, General Data Protection Regulation)。

目前大多数数据库,例如 Oracle,SQL Server,PostgreSQL 等,都实现了行级安全控制。后续以 PostgreSQL 的行级平安为例,解说行级安全控制的性能。

二、PostgreSQL 行级平安

PostgreSQL 的每个用户除了能够通过 SQL 规范权限零碎 GRANT 获取权限外,TABLE 还可执行行安全策略(RSP,Row Security Policies)。

行级平安能够限度每个用户的失常查问能够返回哪些行,或通过数据批改命令(INSERT、UPDATE、DELETE)批改哪些行。这个个性,就是上述文章提到的 RLS 在 PostgreSQL 中的利用实现。

默认状况下,表没有任何 RSP,因而用户依据 SQL 权限系统对 TABLE 有拜访权限,表中的所有行都能够进行查问和更新。

当一个 TABLE 启用了 RSP,则所有对 TABLE 数据行失常的查问或批改操作,都必须被 RSP 容许。如果 TABLE 不存在 RSP,则应用默认回绝策略,意味着没有行可见或能够批改。

RSP 能够指定操作命令、限度角色或两者同时指定;能够指定 RSP 利用于所有操作命令(ALL),或 SELECT、INSERT、UPDATE、DELETE 其中之一;能够将多个角色调配给一个 POLICY,并且失常角色成员资格和继承规定失效。

RLS 的实现逻辑次要是通过管制以下内容:

(1)用户、角色及其成员

(2)操作对象

(3)满足条件的数据

(4)具体命令操作

RLS 的管制次要波及以下的语法:

(1)行安全策略操作

(2)表 RLS 开关操作

具体操作步骤代码解析如下:

(1)创立 POLICYCREATE 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 名称。一个表的多个 Policies 名称惟一;表之间的 Policies 名称无关。

  • table_name

TABLE 的名称,能够是 schema_name.table_name 的格局。

  • AS 失效策略

PERMISSIVE:宽松的,多个 PERMISSIVE 策略之间是 OR 关系;

  • RESTRICTIVE:

严格的,多个 RESTRICTIVE 策略之间是 AND 关系。

  • Command

POLICY 实用的命令。无效选项:ALL(默认),或者 SELECT、INSERT、UPDATE、DELETE 其中之一。

  • role_name

用户 / 角色名称、PUBLIC(默认)、CURRENT_ROLE、CURRENT_USER、SESSION_USER 其中之一或其组合。

  • using_expression

任何返回布尔类型的 SQL 条件表达式,但不能够是聚合或窗口函数。如果启用了行级平安,则此表达式将增加到援用该表的查问中。表达式返回 true 的即将是可见的;表达式返回 false 或 null 的行对用户都将不可见(在 SELECT 中),并且不可用于批改(在 UPDATE 或 DELETE 中);这些即将被默默地过滤,不会呈现报错,用户无感知。

  • check_expression

任何返回布尔类型的 SQL 条件表达式,不能够是聚合或窗口函数。如果启用了行级平安,则此表达式将用于表的 INSERT 和 UPDATE 语句,仅容许 INSERT 或 UPDATE 表达式计算为 true 的行。如果对 INSERT 或 UPDATE 产生记录,表达式的计算结果为 false 或 null,则将引发谬误。check_expression 是针对行提交的新内容而不是原数据进行评估的。

(2)批改 POLICY

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) ]

(3)删除 POLICY

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

(4)批改 TABLEALTER TABLE

ALTER TABLE [IF EXISTS] [ONLY] name [*]
    DISABLE   ROW LEVEL SECURITY  -- 启用 RLS
    ENABLE   ROW LEVEL SECURITY  -- 禁用 RLS。RSPs 能够持续存在。FORCE   ROW LEVEL SECURITY  -- RLS 利用于 TABLE 的 OWNER
    NO FORCE ROW LEVEL SECURITY  -- RLS 不利用于 TABLE 的 OWNER

如果一个表上有多个行安全策略,它们的失效程序必须满足以下 2 条规定:

(1)当不同命令类型的多个策略利用于同一命令时(例如,SELECT 和 UPDATE 策略利用于一个 UPDATE 命令),那么用户必须同时领有这两种类型的权限(例如,从 TABLE 中 SELECT 行以及容许 UPDATE 它们的权限)。因而,应用 AND 运算符将两种策略的表达式组合在一起。

(2)当同一命令类型的多个策略利用于同一命令时,必须至多有一个 PERMISSIVE 策略授予对 TABLE 的拜访权限,并且所有 RESTRICTIVE 策略都必须通过。因而,所有 PERMISSIVE 策略表达式应用 OR 组合,所有 RESTRICTIVE 策略表达式应用 AND 组合,后果应用 AND 组合;如果没有 PERMISSIVE 策略,则回绝拜访。

定义 POLICY 时,Command 类型和 USING、WITH CHECK 的实用关系如下表所示。

Command 操作类型与 Policy 类型的表达式失效关系图,如下表所示。

[a]:如果须要对现有行或新行进行读取拜访(例如,援用关系中列的 WHERE 或 RETURNING 子句),则还须要 SELECT/ALL 策略。

RLS 的应用注意事项:

(1)TABLE 的 owner 能力创立、批改、删除、以及 ENABLE 和 DISABLE POLICY。

(2)TABLE 的 owner 拜访数据行通常不受 POLICY 束缚,但 owner 能够抉择应用 ALTER TABLE … FORCE ROW LEVEL SECURITY 来承受 RSP 束缚。

(3)表上无 RSP,然而启用了表的 RLS,默认回绝策略(所有行不可读和改)。

(4)TRUNCATE 和 REFERENCES 不受 POLICY 束缚。

(5)POLICY 在用户 Queries 指定的条件或函数之前失效(除了 Leakproof 函数,Leakproof 会被优化器抉择在 POLICY 之前失效)。

(6)superuser 和具备 BYPASSLRS 属性的角色在拜访表时总是绕过 RLS 零碎。

(7)一个表能够创立多个 POLICY,Policies 之间不重名。不同表之间的 Policies 命名没有关系,能够反复。

(8)POLICY 的表达式仅思考要拜访或更新行的以后值。

三、PostgreSQL 行级平安实例

以下,以 PostgreSQL 为例进行 RLS 的实例演示。

退出移动版