PostgreSQL中实现行级安全性的研究

作为补充 PostgreSQL存储函数层面实现业务逻辑的研究 и 主要是为了详细解答一条评论.

理论部分在文档中有很好的描述 PostgreSQL - 行保护策略。 下面是一个小例子的实际实现 特定业务任务 - 隐藏已删除的数据。 专用于实施的草图 使用 RLS 进行角色建模 分别提出。

PostgreSQL中实现行级安全性的研究

文章没有什么新意,没有隐藏的含义或秘密知识。 只是一个关于理论想法的实际实施的草图。 如果有人感兴趣,请阅读它。 如果您不感兴趣,请不要浪费时间。

制定问题

在不深入研究该主题领域的情况下,简单地说,问题可以表述如下: 有一个表,实现了某个业务实体。 表中的行可以被删除,但行不能被物理删除;它们必须被隐藏。

因为有句话说:“不要删除任何内容,只需重命名即可。 互联网存储一切”

在此过程中,建议不要重写与该实体一起使用的现有存储函数。

为了实现这个概念,该表具有属性 已删除。 那么一切就很简单了 - 您需要确保客户端只能看到属性所在的行 已删除 错误的该机制是用来做什么的? 行级安全性。

履行

创建单独的角色和架构

CREATE ROLE repos;
CREATE SCHEMA repos;

创建目标表

CREATE TABLE repos.file
(
...
is_del BOOLEAN DEFAULT FALSE
);
CREATE SCHEMA repos

打开 行级安全性

ALTER TABLE repos.file  ENABLE ROW LEVEL SECURITY ;
CREATE POLICY file_invisible_deleted  ON repos.file FOR ALL TO dba_role USING ( NOT is_deleted );
GRANT ALL ON TABLE repos.file to dba_role ;
GRANT USAGE ON SCHEMA repos TO dba_role ;

服务功能 — 删除表中的一行

CREATE OR REPLACE repos.delete( curr_id repos.file.id%TYPE)
RETURNS integer AS $$
BEGIN
...
UPDATE repos.file
SET is_del = TRUE 
WHERE id = curr_id ; 
...
END
$$ LANGUAGE plpgsql SECURITY DEFINER;

业务功能 — 删除文档

CREATE OR REPLACE business_functions.deleteDoc( doc_for_delete JSON )
RETURNS JSON AS $$
BEGIN
...
PERFORM  repos.delete( doc_id ) ;
...
END
$$ LANGUAGE plpgsql SECURITY DEFINER;

结果

客户端删除文档

SELECT business_functions.delCFile( (SELECT json_build_object( 'CId', 3 )) );

删除后客户端看不到该文档

SELECT business_functions.getCFile"( (SELECT json_build_object( 'CId', 3 )) ) ;
-----------------
(0 rows)

但在数据库中文档并没有被删除,只是属性被改变了 是_删除

psql -d my_db
SELECT  id, name , is_del FROM repos.file ;
id |  name  | is_del
--+---------+------------
 1 |  test_1 | t
(1 row)

这就是问题陈述中所要求的。

如果该主题有趣,在下一个研究中,您可以展示一个实现基于角色的模型以使用行级安全性分离数据访问的示例。

来源: habr.com

添加评论