如何使用 Postgraphile 或替代方案在 Postgres 中实现复杂的基于权限的数据访问

     2023-03-08     257

关键词:

【中文标题】如何使用 Postgraphile 或替代方案在 Postgres 中实现复杂的基于权限的数据访问【英文标题】:How to implement complex permission based data access in Postgres with Postgraphile or alternatives 【发布时间】:2021-02-03 04:15:02 【问题描述】:

对于一个新项目,我们目前正在设计一个数据库和一个 API 来访问它。我们已经确定我们将对数据库使用 PostgresQL,并希望通过 GraphQL API 访问它。

为了简化可维护性,我们研究了客户端/API/数据库之间的几个中介,主要是 Prisma、PostGraphile 和 Hasura。 PostGraphile 脱颖而出,因为它易于使用,并且专注于处理“在数据库中”而不是在后端代码中的内容。但是,我们在弄清楚如何实现这一点时遇到了问题。

请允许我扩展我们迄今为止的设计:


临时数据库设计:

usersgroupsroles表: u_g_r 表:一个用户可以属于多个组,并且每个组中可以有多个角色。此表表示 usersgroupsroles 的外键,因为几乎所有组合都可以存在多对多关系。

数据权限:

我们希望用户通过几个步骤授予其他人访问其个人数据的权限,最好是针对每个组。例如:

第 3 级:您自己,只有绝对必要的人,例如客户经理 2 级:仅限 X、Y 等组中的人 1 级:所有人

如果可以为各种类型的数据设置此项,那就太棒了,例如为您的电话号码授予第 2 级,但为您的实际地址授予第 1 级。 因此,这些级别 (1、2、3) 将伴随数据库中的数据,例如 phone_numberphone_number_access_level。然后,在u_g_r 联结表中,user/group/role 的每个组合都将附加一个允许的级别,该级别必须高于相关数据所需的级别。因此,如果您的role 允许访问级别 2 的数据,您将能够查看级别 1 和级别 2 的数据,但不能查看级别 3。


Postgres 允许列和行级别的安全性,让用户访问某些数据。 PostGraphile wiki 详细介绍了(here 和 here)如何使用 JWT 声明而不是 PostGres 角色来完成这项工作。 当我们想要实现上述功能时,我们的问题就来了。似乎我们想要一种不存在的“现场级安全”,但我无法想象其他人没有遇到同样的问题。

你会建议我们做什么?请让我知道是否有我们遗漏的选项,或者是否还有其他更适合我们的选项!

在数据库之外,在后端代码中实现这一点本身可能是最简单的方法,但它极大地影响了我们的可维护性,因为像 PostGraphile 这样的东西对我们来说主要的奢侈是消除了编写 GraphQL 模式和自行解析。

【问题讨论】:

Hasura 的权限系统同时考虑字段和行级安全性,即您可以对具有以下条件的表具有权限:1) 角色 1 可以访问字段 A、字段 B 和行条件 1 和 2) 角色 2 可以访问字段 C ,字段D和行条件2。见:hasura.io/docs/1.0/graphql/core/auth/authorization/… 【参考方案1】:

您似乎希望所有用户都能看到所有表格行,但只能看到某些列。

您可能无法使用列权限,因为这些权限只能允许或拒绝对整个列的访问,并且不尊重谁“拥有”某个表行。

所以也许视图可以做你想做的事,例如:

CREATE VIEW users_view
WITH (security_barrier = true, check_option = local) AS
SELECT /* accessible to everyone */
       username,
       /* accessible only to certain groups */
       CASE WHEN pg_has_role('x', 'USAGE') OR pg_has_role('y', 'USAGE')
            THEN level2_col
            ELSE NULL
       END AS level2_col,
       /* accessible only to admins and owner */
       CASE WHEN username = current_user OR pg_has_role('admin', 'USAGE')
            THEN level3_col
            ELSE NULL
       END AS level3_col
FROM users;

security_barrier 确保没有人可以使用具有副作用的函数来破坏安全性,check_option 确保没有人可以INSERT 一个他们自己不可见的行。

如果您定义INSTEAD OF 触发器,您可以允许对视图进行 DML 操作。

【讨论】:

非常有趣!我一定会调查的!【参考方案2】:

根据 Laurenz Albe 的回答,我为各种列创建了一个巨大的视图。它确实有效,即使有数千个模拟数据条目,它仍然相对较快。

当我上周回到它时,我突然想到了一个更清洁的解决方案(可以说)。我现在不使用像这样的自定义视图,而是使用包含敏感数据的单独表,将它们与外键链接并在这些行上启用行级别安全性。

我没有做过任何基准测试,但它应该会更快,因为这些数据并不总是被要求。它至少节省了带有大量样板的复杂视图!

【讨论】:

在 django 中使用物化视图或替代方案

】在django中使用物化视图或替代方案【英文标题】:usingmaterializedviewsoralternativesindjango【发布时间】:2015-06-2508:29:25【问题描述】:我需要在我的django应用程序中使用一些经常更改的aggregate数据,如果我进行动态计算,可能会出... 查看详情

如何提高子查询的性能或 sql 中子查询的替代方案

】如何提高子查询的性能或sql中子查询的替代方案【英文标题】:Howtoimprovetheperformanceofsubqueryoranalternativetosubqueryintsql【发布时间】:2012-11-2809:04:38【问题描述】:我正在使用以下查询在我的一个javaswing应用程序中显示记录。此... 查看详情

如何从 SuperBible 获取 GLTools 库以在 Ubuntu 中工作?或替代方案? [关闭]

】如何从SuperBible获取GLTools库以在Ubuntu中工作?或替代方案?[关闭]【英文标题】:HowtogettheGLToolslibraryfromSuperBibletoworkinUbuntu?oranalternative?[closed]【发布时间】:2012-06-2115:16:54【问题描述】:我最近买了SuperBible第5版书。我使用Ubuntu... 查看详情

Zaypay 使用电话或短信付款的替代方案

】Zaypay使用电话或短信付款的替代方案【英文标题】:Zaypayalternativesforpaymentsusingcallorsms【发布时间】:2011-01-1117:44:33【问题描述】:我们目前正在尝试在zaypay中实施支付服务提供商,以使用短信或拨打号码来支付服务费用。我... 查看详情

如何将 PDFBox 添加到 Android 项目或建议替代方案

】如何将PDFBox添加到Android项目或建议替代方案【英文标题】:HowtoaddPDFBoxtoanAndroidprojectorsuggestalternative【发布时间】:2012-02-1708:03:35【问题描述】:我正在尝试打开现有的pdf文件,然后从Android应用程序中将另一个页面添加到pdf文... 查看详情

java示例代码_JSoup的替代方案或如何清理空白

java示例代码_JSoup的替代方案或如何清理空白 查看详情

工会与案例或其他替代方案

...然后我想要“传统”组织。如果没有联合,我无法弄清楚如何解决这个问题,我不想使用联合,因为我的一些查询很长而且很复杂。我当前的方法是两 查看详情

/dev/dsp 窗口替代

...在Linux中播放或录制一些音频只是读取或写入/dev/dsp但是如何在windows中做同样的事情呢?(与C)【问题讨论】:【参考方案1】:没有静态设备名称,您应该使用waveOut*函数,here是使用这些API的一个很好的例子。【讨论】:【参... 查看详情

如何在 iPad 上实现 iTunes 文件共享的替代方案?

】如何在iPad上实现iTunes文件共享的替代方案?【英文标题】:HowcanIimplementanalternativetoiTunesfilesharingontheiPad?【发布时间】:2011-04-2009:14:31【问题描述】:我需要将文件从处于“飞行模式”(蓝牙、WLAN和GSM均不可用)的iPad传输到... 查看详情

移动应用程序 - 推送通知替代方案?

...使用它吗?使用轮询或实现您自己的推送通知服务(无论如何都使用轮询)是一个很大的拒绝吗?GCM是否适用于i 查看详情

在 Kubernetes 中进行 Spring Boot 集成测试的 Testcontainers 的选项或替代方案?

...netes?【发布时间】:2021-12-1908:21:25【问题描述】:我需要使用Postgres、Redis和Elasticsearch在SpringBoot项目中 查看详情

ASP.NET MVC 5 实体框架替代方案或在运行时指定架构的能力?

...17-10-1201:16:54【问题描述】:我目前在我的ASP.NETMVC5项目中使用EntityFramework6。我们拥有的每个客户端都有自己的数据库模式。据我目前发现,在运行时使用实体框 查看详情

window.scrollTo 在 phonegap 中不起作用 - 替代解决方案或解决方法?

...下方完美对齐iPhone键盘,获得焦点(如果您喜欢,请随意使用它!)。对齐主要 查看详情

大容量核心数据搜索或其他替代方案?

...由productId、channelId、regionId、date和AUMValue组成。我们可以使用Co 查看详情

ESlint for VSCode 不使用节点或替代方案?

】ESlintforVSCode不使用节点或替代方案?【英文标题】:ESlintforVSCodewithoutusingnodeoralternative?【发布时间】:2018-06-2004:14:02【问题描述】:我们正在向初学者教授基本的JavaScript,并且最近从Atom编辑器切换到VSCode。问题在于VSCode要求... 查看详情

使用 sincedb 使用 logstash 删除传输的日志,或使用替代解决方案

】使用sincedb使用logstash删除传输的日志,或使用替代解决方案【英文标题】:Deletetransferredlogswithlogstashusingsincedb,oruseanalternativesolution【发布时间】:2017-06-1414:13:04【问题描述】:我想使用logstash将日志文件从本地目录移动到elastic... 查看详情

JPA 性能优化或替代方案

...一个对数据库读取性能要求很高的项目中。我们目前正在使用JPA(EclipseLink实现),目前只是因为它提供了方便的数据库访问和列映射。对于我们的查询,我们使用高度具体的SQL查询。我们还使用一个数据库(SAPHANA,内存中),... 查看详情

如何在 eslint 中使用 atom-typescript 或替代方法

】如何在eslint中使用atom-typescript或替代方法【英文标题】:Howtouseatom-typescriptoralternativewitheslint【发布时间】:2020-11-1612:22:15【问题描述】:Atom包-已安装原子打字稿仅语言打字稿语法短绒linter-eslintlinter-stylelintlinter-ui-default更漂... 查看详情