【发布时间】:2020-06-09 16:10:30
【问题描述】:
PostGraphile 不推荐column-level SELECT grants,而是推荐
将您的关注点拆分为多个表格并使用 一对一的关系功能来链接它们。
现在我希望我的users 表有一个role 字段,role_admin 可以访问但role_consumer 不能访问。基于上述建议,我创建了两个表。 users 表(在公共模式中)包含两个角色都可以看到的所有字段,user_accounts(在私有模式中)包含只有role_admin 必须能够看到的role 字段。 role 字段通过计算列添加到 user GraphQL 类型。
CREATE SCHEMA demo_public;
CREATE SCHEMA demo_private;
/* users table*/
CREATE TABLE demo_public.users (
user_id SERIAL PRIMARY KEY,
first_name VARCHAR(50) NOT NULL,
);
/* user_accounts */
CREATE TABLE demo_private.user_accounts (
user_id INT PRIMARY KEY REFERENCES demo_public.users (user_id) ON DELETE CASCADE,
role text not null default 'role_consumer',
);
/* role as computed column */
CREATE FUNCTION demo_public.users_role
(
u demo_public.users
)
RETURNS TEXT as $$
<code>
$$ LANGUAGE SQL STRICT STABLE;
现在基本上我有两种药水可以设置权限。
1) 第一个选项是使用表级安全性。 IOW 将表 user_accounts 上的选择访问权限仅授予 role_admin。
GRANT SELECT ON TABLE demo_private.user_accounts TO role_admin;
GRANT EXECUTE ON FUNCTION demo_public.users_role(demo_public.users) TO role_admin;
ALTER TABLE demo_private.user_accounts ENABLE ROW LEVEL SECURITY;
CREATE POLICY select_any_user_accounts ON demo_private.user_accounts FOR SELECT TO role_admin using (true);
这种方法的问题在于,当role_consumer 运行包含role 字段的查询时
{
me {
firstname
role
}
}
上述查询返回错误。这不好,因为错误会影响隐藏其他同级字段结果的整个结果。
2) 另一个选项是使用除表级别之外的行级别安全性;表级别的 IOW,将表 user_accounts 的选择访问权限授予 role_admin 和 role_consumer,但在行级别仅允许管理员访问 user_accounts 的行。
GRANT USAGE ON SCHEMA demo_private TO role_consumer;
GRANT SELECT ON TABLE demo_private.user_accounts TO role_consumer;
GRANT EXECUTE ON FUNCTION demo_public.users_role(demo_public.users) TO role_consumer;
ALTER TABLE demo_private.user_accounts ENABLE ROW LEVEL SECURITY;
CREATE POLICY select_user_accounts ON demo_private.user_accounts FOR SELECT
USING ('role_admin' = nullif(current_setting('role', true), ''));
现在如果consumer_role 的用户运行上述查询,role 字段将为空,不会影响其兄弟字段。但是有两个问题:
我们是否应该始终避免错误以防止它们影响兄弟姐妹?
如果是,我们是否应该始终在行级别处理事情,而不是只在表级别处理?
【问题讨论】:
标签: postgresql graphql postgraphile