如何首先使用带数据库凭证轮换的 postgresql 设置由 EF 核心代码创建的对象的默认所有者?

How to set default owner of objects created by EF core code first using postgresql with database credential rotation?

我正在从容器化 asp.net 核心 3.1 应用程序 运行 代码优先 EF 核心连接到具有 PostgreSQL 兼容性的 Amazon Aurora 实例,并希望执行数据库凭证轮换。我已经设置了一个代表数据库所有者的角色,以及一个代表我们将过期并替换为新凭据的当前有效登录凭据的角色。

我采纳了此博客的建议 post: http://davidhollenberger.com/2017/03/16/postgres-credential-rotation/,本质上是:

create role db_owner nologin;
create role foo_a with encrypted password ...;
grant db_owner to foo_a;
alter role foo_a set role db_owner;

我了解到每当 foo_a 登录到 postgres 时,他们的默认角色设置为 db_owner。如果我使用 psql 登录数据库,这似乎一直有效。

但是,对于 EF Core,当使用 foo_a 数据库凭据连接时将数据库迁移到新架构,新对象的对象所有者列为 foo_a

示例:

                       List of relations
 Schema | Name | Type  |                 Owner
--------+------+-------+----------------------------------------
 public | test | table | foo_a

我预计所有者是 db_owner,因为 foo_a 应该始终以 db_owner 身份登录。

我可以从 EF Core 做些什么,或者在设置 postgresql 数据库时允许我们将用户创建的所有对象的默认所有权设置为代表我们的角色组数据库所有者?我不希望将这些临时帐户设为实例的某种 'superuser',因为我们的数据库实例中有多个租户,相反,我希望拥有类似于 'dbo' 角色的东西,该角色拥有数据库和临时用户将始终以 'dbo' 角色连接。

使用 DISCARD ALL 语句重置合并的连接,这又将会话和当前用户标识符重置为最初经过身份验证的用户名。换句话说:

  1. 合并连接重置(https://www.npgsql.org/doc/performance.html#pooled-connection-reset
  2. 运行 DISCARD ALL (https://www.postgresql.org/docs/current/sql-discard.html)
  3. 依次运行 SET SESSION AUTHORIZATION DEFAULT (https://www.postgresql.org/docs/8.1/sql-set-session-authorization.html)

在数据库迁移期间,这会将创建的任何对象的所有者设置为用户,而不是他自动继承的 dbo 角色 ALTER ROLE... SET ROLE...

解决此问题的选项将取决于您的需要。以下是我们考虑解决此问题的几个选项:

  1. 使数据库所有者成为数据库用户的成员。用作为我们 database/user 供应和轮换策略的一部分运行的脚本对此进行补充,该策略将所有对象所有权设置为所有者而不是用户。这需要对 .net 核心应用程序进行零代码更改,但从对象所有权的角度来看确实很混乱。
  2. 在 .Net 中,当我们重用池中的连接时,使用 IDBCommandInterceptor 设置适当的角色。这是一种影响您的 .net 核心项目的更具侵入性的解决方案,但如果您的要求涉及一个或仅几个项目的凭证轮换,它可能是实用的。
  3. 将选项 No reset on close=true 附加到 npgsql 连接字符串。但是,请注意,如果您使用连接池,这可能会导致会话状态泄漏。参考:https://www.npgsql.org/doc/connection-string-parameters.html#performance

其他选项,例如 运行 代理也值得考虑。