所以我一直对vew的安全性和行级安全性之间的区别感到困惑。
所以我想我的一般问题是
当视图可以限制一个人对行和/或列的访问时,为什么需要行级访问?
所以我一直对vew的安全性和行级安全性之间的区别感到困惑。
所以我想我的一般问题是
当视图可以限制一个人对行和/或列的访问时,为什么需要行级访问?
我想创建一个依赖于同一表中其他记录的策略。例如,假设有以下联结表:
project_id | user_id
------------+----------
1 | 1
------------+----------
1 | 2
------------+----------
2 | 2
我想阻止用户选择与其不相关的项目相关的记录,并允许选择其余的。
就像是:
CREATE POLICY project_user_read ON project_user FOR SELECT
USING(
project_id IN(
SELECT project_id
FROM project_user
WHERE user_id = current_setting('app.current_user_id')::bigint ---> I use runtime variables
)
);
这将导致这种方式:
SET app.current_user_id = 1;
SELECT * FROM project_user;
-- project_id | user_id
-- ------------+----------
-- 1 | 1
-- ------------+----------
-- 1 | 2
这显然不起作用,因为它是一个循环条件。
有没有办法用 RLS 实现这样的逻辑?
尝试时CREATE POLICY
出现以下错误:
ERROR: row is too big: size XXX, maximum size 8160
pg_policies表有大小限制吗?
可以扩大,还是用连接写这么多条件是不好的做法?
现在,我通过将查询更改为更少的字符来解决它,但是如何避免呢?
几乎太长的政策示例。
CREATE POLICY check_out_insert ON check_out FOR INSERT
WITH CHECK (
(user_id = current_setting('app.current_user_id')::bigint AND
file_version_id = ANY(ARRAY(
SELECT file_version.id fv_id FROM file_version
INNER JOIN "file" ON (file_version.file_id = "file".id)
INNER JOIN "file_user" ON ("file".id = "file_user".file_id AND file_user.deleted_at IS NULL)
WHERE file_user.user_id = current_setting('app.current_user_id')::bigint)
)
OR
true = ANY(
ARRAY(SELECT is_owner
FROM "group"
WHERE id = current_setting('app.current_user_group_id')::bigint
LIMIT 1
)
)
OR
file_version_id = ANY(
ARRAY(SELECT DISTINCT file_version.id fv_id FROM file_version
INNER JOIN "file" ON (file_version.file_id = "file".id)
INNER JOIN "sub_folder" ON (file.sub_folder_id = "sub_folder".id)
INNER JOIN "folder" ON (sub_folder.folder_id = "folder".id)
INNER JOIN "folder_group" ON (folder_group.folder_id = "folder".id AND folder_group.group_id = current_setting('app.current_user_group_id')::bigint)
INNER JOIN "project_user" ON (folder.project_id = "project_user".project_id AND "project_user".user_id = current_setting('app.current_user_id')::bigint)
WHERE folder.type = 'nda'
)
)
)
);`);
我想创建一个标签文本的有序列表,所以我编写了以下初始脚本: Schema (PostgreSQL v10.0)
create table tbl1 (
uid text primary key /* user id */
);
create table tbl2 (
uid text not null default current_setting('custom.setting.uid', true)::text,
order_id int not null,
labeltext text,
foreign key (uid) references tbl1 (uid) on delete cascade
);
INSERT INTO tbl1 (uid) VALUES ('boom');
INSERT INTO tbl1 (uid) VALUES ('bang');
INSERT INTO tbl1 (uid) VALUES ('bash');
alter table tbl2 enable row level security;
create policy all_order on tbl2 for all
using (uid = current_setting('custom.setting.uid', true)::text)
with check (uid = current_setting('custom.setting.uid', true)::text);
create or replace function tfn(text) returns int as $$
declare
tmp int;
begin
insert into tbl2(order_id, labeltext)
select coalesce(
(select order_id
from tbl2
order by order_id desc limit 1
),
0
) + 1, $1
returning order_id into tmp;
return tmp;
end;
$$ language plpgsql;
set custom.setting.uid to 'boom';
show custom.setting.uid;
select tfn('foo');
select tfn('bar');
set custom.setting.uid to 'bang';
select tfn('baz');
tfn
期望为当前用户获得最大的 order_id并插入一些带有增加的 order_id 的新标签文本。但是,结果看起来不同:
**Query #1**
select * from tbl2;
| uid | order_id | labeltext |
| ---- | -------- | --------- |
| boom | 1 | foo |
| boom | 2 | bar |
| bang | 3 | baz |
期望用户bang创建的行具有order_id = 1,但实际上...... 它仍然能够无限制地选择其他用户的order_id
更新时如何使用RLS限制order_id的选择?如果这不适用于 RLS,还有其他选择吗?
行级安全性的优缺点是什么?
我们正在将数据库从桌面应用程序移植到 Web 应用程序,并想知道确保敏感数据安全的最佳方法。
对于我们的应用程序,登录系统的用户数量有限,例如受信任的承包商而不是公众。
我们当然可以编写查询来逐个检查权限,或者设置行以便只有该组织的承包商才能看到该行。
使用什么标准来决定什么是最佳实践?
我有一个结构如此的表(简化)
Name, EMail, LastLoggedInAt
我在 SQL Server (RemoteUser) 中有一个用户应该只能看到 LastLoggdInAt 字段不为空的数据(通过选择查询)。
看起来我可以做到这一点?可能吗?
如何配置一个表,使用户可以修改该用户“拥有”的行,但不能修改其他用户“拥有”的行?