使用 Access ODBC 链接表的 PostgreSQL 授权

PostgreSQL authorization with Access ODBC Linked Tables

对于不耐烦的人 - 我可以将这个问题总结为:

What practical approach can be used to leverage role-based privileges in PostgreSQL when using an Access Front End that employs ODBC linked-tables?

现在是更长的版本:

我接手了将 Access 2000 / PG 7 应用程序升级到 Access 2013 / PG 9 的艰巨任务。我是 PostgreSQL 的新手,但经常使用 Oracle 和 Microsoft Access。
编辑:生产服务器是 运行 PostgreSQL on Mac OS X Lion。我的测试机是 运行 PostgreSQL on Oracle Linux 7.

此 Access DB 通过 ODBC 链接到 PG 数据库中的 tables,使用单个 PG 登录角色 (application_user) 进行连接。每个用户都连接这个登录角色,限制用户权限的只是Forms/VBA中的条件。但是,如果用户可以进入导航窗格 - 他们可以直接访问链接的 table 并绕过所有安全限制。在升级此数据库时,我想看看是否可以收紧它。

我可以在 PostgreSQL 上为每个用户设置他们自己的登录角色,但这意味着(从我的角度来看)对数据库进行大量重组。我不想对生产数据库进行如此大的更改 - 更需要增量更改。

查看数据库的安全需求 - 我可以想到只需要五个角色。

我可以在 PGSQL 中将它们设置为组角色,并且每个 table 都为每个角色设置必要的 ACL。

我缺少的是如何从单个登录角色 (application_user) 转到所有上述角色?

我最初的想法是将 application_user(登录角色)设置为没有组角色(基本上导致 "Not Authorized - No Access" ),然后调用 PL/pgSQL 函数 authorize(Username, MD5PassWord) 来授权和提升角色。该函数将检查提供的 MD5 哈希值是否与存储在用户 table 中的 MD5 哈希值匹配 - 如果匹配 - 它会为适当的组角色发出 SET SESSION ROLE
如果这行得通,它会让我跟踪登录的用户名,然后使用 pg_backend_pid() 函数,我可以将它与业务逻辑的用户关联起来或记录或其他什么。这也意味着我不必担心某些用户进入链接 Table - 因为他们的访问将受到他们当前在该数据库会话中被授权的任何角色的限制。

所以我编写了一个 plpgsql 脚本,将其所有者设置为 OrderCustomerEntryGroup 并赋予它 SECURITY DEFINER 权限。

DECLARE
    v_Status integer;
BEGIN
    v_Status := 0;
    IF pin_username = 'username' AND MD5('foo') = pin_pwmd5 THEN
      SET SESSION AUTHORIZATION OrderEntryGroup;
      v_Status := 1;
    END IF;
    RETURN v_Status;
END;

然而,我的实施唯一的问题是

SELECT authenticate('username',MD5('foo'));

给出:

ERROR: cannot set parameter "session_authorization" within security-definer function
SQL state: 42501
Context: SQL statement "SET SESSION AUTHORIZATION OrderEntryGroup"
PL/pgSQL function authenticate(character varying,text) line 7 at SQL statement

所以我仔细阅读了这个 - 据我所知,你曾经能够这样做,但无论出于何种原因它被删除了。除了在每个用户级别使用内置角色外,我还没有找到替代方案。

所以我要问的是..我缺少什么来使我的方法(一个简单的解决方案)起作用,或者有没有更好的方法可以做到这一点而不涉及撕裂现有的访问数据库?

如果您想限制直接连接对数据库的访问,那么无论如何您都需要在后端执行一定数量的 "retooling"。最好的方法几乎总是让每个用户使用他们自己的凭据连接,然后根据他们在数据库中所属的组(有时称为 "roles")限制该用户可以执行的操作。

如果您想避免为每个网络用户设置单独的数据库 userids/passwords,那么您应该研究使用集成 Windows 身份验证 (SSPI),如另一个问题 here 中所讨论的.您仍然需要在数据库级别定义用户(除了 groups/roles),但无论如何您都必须完成大部分工作。