将应用程序最终用户映射到数据库用户的每种方法有哪些优点?

时间:2008-12-07 04:46:28

标签: sql database oracle security

将应用程序最终用户映射到数据库用户似乎有三种常用方法。

  1. 一对一映射:每个应用程序用户(bob,nancy和fred)也会获得相应的数据库用户帐户(bob nancy和fred)。
  2. N到M映射:每个应用程序用户都映射到代表其角色的数据库用户。当fred映射到'manager'数据库用户时,bob和nancy被映射到'clerk'数据库用户。
  3. N到1映射:每个应用程序用户都映射到一个数据库用户(app_user),并且只在应用程序层管理身份。
  4. 似乎#3是Web应用程序开发中最常见的。 为什么没有更强调其他两个选项?

    Oracle鼓励像#2这样的技术使用其代理身份验证功能,原因如下:

    有限信任模型 - 控制代表中间层可以连接的用户,以及中间层可以为用户承担的角色

    可扩展性 - 支持轻量级用户会话并消除重新验证客户端的开销

    问责制,通过保留真实用户的身份到数据库,并启用对代表真实用户采取的操作的审核

    Oracle's Proxy Authentication documentation

9 个答案:

答案 0 :(得分:7)

除了更简单的管理之外,Web服务器上的选项3还具有性能优势;这允许连接池 - 即,可以连续地重复使用少量的物理数据库连接来为大量app用户提供服务。这被称为“trusted subsystem”模型 - 即您的app-server验证外部呼叫者,但随后app-server本身被用作向下呼叫的身份。这里最大的问题是,对于审计等,你需要不断告诉数据库谁做了当前的更改(USER_NAME()SUSER_SNAME()之类的东西不再有用) - 当然,这相对容易欺骗。

如果Web服务器使用每个用户的安全性,那么这是不可能的 - 因此您基本上必须禁用连接池。建立连接的行为(相对)昂贵,因此这将对性能产生重大影响。您不希望在请求之间保持(每用户)连接,因为这会导致巨大的池和大量打开的连接(也很昂贵)。

他们之间的“每个角色”选项网站 - 但很少有角色真正互相排斥,这使得这很难实现。

对于直接与数据库通信的客户端应用程序,选项1是最简单的维护,因为您不需要将任何特殊帐户详细信息分发给客户端。池同样不是问题,因为客户端的机器只充当1个用户。

答案 1 :(得分:1)

Re 2),应用程序安全/权限需求通常比数据库安全层提供的粒度更精细,除非您将大部分应用程序逻辑放入数据库中。一个简单的例子是,虽然两个用户可能需要更新订单表,但是一个可能正在创建他们自己的订单而另一个可能是管理员用户编辑其他人的订单。它们都需要对表进行插入/更新权限。您可以通过存储过程实现此限制,但这确实是一种解决方法 - 两个用户仍然需要更新表,因此需要具有这些权限的帐户。

我更喜欢为应用程序的所有最终用户使用相同的db帐户,并在db之外实现应用程序角色和权限。

显然,对于用户可以自行注册的网络应用,1)是不切实际的。我有一个拥有500,000或更多用户的网站 - 我想要那么多数据库帐户吗?我不这么认为!

我采用极简主义的方法(我相信很多人会争辩),其中运行的应用程序的db用户具有运行所需的最小权限,但不多。这意味着db用户无法进行架构更改,删除表,还原数据库等。

在开发过程中使用单独的帐户进行架构修改,该帐户具有必要的权限。

答案 2 :(得分:1)

N对1映射的一些原因如此广泛使用可能是因为,

  1. 在传统的软件开发数据库中,数据库被视为仅仅是存储库,而不仅仅是存储库。

  2. 程序员将数据库视为黑匣子,访问权限被视为一次性活动。

  3. 程序员很乐意调试代码并解决问题,而不是担心数据库级别的安全角色定义和维护。

  4. 在为管理员用户提供“用户/角色维护”屏幕的典型应用程序中,很容易拥有USER,SECURITY_ROLE,USER_SECURITY_ROLE等表来维护应用程序用户信息而不是创建用户,数据库本身的安全条目。

  5. 如果业务模型中没有明确定义的角色(双重角色,可自定义的访问权限等),则很容易在应用程序级而不是数据库中实现安全性。

答案 3 :(得分:0)

对于大多数应用来说,似乎最明智的一个。 #2对我来说似乎不对。在这种情况下,我将拥有组,用户可以适合组。

答案 4 :(得分:0)

我想补充一点,方法#1要求创建应用程序用户的代码在可能破坏权限的数据库帐户下运行。对我而言,这是一种不必要的风险。

答案 5 :(得分:0)

如果您处于应用程序面向Internet的环境以及具有更多权限的内部用户,则可以对选项2进行说明。

这样,您就可以在数据库上的权限较低(在表访问方面)帐户下运行面向Internet的应用程序服务器,并且内部用户可以访问具有附加访问权限的单独服务器。优点是,即使面向Internet的路由完全受到破坏,它仍然没有权限来处理内部用户需要访问的表。

如果您的身份验证系统支持委派(例如Windows身份验证,Kerberos),则选项1和2可以正常工作 - 因为应用程序服务器不需要保存或存储自己的凭据,它可以简单地模拟客户端。实际上这比选项3要好得多(因为如果服务器受到攻击,攻击者只能使用当前连接用户的权限,他们无法访问整个数据库)。但是,您很少能够使用此功能。

在通常的互联网设置中,3是唯一现实的选择。

编辑:这些选项都不会阻止您使用应用程序层中的业务逻辑进行进一步的访问控制,因此,如某些答案所暗示的那样,这是选项3的优势是不正确的。在所有情况下,应用程序层仍然知道其客户端是谁。

答案 6 :(得分:-1)

因为数据库角色(按对象,CRUD等)通常不适用于用户名,除非它们是数据库开发人员。 AD和数据库都有角色,但两者之间存在相同的不匹配。唯一的中途防御映射是管理员角色,但即便如此也是如此。

这个问题是“综合安全”这个术语引发的一种常见误解的结果,它实际上最终意味着“单一登录”(即用户验证),并且可能在AD内创建另一组角色和组因此,可以为AD管理员分配数据库安全的责任 - 通常不是他们受过良好培训的东西,尽管我确定有例外。

答案 7 :(得分:-1)

答案 8 :(得分:-2)

我不了解Oracle,但在SQL Server中,您希望池连接,最好的方法是让单个用户连接。每个不同的用户使用不同的连接字符串,这可能会减慢速度,因为现有的连接无法汇集并重新用于不同的用户。

如果您正在进行N teir应用程序,那么您的安全逻辑应该放在中间位置。您不希望每次要检查并查看某人是否具有某个区域的权限时都必须返回数据库。大多数应用程序中的权限通常比数据库安全性提供的更具体。