AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / dba / 问题 / 25357
Accepted
Chris Travers
Chris Travers
Asked: 2012-10-04 05:08:02 +0800 CST2012-10-04 05:08:02 +0800 CST 2012-10-04 05:08:02 +0800 CST

PostgreSQL 上金融应用的身份验证方法选择

  • 772

首先是一些背景。

LedgerSMB 项目是一个在 PostgreSQL 上运行的开源财务会计软件项目。我们在用户定义的函数中实现了大量的业务逻辑,作为程序对象方法和数据库行为之间的主要映射工具。目前我们使用数据库用户作为身份验证用户,部分是出于选择(这允许集中的安全逻辑,以便可以编写其他工具并重用授予用户的权限),部分是出于必要(在我们从 SQL-Ledger 分叉后,有在该代码库上改进安全性的选择并不多)。

这使我们能够访问 PostgreSQL 可以访问的合理数量的单点登录选项,从 LDAP 到 Kerberos 5。我们甚至可以在涉及密码的地方使用 PAM。它还允许我们在与其他应用程序集成或允许其他客户端接口时重用权限。对于财务会计应用程序来说,这似乎是一场净赢。

有明显的成本。对于 Web 应用程序,我们非常受限于可以支持的 http auth 类型。例如,DIGEST 完全出局了。BASIC 工作,我们可以很容易地实现 KRB5(我计划支持它并为 1.4 开箱即用)。非常强大的身份验证措施无法直接对此进行适当管理,尽管我们可能会在必要时将它们填充进去(例如 BASIC + 客户端 SSL 证书,其 cn 与用户名和特定的根 ca 匹配)。

与此同时,我们遇到了相当多的批评,主要来自开发人群,偶尔来自 dba,他们告诉我应用程序应该是安全屏障,而不是数据库。我的观点仍然是较小的安全边界通常更好,业务逻辑和安全逻辑的重用是一起使用的,并且我觉得重用业务逻辑而不在同一级别重用安全逻辑是危险的的程序。

我在这里错过了任何主要的权衡吗?有没有我没有考虑的问题?

database-design postgresql
  • 1 1 个回答
  • 3575 Views

1 个回答

  • Voted
  1. Best Answer
    Craig Ringer
    2012-10-04T18:00:14+08:002012-10-04T18:00:14+08:00

    我认为您将身份验证和授权混为一谈。

    我完全同意将安全模型保存在数据库中是明智的,尤其是 LedgerSMB 的设计考虑到了来自多个客户端的访问。除非您计划使用中间件层进行 3 层,否则将用户作为数据库角色是非常有意义的,尤其是对于会计应用程序之类的东西。

    这并不意味着您必须使用 PostgreSQL 支持的身份验证方法针对数据库对用户进行身份验证。您的数据库用户、角色和授权只能在您喜欢的情况下用于授权。

    以下是它在 web ui 中的工作方式,例如:

    • jane连接到 web ui 服务器并使用所需的任何方法进行身份验证,例如 HTTPS X.509 客户端证书握手和 DIGEST 身份验证。服务器现在有一个来自它接受的用户的连接是真的jane。

    • 服务器使用固定的用户名/密码(或 Kerberos 或任何您喜欢的)连接到 PostgreSQL,以 user 身份向 db 服务器验证其自身webui。db 服务器信任webui对其用户进行身份验证,因此webui已给予适当GRANT的 s(见下文)。

    • 在那个连接上,服务器SET ROLE jane;用来假设用户的授权级别jane。直到RESET ROLE;或另一个SET ROLE运行,连接以jane与SELECT current_user()etc 将报告的相同访问权限运行jane。

    • 服务器维护它必须连接的数据库连接和 user 的 web 会话之间的关联SET ROLE,jane不允许janePostgreSQL 连接被其他用户的其他连接使用,而没有新的SET ROLE中间连接。

    您现在在服务器外部进行身份验证,但在服务器中保持授权。Pg 需要知道存在哪些用户,但不需要他们的密码或身份验证方法。

    看:

    • SET SESSION AUTHORIZATION
    • SET ROLE
    • GRANT

    细节

    webui 服务器控制查询运行,它不会让jane运行原始 SQL(我希望!)所以jane不能通过RESET ROLE; SET ROLE special_admin_user;web ui。为了增加安全性,我会向拒绝的服务器添加一个语句过滤器,SET ROLE除非RESET ROLE连接在或进入未分配连接池。

    您仍然可以在其他客户端中自由地使用对 Pg 的直接身份验证;你可以自由混合搭配。您只需向用户授予可以通过网络登录GRANT的webui用户的权限SET ROLE,然后为这些用户提供CONNECT您想要的任何正常权限、密码等。如果您想让它们仅用于 Web,则REVOKE它们CONNECT对数据库(和来自public)的权限。

    为了使这样的身份验证/授权拆分变得容易,我有一个特殊的角色assume_any_user,我GRANT每个新创建的用户都有。然后,我GRANT assume_any_user使用受信任的 Web 前端之类的东西使用的真实用户名,赋予他们成为他们喜欢的任何用户的权利。

    创建assume_any_user一个NOINHERIT角色很重要,因此webui用户或其他任何人都没有自己的特权,并且只能在数据库SET ROLE对真实用户起作用时才可以对其进行操作。在任何情况下都不应webui是超级用户或数据库所有者。

    如果您是连接池,则SET LOCAL ROLE只能在事务中使用来设置角色,因此您可以在COMMIT或之后将连接返回到池中ROLLBACK。请注意这RESET ROLE仍然有效,因此让客户端运行他们想要的任何 SQL 仍然是不安全的。

    SET SESSION AUTHORIZATION是此命令的相关但更强大的版本。它不需要角色成员身份,但它是一个仅限超级用户的命令。您不希望您的 web ui 以超级用户身份连接。它可以用RESET SESSION AUTHORIZATION,SET SESSION AUTHORIZATION DEFAULT或SET SESSION AUTHORIZATION theusername重新获得超级用户权限来逆转,因此它也不是一个放弃特权的安全屏障。

    如果您是角色成员但不是超级用户,那么一个可以工作但不可逆并且可以工作的命令SET SESSION AUTHORIZATION会很棒。目前还没有,但如果你小心的话,你仍然可以很好地分离身份验证和授权。

    例子和解释

    CREATE ROLE dbowner NOLOGIN;
    CREATE TABLE test_table(x text);
    INSERT INTO test_table(x) VALUES ('bork');
    ALTER TABLE test_table OWNER TO dbowner;
    
    CREATE ROLE assume_any_user NOINHERIT NOLOGIN;
    CREATE ROLE webui LOGIN PASSWORD 'somepw' IN ROLE assume_any_user;
    
    CREATE ROLE jane LOGIN PASSWORD 'somepw';
    GRANT jane TO assume_any_user;
    GRANT ALL ON TABLE test_table TO jane;
    
    CREATE ROLE jim LOGIN PASSWORD 'somepw';
    GRANT jim TO assume_any_user;
    

    现在连接为webui. 请注意,您不能做任何事情,但test_table您可以 SET ROLE,jane然后您可以访问:test_table

    $ psql -h 127.0.0.1 -U webui regress
    Password for user webui:
    
    regress=> SELECT session_user, current_user;
     session_user | current_user 
    --------------+--------------
     webui        | webui
    (1 row)
    
    
    
    regress=> SELECT * FROM test_table;
    ERROR:  permission denied for relation test_table
    
    regress=> SET ROLE jane;
    SET
    
    regress=> SELECT session_user, current_user;
     session_user | current_user 
    --------------+--------------
     webui        | jane
    (1 row)
    
    regress=> SELECT * FROM test_table;
      x   
    ------
     bork
    (1 row)
    

    webui 请 注意,即使已经d 到并且即使还没有被ed 授予担任该角色的权利,也可以SET ROLE这样做。设置您的有效用户 ID,但它不会删除您使用其他角色的能力,这是您连接的角色的属性,而不是您当前的有效角色。因此,您必须小心控制对and命令的访问。AFAIK,没有办法永久建立连接,真正成为目标用户,尽管拥有它肯定会很好。jimSET ROLEjanejaneGRANTjimSET ROLESET ROLESET ROLERESET ROLESET ROLE

    相比:

    $ psql -h 127.0.0.1 -U webui regress
    Password for user webui:
    
    regress=> SET ROLE jane;
    SET
    
    regress=> SET ROLE jim;
    SET
    regress=> SELECT session_user, current_user;
     session_user | current_user 
    --------------+--------------
     webui        | jim
    (1 row)
    

    至:

    $ psql -h 127.0.0.1 -U jane regress
    Password for user jane:
    
    regress=> SET ROLE webui;
    ERROR:  permission denied to set role "webui"
    regress=> SET ROLE jim;
    ERROR:  permission denied to set role "jim"
    

    这意味着这SET ROLE与以给定角色登录并不完全相同,您必须牢记这一点。

    webui不能SET ROLE,dbowner因为它没有被GRANT正确编辑:

    regress=> SET ROLE dbowner;
    ERROR:  permission denied to set role "dbowner"
    

    因此,它本身非常无能为力,它只能承担其他用户的权利,并且只有当这些用户启用了 Web 访问权限时。

    • 18

相关问题

  • 运行时间偏移延迟复制的最佳实践

  • 存储过程可以防止 SQL 注入吗?

  • 在数据仓库中实现多对多关系有哪些方法?

  • PostgreSQL 中 UniProt 的生物序列

  • PostgreSQL 9.0 Replication 和 Slony-I 有什么区别?

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    如何查看 Oracle 中的数据库列表?

    • 8 个回答
  • Marko Smith

    mysql innodb_buffer_pool_size 应该有多大?

    • 4 个回答
  • Marko Smith

    列出指定表的所有列

    • 5 个回答
  • Marko Smith

    从 .frm 和 .ibd 文件恢复表?

    • 10 个回答
  • Marko Smith

    如何在不修改我自己的 tnsnames.ora 的情况下使用 sqlplus 连接到位于另一台主机上的 Oracle 数据库

    • 4 个回答
  • Marko Smith

    你如何mysqldump特定的表?

    • 4 个回答
  • Marko Smith

    如何选择每组的第一行?

    • 6 个回答
  • Marko Smith

    使用 psql 列出数据库权限

    • 10 个回答
  • Marko Smith

    如何从 PostgreSQL 中的选择查询中将值插入表中?

    • 4 个回答
  • Marko Smith

    如何使用 psql 列出所有数据库和表?

    • 7 个回答
  • Martin Hope
    Mike Walsh 为什么事务日志不断增长或空间不足? 2012-12-05 18:11:22 +0800 CST
  • Martin Hope
    Stephane Rolland 列出指定表的所有列 2012-08-14 04:44:44 +0800 CST
  • Martin Hope
    haxney MySQL 能否合理地对数十亿行执行查询? 2012-07-03 11:36:13 +0800 CST
  • Martin Hope
    qazwsx 如何监控大型 .sql 文件的导入进度? 2012-05-03 08:54:41 +0800 CST
  • Martin Hope
    markdorison 你如何mysqldump特定的表? 2011-12-17 12:39:37 +0800 CST
  • Martin Hope
    pedrosanta 使用 psql 列出数据库权限 2011-08-04 11:01:21 +0800 CST
  • Martin Hope
    Jonas 如何使用 psql 对 SQL 查询进行计时? 2011-06-04 02:22:54 +0800 CST
  • Martin Hope
    Jonas 如何从 PostgreSQL 中的选择查询中将值插入表中? 2011-05-28 00:33:05 +0800 CST
  • Martin Hope
    Jonas 如何使用 psql 列出所有数据库和表? 2011-02-18 00:45:49 +0800 CST
  • Martin Hope
    bernd_k 什么时候应该使用唯一约束而不是唯一索引? 2011-01-05 02:32:27 +0800 CST

热门标签

sql-server mysql postgresql sql-server-2014 sql-server-2016 oracle sql-server-2008 database-design query-performance sql-server-2017

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve